diff --git a/changelog/shebang-without-d-extension.dd b/changelog/shebang-without-d-extension.dd new file mode 100644 index 0000000..7e9b33d --- /dev/null +++ b/changelog/shebang-without-d-extension.dd @@ -0,0 +1,6 @@ +Shebang without .d extension + +Dub single-file packages e.g. `app.d` can now be called without .d extension. +In addition to `dub app.d --param` you can call `dub app --param`. + +Also files without .d extension are supported now as single-file packages. \ No newline at end of file diff --git a/source/dub/commandline.d b/source/dub/commandline.d index f6bcfdc..7b556d0 100644 --- a/source/dub/commandline.d +++ b/source/dub/commandline.d @@ -19,7 +19,7 @@ import dub.packagemanager; import dub.packagesuppliers; import dub.project; -import dub.internal.utils : getDUBVersion, getClosestMatch; +import dub.internal.utils : getDUBVersion, getClosestMatch, getTempFile; import std.algorithm; import std.array; @@ -33,7 +33,7 @@ import std.string; import std.typecons : Tuple, tuple; import std.variant; - +import std.path: setExtension; /** Retrieves a list of all available commands. @@ -101,13 +101,26 @@ // special stdin syntax if (args.length >= 2 && args[1] == "-") { - import dub.internal.utils: getTempFile; - auto path = getTempFile("app", ".d"); stdin.byChunk(4096).joiner.toFile(path.toNativeString()); args = args[0] ~ [path.toNativeString()] ~ args[2..$]; } + // create the list of all supported commands + CommandGroup[] commands = getCommands(); + string[] commandNames = commands.map!(g => g.commands.map!(c => c.name).array).join.array; + + // Shebang syntax support for files without .d extension + if (args.length >= 2 && !args[1].endsWith(".d") && !args[1].startsWith("-") && !commandNames.canFind(args[1])) { + if (exists(args[1])) { + auto path = getTempFile("app", ".d"); + copy(args[1], path.toNativeString()); + args[1] = path.toNativeString(); + } else if (exists(args[1].setExtension(".d"))) { + args[1] = args[1].setExtension(".d"); + } + } + // special single-file package shebang syntax if (args.length >= 2 && args[1].endsWith(".d")) { args = args[0] ~ ["run", "-q", "--temp-build", "--single", args[1], "--"] ~ args[2 ..$]; @@ -163,9 +176,6 @@ options.root_path = options.root_path.absolutePath.buildNormalizedPath; } - // create the list of all supported commands - CommandGroup[] commands = getCommands(); - // extract the command string cmdname; args = common_args.extractRemainingArgs(); diff --git a/test/issue103-single-file-package-no-ext b/test/issue103-single-file-package-no-ext new file mode 100755 index 0000000..8c76638 --- /dev/null +++ b/test/issue103-single-file-package-no-ext @@ -0,0 +1,12 @@ +#!../bin/dub +/+ dub.sdl: + name "single-file-test" ++/ +module hello; + +void main(string[] args) +{ + import std.stdio : writeln; + assert(args.length == 4 && args[1 .. 4] == ["foo", "--", "bar"]); + writeln("Hello, World!"); +} diff --git a/test/issue103-single-file-package.sh b/test/issue103-single-file-package.sh index 0c23eb2..cce4674 100755 --- a/test/issue103-single-file-package.sh +++ b/test/issue103-single-file-package.sh @@ -10,6 +10,8 @@ rm single-file-test ./issue103-single-file-package.d foo -- bar +${DUB} ./issue103-single-file-package foo -- bar +./issue103-single-file-package-no-ext foo -- bar ${DUB} issue103-single-file-package-w-dep.d