Skip to content

Commit

Permalink
Merge pull request #2944 from Geod24/mlang/FSR
Browse files Browse the repository at this point in the history
Refactor filesystem abstraction to and use it in production 

Signed-off-by: Nicholas Wilson <[email protected]>
Merged-on-behalf-of: Nicholas Wilson <[email protected]>
  • Loading branch information
dlang-bot authored Jun 25, 2024
2 parents 7658fa8 + 6808d80 commit 33f3ceb
Show file tree
Hide file tree
Showing 11 changed files with 830 additions and 644 deletions.
2 changes: 2 additions & 0 deletions build-files.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ source/dub/internal/dyaml/style.d
source/dub/internal/dyaml/tagdirective.d
source/dub/internal/dyaml/token.d
source/dub/internal/git.d
source/dub/internal/io/filesystem.d
source/dub/internal/io/realfs.d
source/dub/internal/libInputVisitor.d
source/dub/internal/sdlang/ast.d
source/dub/internal/sdlang/exception.d
Expand Down
8 changes: 4 additions & 4 deletions source/dub/dub.d
Original file line number Diff line number Diff line change
Expand Up @@ -376,15 +376,15 @@ class Dub {
import dub.test.base : TestDub;

scope (exit) environment.remove("DUB_REGISTRY");
auto dub = new TestDub(null, ".", null, SkipPackageSuppliers.configured);
auto dub = new TestDub(null, "/dub/project/", null, SkipPackageSuppliers.configured);
assert(dub.packageSuppliers.length == 0);
environment["DUB_REGISTRY"] = "http://example.com/";
dub = new TestDub(null, ".", null, SkipPackageSuppliers.configured);
dub = new TestDub(null, "/dub/project/", null, SkipPackageSuppliers.configured);
assert(dub.packageSuppliers.length == 1);
environment["DUB_REGISTRY"] = "http://example.com/;http://foo.com/";
dub = new TestDub(null, ".", null, SkipPackageSuppliers.configured);
dub = new TestDub(null, "/dub/project/", null, SkipPackageSuppliers.configured);
assert(dub.packageSuppliers.length == 2);
dub = new TestDub(null, ".", [new RegistryPackageSupplier(URL("http://bar.com/"))], SkipPackageSuppliers.configured);
dub = new TestDub(null, "/dub/project/", [new RegistryPackageSupplier(URL("http://bar.com/"))], SkipPackageSuppliers.configured);
assert(dub.packageSuppliers.length == 3);

dub = new TestDub();
Expand Down
96 changes: 96 additions & 0 deletions source/dub/internal/io/filesystem.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/**
* An abstract filesystem representation
*
* This interface allows to represent the file system to various part of Dub.
* Instead of direct use of `std.file`, an implementation of this interface can
* be used, allowing to mock all I/O in unittest on a thread-local basis.
*/
module dub.internal.io.filesystem;

public import std.datetime.systime;

public import dub.internal.vibecompat.inet.path;

/// Ditto
public interface Filesystem
{
static import dub.internal.vibecompat.core.file;

/// TODO: Remove, the API should be improved
public alias IterateDirDg = int delegate(
scope int delegate(ref dub.internal.vibecompat.core.file.FileInfo));

/// Ditto
public IterateDirDg iterateDirectory (in NativePath path) scope;

/// Returns: The `path` of this FSEntry
public abstract NativePath getcwd () const scope;

/**
* Implements `mkdir -p`: Create a directory and every intermediary
*
* There is no way to error out on intermediate directory,
* like standard mkdir does. If you want this behavior,
* simply check (`existsDirectory`) if the parent directory exists.
*
* Params:
* path = The path of the directory to be created.
*/
public abstract void mkdir (in NativePath path) scope;

/// Checks the existence of a file
public abstract bool existsFile (in NativePath path) const scope;

/// Checks the existence of a directory
public abstract bool existsDirectory (in NativePath path) const scope;

/// Reads a file, returns the content as `ubyte[]`
public abstract ubyte[] readFile (in NativePath path) const scope;

/// Reads a file, returns the content as text
public abstract string readText (in NativePath path) const scope;

/// Write to this file
public final void writeFile (in NativePath path, const(char)[] data) scope
{
import std.string : representation;

this.writeFile(path, data.representation);
}

/// Ditto
public abstract void writeFile (in NativePath path, const(ubyte)[] data) scope;

/** Remove a file
*
* Always error if the target is a directory.
* Does not error if the target does not exists
* and `force` is set to `true`.
*
* Params:
* path = Path to the file to remove
* force = Whether to ignore non-existing file,
* default to `false`.
*/
public void removeFile (in NativePath path, bool force = false);

/** Remove a directory
*
* Remove an existing empty directory.
* If `force` is set to `true`, no error will be thrown
* if the directory is empty or non-existing.
*
* Params:
* path = Path to the directory to remove
* force = Whether to ignore non-existing / non-empty directories,
* default to `false`.
*/
public void removeDir (in NativePath path, bool force = false);

/// Implement `std.file.setTimes`
public void setTimes (in NativePath path, in SysTime accessTime,
in SysTime modificationTime);

/// Implement `std.file.setAttributes`
public void setAttributes (in NativePath path, uint attributes);
}
Loading

0 comments on commit 33f3ceb

Please sign in to comment.