diff --git a/test/issue2234-copy-read-only-files.script.d b/test/issue2234-copy-read-only-files.script.d new file mode 100644 index 0000000..d785db1 --- /dev/null +++ b/test/issue2234-copy-read-only-files.script.d @@ -0,0 +1,128 @@ +/+ dub.json: { +"name": "issue2234_copy_read_only_files" +} +/ + +/* +When DUB copies read-only files to the targetPath, the read-only flag must be +removed. If not, any subsequent copy operations will fail. + +Version control systems such as Git Large File Storage typically mark binary +files as read-only, to prevent simultaneous edits in unmergeable formats. +*/ + +module issue2234_copy_read_only_files.script; + +import + std.algorithm.searching, + std.algorithm.iteration, + std.stdio, std.process, std.path, std.file; + +int main() +{ + const project_dir = buildPath(__FILE_FULL_PATH__.dirName, "issue2234-copy-read-only-files"); + const deployment_dir = buildPath(project_dir, "bin"); + auto deployables = dirEntries(buildPath(project_dir, "files"), "*", SpanMode.depth).filter!isFile; + + // Prepare environment. + if (deployment_dir.exists) + { + foreach (entry; dirEntries(deployment_dir, "*", SpanMode.depth)) + { + if (entry.isDir) + entry.rmdir; + else + { + entry.makeWritable; + entry.remove; + } + } + deployment_dir.rmdir; + } + foreach (ref f; deployables) + f.makeReadOnly; + + // Execute test. + const dub = environment.get("DUB", buildPath(__FILE_FULL_PATH__.dirName.dirName, "bin", "dub.exe")); + const cmd = [dub, "build", "--build=release"]; + const result = execute(cmd, null, Config.none, size_t.max, project_dir); + if (result.status || result.output.canFind("Failed")) + { + writefln("\n> %-(%s %)", cmd); + writeln("==========================================================="); + writeln(result.output); + writeln("==========================================================="); + writeln("Last command failed with exit code ", result.status, '\n'); + return 1; + } + + foreach (deployed; dirEntries(deployment_dir, "*", SpanMode.depth).filter!isFile) + if (!isWritable(deployed)) + { + writeln(deployed, " is expected to be writable, but it is not."); + return 1; + } + + return 0; +} + +void makeReadOnly(string name) +{ + version (Windows) + { + import core.sys.windows.windows; + + name.setAttributes(name.getAttributes() | FILE_ATTRIBUTE_READONLY); + } + else version (Posix) + { + import core.sys.posix.sys.stat; + + name.setAttributes(name.getAttributes() & ~(S_IWUSR | S_IWGRP | S_IWOTH)); + } + else + static assert("Needs implementation."); + + import std.exception; + import std.stdio; + assertThrown!ErrnoException(File(name, "w")); +} + +void makeWritable(string name) +{ + version (Windows) + { + import core.sys.windows.windows; + + name.setAttributes(name.getAttributes() & ~FILE_ATTRIBUTE_READONLY); + } + else version (Posix) + { + import core.sys.posix.sys.stat; + + name.setAttributes(name.getAttributes() | (S_IWUSR | S_IWGRP | S_IWOTH)); + } + else + static assert("Needs implementation."); + + import std.exception; + import std.stdio; + assertNotThrown!ErrnoException(File(name, "w")); +} + +bool isWritable(string name) +{ + version (Windows) + { + import core.sys.windows.windows; + + return (name.getAttributes() & FILE_ATTRIBUTE_READONLY) == 0; + } + else version (Posix) + { + import core.sys.posix.sys.stat; + + return (name.getAttributes() & S_IWUSR) != 0; + } + else + static assert("Needs implementation."); +} diff --git a/test/issue2234-copy-read-only-files/.gitignore b/test/issue2234-copy-read-only-files/.gitignore new file mode 100644 index 0000000..ba077a4 --- /dev/null +++ b/test/issue2234-copy-read-only-files/.gitignore @@ -0,0 +1 @@ +bin diff --git a/test/issue2234-copy-read-only-files/dub.json b/test/issue2234-copy-read-only-files/dub.json new file mode 100644 index 0000000..f911f1d --- /dev/null +++ b/test/issue2234-copy-read-only-files/dub.json @@ -0,0 +1,8 @@ +{ + "name": "issue2234_copy_read_only_files", + "copyFiles": [ + "files/to_be_deployed.bin", + "files/images" + ], + "targetPath": "bin" +} diff --git a/test/issue2234-copy-read-only-files/files/images/to_be_deployed.img b/test/issue2234-copy-read-only-files/files/images/to_be_deployed.img new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/issue2234-copy-read-only-files/files/images/to_be_deployed.img diff --git a/test/issue2234-copy-read-only-files/files/to_be_deployed.bin b/test/issue2234-copy-read-only-files/files/to_be_deployed.bin new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/issue2234-copy-read-only-files/files/to_be_deployed.bin diff --git a/test/issue2234-copy-read-only-files/source/app.d b/test/issue2234-copy-read-only-files/source/app.d new file mode 100644 index 0000000..ab73b3a --- /dev/null +++ b/test/issue2234-copy-read-only-files/source/app.d @@ -0,0 +1 @@ +void main() {}