Hi,

I would like to anounce the new [ThePath](https://code.dlang.org/packages/thepath) published to https://code.dlang.org/.

The basic functionality of [ThePath](https://code.dlang.org/packages/thepath) library seems to be completed, and before stabilizing it, i would like to ask community to review this lib and suggest what could be added / changed to make it usable for your usecases. Also, currently, this lib is tested only on linux, thus, may be some of you would be interested in making it cross-platform (help with testing and adding unittests for other platforms (Windows, MacOs, etc)). It should work on other platforms, but possibly with restricted functionality.

Basically, this lib provides single struct `Path`, that have to be used to deal with file system paths and files in object-oriented way, making code more readable.

Also, this lib contains function [createTempDirectory](https://github.com/katyukha/thepath/blob/master/source/thepath/utils.d), that, i think, would be nice to have it in Phobos.

So, the questions are:
- Do it have sense to convert `Path` to a class? Or keep it as struct? - Do it have sense to convert `Path` to template struct to make it possible to work with other types of strings (except `string` type)? - What are the requirements to place [createTempDirectory](https://github.com/katyukha/thepath/blob/master/source/thepath/utils.d#L11) function in Phobos?
- What else could be changed to make it better?

Short list of features:
- automatic expansion of `~` when needed (before passing path to std.file or std.stdio funcs)
- single method to copy path (file or directory) to dest path
- single method to remove path (file or directory)
- simple method to `walk` through the path
    - `foreach(p; Path.current.walk) writeln(p.toString);`
    - `foreach(p; Path("/tmp").walk) writeln(p.toString);`
- simple construction of paths from parts:
    - `Path("a", "b", "c")`
    - `Path("a").join("b", "c")`
- simple deconstruction of paths
    - `Path("a/b/c/d").segments == ["a", "b", "c", "d"]`
    - `Path("a", "b", "c", "d").segments == ["a", "b", "c", "d"]`
- overriden comparison operators for paths.
    - `Path("a", "b") == Path("a", "b")`
    - `Path("a", "b") != Path("a", "c")`
    - `Path("a", "b") < Path("a", "c")`
- `hasAttributes` / `getAttributes` / `setAttributes` methods to work with file attrs
- file operations as methods:
    - `Path("my-path").writeFile("Hello world")`
    - `Path("my-path").readFile()`
- support search by glob-pattern
- `foreach(path; Path.current.glob("*.py")) writeln(p.toString);`


Short example is described below. More examples available in unittests and documentation.


```d
import thepath;


Path app_dir = Path("~/.local/my-app");
Path catalog_dir = app_dir.join("catalog");


void init() {
// Note, that automatic '~' expansion will be done before checking the
    // existense of directory
    if (!app_dir.exists) {
        app_dir.mkdir(true);  // create recursive
    }
    if (!catalog_dir.exists) {
        catalog_dir.mkdir(true);
    }
}

void list_dir() {
    // Easily print content of the catalog directory
    foreach(Path p; catalog_dir.walkBreadth) {
        writeln(p.toAbsolute().toString());
    }
}

// Print all python files in current directory
void find_python_files() {
    foreach(path; Path.current.glob("*.py", SpanMode.breadth))
        // Print paths relative to current directory
        writeln(p.relativeTo(Path.current).toString);
}

Path findConfig() {
    // Search for "my-project.conf" in current directories and in
    // its parent directories
    auto config = Path.current.searchFileUp("my-project.conf");
    enforce(!config.isNull);
    return config.get;
}
```

Reply via email to