Skip to content

Commit f86b06a

Browse files
MrcSnmWebFreak001
andauthored
Implemented recipe files for dub #2684 (#2685)
Co-authored-by: Jan Jurzitza <[email protected]>
1 parent 52fd928 commit f86b06a

File tree

11 files changed

+118
-10
lines changed

11 files changed

+118
-10
lines changed

changelog/recipefile.dd

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Added `--recipe=` switch to DUB
2+
3+
You can now override which file is used as recipe, instead of the default
4+
`dub.sdl` and `dub.json`. This means you can define multiple dub.json files for
5+
local development, for example for special local-machine-only operations, and
6+
select which one to use over the CLI.
7+
8+
```
9+
dub build --recipe=custom-dub.json
10+
```
11+
12+
This can also be used to pick dub.sdl over dub.json, if both of them exist in
13+
the same directory. Although this is discouraged for interoperability with other
14+
DUB-supporting tools and general confusion for users. Both existing at the same
15+
time may also become an error when this switch is not specified in the future.

source/dub/commandline.d

+27-8
Original file line numberDiff line numberDiff line change
@@ -501,11 +501,13 @@ int runDubCommandLine(string[] args)
501501
return 1;
502502
}
503503

504-
// initialize the root package
505-
Dub dub = cmd.prepareDub(handler.options);
504+
try {
505+
// initialize the root package
506+
Dub dub = cmd.prepareDub(handler.options);
506507

507-
// execute the command
508-
try return cmd.execute(dub, remaining_args, command_args.appArgs);
508+
// execute the command
509+
return cmd.execute(dub, remaining_args, command_args.appArgs);
510+
}
509511
catch (UsageException e) {
510512
// usage exceptions get thrown before any logging, so we are
511513
// making the errors more narrow to better fit on small screens.
@@ -534,7 +536,7 @@ struct CommonOptions {
534536
bool verbose, vverbose, quiet, vquiet, verror, version_;
535537
bool help, annotate, bare;
536538
string[] registry_urls;
537-
string root_path;
539+
string root_path, recipeFile;
538540
enum Color { automatic, on, off }
539541
Color colorMode = Color.automatic;
540542
SkipPackageSuppliers skipRegistry = SkipPackageSuppliers.none;
@@ -568,6 +570,7 @@ struct CommonOptions {
568570
{
569571
args.getopt("h|help", &help, ["Display general or command specific help"]);
570572
args.getopt("root", &root_path, ["Path to operate in instead of the current working dir"]);
573+
args.getopt("recipe", &recipeFile, ["Loads a custom recipe path instead of dub.json/dub.sdl"]);
571574
args.getopt("registry", &registry_urls, [
572575
"Search the given registry URL first when resolving dependencies. Can be specified multiple times. Available registry types:",
573576
" DUB: URL to DUB registry (default)",
@@ -836,11 +839,25 @@ class Command {
836839
dub = new Dub(options.root_path, package_suppliers, options.skipRegistry);
837840
dub.dryRun = options.annotate;
838841
dub.defaultPlacementLocation = options.placementLocation;
839-
842+
dub.mainRecipePath = options.recipeFile;
840843
// make the CWD package available so that for example sub packages can reference their
841844
// parent package.
842-
try dub.packageManager.getOrLoadPackage(NativePath(options.root_path), NativePath.init, false, StrictMode.Warn);
843-
catch (Exception e) { logDiagnostic("No valid package found in current working directory: %s", e.msg); }
845+
try dub.packageManager.getOrLoadPackage(NativePath(options.root_path), NativePath(options.recipeFile), false, StrictMode.Warn);
846+
catch (Exception e) {
847+
// by default we ignore CWD package load fails in prepareDUB, since
848+
// they will fail again later when they are actually requested. This
849+
// is done to provide custom options to the loading logic and should
850+
// ideally be moved elsewhere. (This catch has been around since 10
851+
// years when it was first introduced in _app.d_)
852+
logDiagnostic("No valid package found in current working directory: %s", e.msg);
853+
854+
// for now, we work around not knowing if the package is needed or
855+
// not, simply by trusting the user to only use `--recipe` when the
856+
// recipe file actually exists, otherwise we throw the error.
857+
bool loadMustSucceed = options.recipeFile.length > 0;
858+
if (loadMustSucceed)
859+
throw e;
860+
}
844861

845862
return dub;
846863
}
@@ -1168,6 +1185,7 @@ abstract class PackageBuildCommand : Command {
11681185
return true;
11691186
}
11701187

1188+
11711189
bool from_cwd = package_name.length == 0 || package_name.startsWith(":");
11721190
// load package in root_path to enable searching for sub packages
11731191
if (loadCwdPackage(dub, from_cwd)) {
@@ -1272,6 +1290,7 @@ class GenerateCommand : PackageBuildCommand {
12721290
if (!gensettings.config.length)
12731291
gensettings.config = m_defaultConfig;
12741292
gensettings.runArgs = app_args;
1293+
gensettings.recipeName = dub.mainRecipePath;
12751294
// legacy compatibility, default working directory is always CWD
12761295
gensettings.overrideToolWorkingDirectory = getWorkingDirectory();
12771296

source/dub/dub.d

+9
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ class Dub {
126126
PackageManager m_packageManager;
127127
PackageSupplier[] m_packageSuppliers;
128128
NativePath m_rootPath;
129+
string m_mainRecipePath;
129130
SpecialDirs m_dirs;
130131
Settings m_config;
131132
Project m_project;
@@ -391,6 +392,14 @@ class Dub {
391392
/// application.
392393
@property string projectName() const { return m_project.name; }
393394

395+
@property string mainRecipePath() const { return m_mainRecipePath; }
396+
/// Whenever the switch --recipe= is supplied, this member will be populated.
397+
@property string mainRecipePath(string recipePath)
398+
{
399+
return m_mainRecipePath = recipePath;
400+
}
401+
402+
394403
@property NativePath projectPath() const { return this.m_project.rootPackage.path; }
395404

396405
@property string[] configurations() const { return m_project.configurations; }

source/dub/generators/build.d

+9-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,16 @@ string computeBuildName(string config, in GeneratorSettings settings, const stri
4646
addHash(settings.platform.architecture);
4747
addHash(settings.platform.compiler);
4848
addHash(settings.platform.compilerVersion);
49+
if(settings.recipeName != "")
50+
addHash(settings.recipeName);
4951
const hashstr = Base64URL.encode(hash.finish()[0 .. $ / 2]).stripRight("=");
5052

53+
if(settings.recipeName != "")
54+
{
55+
import std.path:stripExtension, baseName;
56+
string recipeName = settings.recipeName.baseName.stripExtension;
57+
return format("%s-%s-%s-%s", config, settings.buildType, recipeName, hashstr);
58+
}
5159
return format("%s-%s-%s", config, settings.buildType, hashstr);
5260
}
5361

@@ -747,10 +755,9 @@ private string computeBuildID(in BuildSettings buildsettings, string config, Gen
747755
(cast(uint)(buildsettings.options & ~BuildOption.color)).to!string, // exclude color option from id
748756
settings.platform.compilerBinary,
749757
settings.platform.compiler,
750-
settings.platform.compilerVersion,
758+
settings.platform.compilerVersion
751759
],
752760
];
753-
754761
return computeBuildName(config, settings, hashing);
755762
}
756763

source/dub/generators/generator.d

+1
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,7 @@ struct GeneratorSettings {
809809
BuildPlatform platform;
810810
Compiler compiler;
811811
string config;
812+
string recipeName;
812813
string buildType;
813814
BuildSettings buildSettings;
814815
BuildMode buildMode = BuildMode.separate;

test/issue2684-recipe-file.sh

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
3+
cd ${CURR_DIR}/issue2684-recipe-file
4+
${DUB} | grep -c "This was built using dub.json" > /dev/null
5+
${DUB} --recipe=dubWithAnotherSource.json | grep -c "This was built using dubWithAnotherSource.json" > /dev/null

test/issue2684-recipe-file/.gitignore

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
.dub
2+
docs.json
3+
__dummy.html
4+
docs/
5+
/issue2684-recipe-file
6+
issue2684-recipe-file.so
7+
issue2684-recipe-file.dylib
8+
issue2684-recipe-file.dll
9+
issue2684-recipe-file.a
10+
issue2684-recipe-file.lib
11+
issue2684-recipe-file-test-*
12+
*.exe
13+
*.pdb
14+
*.o
15+
*.obj
16+
*.lst
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module app;
2+
import std.stdio;
3+
4+
void main()
5+
{
6+
writeln("This was built using dubWithAnotherSource.json");
7+
}

test/issue2684-recipe-file/dub.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"authors": [
3+
"Hipreme"
4+
],
5+
"copyright": "Copyright © 2023, Hipreme",
6+
"description": "A minimal D application.",
7+
"license": "public domain",
8+
"name": "issue2684-recipe-file"
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"authors": [
3+
"Hipreme"
4+
],
5+
"copyright": "Copyright © 2023, Hipreme",
6+
"description": "A minimal D application.",
7+
"sourcePaths": ["anotherSource"],
8+
"license": "public domain",
9+
"name": "issue2684-recipe-file"
10+
}
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module app;
2+
import std.stdio;
3+
4+
void main()
5+
{
6+
writeln("This was built using dub.json.
7+
Try using the other configuration by calling dub with:
8+
dub --recipe=dubWithAnotherSource.json
9+
");
10+
}

0 commit comments

Comments
 (0)