Skip to content

Commit c0ff469

Browse files
committed
dub run <package> should search the registry on failure
1 parent 927c5e6 commit c0ff469

File tree

3 files changed

+137
-2
lines changed

3 files changed

+137
-2
lines changed

changelog/dub-run.dd

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
`dub run` will now automatically fetch a package if it's not found locally
2+
3+
Starting with this release, `dub run <mypackage>` makes sure that the package is available locally.
4+
This means that now a `dub fetch <mypackage>` is no longer required and all a user of a library needs to run your dub package is `dub run`:
5+
6+
$(CONSOLE
7+
> dub run gitcompatibledubpackage
8+
gitcompatibledubpackage wasn't found locally, but it's available online:
9+
---
10+
Description: Example of a DUB package also usable as git submodule. For DUB test suite.
11+
Version: 1.0.4
12+
---
13+
Do you want to fetch gitcompatibledubpackage? [Y/n]:
14+
)
15+
16+
An optional `--yes` (`-y`) flag is provided for non-interactive use:
17+
18+
$(CONSOLE
19+
> dub run --yes gitcompatibledubpackage
20+
gitcompatibledubpackage wasn't found locally, but it's available online:
21+
---
22+
Description: Example of a DUB package also usable as git submodule. For DUB test suite.
23+
Version: 1.0.4
24+
---
25+
Fetching gitcompatibledubpackage 1.0.4...
26+
Building package gitcompatibledubpackage in /home/seb/.dub/packages/gitcompatibledubpackage-1.0.4/gitcompatibledubpackage/
27+
Performing "debug" build using dmd for x86_64.
28+
gitcompatibledubpackage 1.0.4: building configuration "exe"...
29+
Linking...
30+
Running ../../.dub/packages/gitcompatibledubpackage-1.0.4/gitcompatibledubpackage/gitcompatibledubpackage
31+
Hello DUB
32+
)
33+
34+
If one wants to run a specific version of a package, it can be passed to `dub run` too:
35+
36+
$(CONSOLE
37+
> dub run gitcompatibledubpackage:1.0.4
38+
Fetching gitcompatibledubpackage 1.0.4...
39+
Building package gitcompatibledubpackage in /home/seb/.dub/packages/gitcompatibledubpackage-1.0.4/gitcompatibledubpackage/
40+
Performing "debug" build using dmd for x86_64.
41+
gitcompatibledubpackage 1.0.4: building configuration "exe"...
42+
Linking...
43+
Running ../../.dub/packages/gitcompatibledubpackage-1.0.4/gitcompatibledubpackage/gitcompatibledubpackage
44+
Hello DUB
45+
)

source/dub/commandline.d

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ int runDubCommandLine(string[] args)
120120
args[1] = args[1].setExtension(".d");
121121
}
122122
}
123-
123+
124124
// special single-file package shebang syntax
125125
if (args.length >= 2 && args[1].endsWith(".d")) {
126126
args = args[0] ~ ["run", "-q", "--temp-build", "--single", args[1], "--"] ~ args[2 ..$];
@@ -517,7 +517,7 @@ class InitCommand : Command {
517517
free_args = free_args[1 .. $];
518518
}
519519

520-
string input(string caption, string default_value)
520+
static string input(string caption, string default_value)
521521
{
522522
writef("%s [%s]: ", caption, default_value);
523523
auto inp = readln();
@@ -829,6 +829,7 @@ class GenerateCommand : PackageBuildCommand {
829829
}
830830

831831
class BuildCommand : GenerateCommand {
832+
bool m_yes; // automatic yes to prompts;
832833
this()
833834
{
834835
this.name = "build";
@@ -848,12 +849,70 @@ class BuildCommand : GenerateCommand {
848849
args.getopt("f|force", &m_force, [
849850
"Forces a recompilation even if the target is up to date"
850851
]);
852+
args.getopt("y|yes", &m_yes, [
853+
`Automatic yes to prompts. Assume "yes" as answer to all prompts and run non-interactively.`
854+
]);
851855
super.prepare(args);
852856
m_generator = "build";
853857
}
854858

855859
override int execute(Dub dub, string[] free_args, string[] app_args)
856860
{
861+
// single package files don't need to be downloaded, they are on the disk.
862+
if (free_args.length < 1 || m_single)
863+
return super.execute(dub, free_args, app_args);
864+
865+
const package_parts = free_args[0].split(":");
866+
const package_name = package_parts.front;
867+
const pack = dub.packageManager.getFirstPackage(package_name);
868+
869+
if (pack)
870+
return super.execute(dub, free_args, app_args);
871+
872+
static bool input(string caption, bool default_value = true) {
873+
writef("%s [%s]: ", caption, default_value ? "Y/n" : "y/N");
874+
auto inp = readln();
875+
string userInput = "y";
876+
if (inp.length > 1)
877+
userInput = inp[0 .. $ - 1].toLower;
878+
879+
switch (userInput) {
880+
case "no", "n", "0":
881+
return false;
882+
case "yes", "y", "1":
883+
default:
884+
return true;
885+
}
886+
}
887+
888+
Dependency dep;
889+
890+
if (package_parts.length > 1 && !package_parts[1].empty) {
891+
// the user provided a version manually
892+
free_args[0] = package_name;
893+
dep = Dependency(package_parts[1]);
894+
} else {
895+
// search for the package and filter versions for exact matches
896+
auto search = dub.searchPackages(package_name)
897+
.map!(tup => tup[1].find!(p => p.name == package_name))
898+
.filter!(ps => !ps.empty);
899+
if (search.empty)
900+
return 2;
901+
902+
const p = search.front.front;
903+
logInfo("%s wasn't found locally, but it's available online:", package_name);
904+
logInfo("---");
905+
logInfo("Description: %s", p.description);
906+
logInfo("Version: %s", p.version_);
907+
logInfo("---");
908+
909+
const answer = m_yes ? true : input("Do you want to fetch %s?".format(package_name));
910+
if (!answer)
911+
return 0;
912+
dep = Dependency(p.version_);
913+
}
914+
915+
dub.fetch(package_name, dep, dub.defaultPlacementLocation, FetchOptions.none);
857916
return super.execute(dub, free_args, app_args);
858917
}
859918
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/bin/bash
2+
3+
set -eu -o pipefail
4+
$DUB remove --version="*" gitcompatibledubpackage || true
5+
6+
# check whether the interactive run mode works
7+
echo "y" | $DUB run gitcompatibledubpackage | grep "Hello DUB"
8+
$DUB remove gitcompatibledubpackage
9+
10+
echo "n" | $DUB run gitcompatibledubpackage | grep "Hello DUB"
11+
! $DUB remove gitcompatibledubpackage
12+
13+
# check -y
14+
$DUB run --yes gitcompatibledubpackage | grep "Hello DUB"
15+
$DUB remove gitcompatibledubpackage
16+
17+
# check --yes
18+
$DUB run -y gitcompatibledubpackage | grep "Hello DUB"
19+
$DUB remove gitcompatibledubpackage
20+
21+
# check supplying versions directly
22+
dub_log="$($DUB run gitcompatibledubpackage:1.0.4)"
23+
echo "$dub_log" | grep "Hello DUB"
24+
echo "$dub_log" | grep "Fetching.*1.0.4"
25+
$DUB remove gitcompatibledubpackage
26+
27+
# check supplying an invalid version
28+
(! $DUB run gitcompatibledubpackage:0.42.43) 2>&1 | \
29+
grep 'No package gitcompatibledubpackage was found matching the dependency 0[.]42[.]43'
30+
31+
! $DUB remove gitcompatibledubpackage

0 commit comments

Comments
 (0)