Skip to content

Commit

Permalink
Implemented recipe files for dub #2684 (#2685)
Browse files Browse the repository at this point in the history
Co-authored-by: Jan Jurzitza <[email protected]>
  • Loading branch information
MrcSnm and WebFreak001 authored Aug 13, 2023
1 parent 52fd928 commit f86b06a
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 10 deletions.
15 changes: 15 additions & 0 deletions changelog/recipefile.dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Added `--recipe=` switch to DUB

You can now override which file is used as recipe, instead of the default
`dub.sdl` and `dub.json`. This means you can define multiple dub.json files for
local development, for example for special local-machine-only operations, and
select which one to use over the CLI.

```
dub build --recipe=custom-dub.json
```

This can also be used to pick dub.sdl over dub.json, if both of them exist in
the same directory. Although this is discouraged for interoperability with other
DUB-supporting tools and general confusion for users. Both existing at the same
time may also become an error when this switch is not specified in the future.
35 changes: 27 additions & 8 deletions source/dub/commandline.d
Original file line number Diff line number Diff line change
Expand Up @@ -501,11 +501,13 @@ int runDubCommandLine(string[] args)
return 1;
}

// initialize the root package
Dub dub = cmd.prepareDub(handler.options);
try {
// initialize the root package
Dub dub = cmd.prepareDub(handler.options);

// execute the command
try return cmd.execute(dub, remaining_args, command_args.appArgs);
// execute the command
return cmd.execute(dub, remaining_args, command_args.appArgs);
}
catch (UsageException e) {
// usage exceptions get thrown before any logging, so we are
// making the errors more narrow to better fit on small screens.
Expand Down Expand Up @@ -534,7 +536,7 @@ struct CommonOptions {
bool verbose, vverbose, quiet, vquiet, verror, version_;
bool help, annotate, bare;
string[] registry_urls;
string root_path;
string root_path, recipeFile;
enum Color { automatic, on, off }
Color colorMode = Color.automatic;
SkipPackageSuppliers skipRegistry = SkipPackageSuppliers.none;
Expand Down Expand Up @@ -568,6 +570,7 @@ struct CommonOptions {
{
args.getopt("h|help", &help, ["Display general or command specific help"]);
args.getopt("root", &root_path, ["Path to operate in instead of the current working dir"]);
args.getopt("recipe", &recipeFile, ["Loads a custom recipe path instead of dub.json/dub.sdl"]);
args.getopt("registry", &registry_urls, [
"Search the given registry URL first when resolving dependencies. Can be specified multiple times. Available registry types:",
" DUB: URL to DUB registry (default)",
Expand Down Expand Up @@ -836,11 +839,25 @@ class Command {
dub = new Dub(options.root_path, package_suppliers, options.skipRegistry);
dub.dryRun = options.annotate;
dub.defaultPlacementLocation = options.placementLocation;

dub.mainRecipePath = options.recipeFile;
// make the CWD package available so that for example sub packages can reference their
// parent package.
try dub.packageManager.getOrLoadPackage(NativePath(options.root_path), NativePath.init, false, StrictMode.Warn);
catch (Exception e) { logDiagnostic("No valid package found in current working directory: %s", e.msg); }
try dub.packageManager.getOrLoadPackage(NativePath(options.root_path), NativePath(options.recipeFile), false, StrictMode.Warn);
catch (Exception e) {
// by default we ignore CWD package load fails in prepareDUB, since
// they will fail again later when they are actually requested. This
// is done to provide custom options to the loading logic and should
// ideally be moved elsewhere. (This catch has been around since 10
// years when it was first introduced in _app.d_)
logDiagnostic("No valid package found in current working directory: %s", e.msg);

// for now, we work around not knowing if the package is needed or
// not, simply by trusting the user to only use `--recipe` when the
// recipe file actually exists, otherwise we throw the error.
bool loadMustSucceed = options.recipeFile.length > 0;
if (loadMustSucceed)
throw e;
}

return dub;
}
Expand Down Expand Up @@ -1168,6 +1185,7 @@ abstract class PackageBuildCommand : Command {
return true;
}


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

Expand Down
9 changes: 9 additions & 0 deletions source/dub/dub.d
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ class Dub {
PackageManager m_packageManager;
PackageSupplier[] m_packageSuppliers;
NativePath m_rootPath;
string m_mainRecipePath;
SpecialDirs m_dirs;
Settings m_config;
Project m_project;
Expand Down Expand Up @@ -391,6 +392,14 @@ class Dub {
/// application.
@property string projectName() const { return m_project.name; }

@property string mainRecipePath() const { return m_mainRecipePath; }
/// Whenever the switch --recipe= is supplied, this member will be populated.
@property string mainRecipePath(string recipePath)
{
return m_mainRecipePath = recipePath;
}


@property NativePath projectPath() const { return this.m_project.rootPackage.path; }

@property string[] configurations() const { return m_project.configurations; }
Expand Down
11 changes: 9 additions & 2 deletions source/dub/generators/build.d
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,16 @@ string computeBuildName(string config, in GeneratorSettings settings, const stri
addHash(settings.platform.architecture);
addHash(settings.platform.compiler);
addHash(settings.platform.compilerVersion);
if(settings.recipeName != "")
addHash(settings.recipeName);
const hashstr = Base64URL.encode(hash.finish()[0 .. $ / 2]).stripRight("=");

if(settings.recipeName != "")
{
import std.path:stripExtension, baseName;
string recipeName = settings.recipeName.baseName.stripExtension;
return format("%s-%s-%s-%s", config, settings.buildType, recipeName, hashstr);
}
return format("%s-%s-%s", config, settings.buildType, hashstr);
}

Expand Down Expand Up @@ -747,10 +755,9 @@ private string computeBuildID(in BuildSettings buildsettings, string config, Gen
(cast(uint)(buildsettings.options & ~BuildOption.color)).to!string, // exclude color option from id
settings.platform.compilerBinary,
settings.platform.compiler,
settings.platform.compilerVersion,
settings.platform.compilerVersion
],
];

return computeBuildName(config, settings, hashing);
}

Expand Down
1 change: 1 addition & 0 deletions source/dub/generators/generator.d
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,7 @@ struct GeneratorSettings {
BuildPlatform platform;
Compiler compiler;
string config;
string recipeName;
string buildType;
BuildSettings buildSettings;
BuildMode buildMode = BuildMode.separate;
Expand Down
5 changes: 5 additions & 0 deletions test/issue2684-recipe-file.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

cd ${CURR_DIR}/issue2684-recipe-file
${DUB} | grep -c "This was built using dub.json" > /dev/null
${DUB} --recipe=dubWithAnotherSource.json | grep -c "This was built using dubWithAnotherSource.json" > /dev/null
16 changes: 16 additions & 0 deletions test/issue2684-recipe-file/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.dub
docs.json
__dummy.html
docs/
/issue2684-recipe-file
issue2684-recipe-file.so
issue2684-recipe-file.dylib
issue2684-recipe-file.dll
issue2684-recipe-file.a
issue2684-recipe-file.lib
issue2684-recipe-file-test-*
*.exe
*.pdb
*.o
*.obj
*.lst
7 changes: 7 additions & 0 deletions test/issue2684-recipe-file/anotherSource/app.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module app;
import std.stdio;

void main()
{
writeln("This was built using dubWithAnotherSource.json");
}
9 changes: 9 additions & 0 deletions test/issue2684-recipe-file/dub.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"authors": [
"Hipreme"
],
"copyright": "Copyright © 2023, Hipreme",
"description": "A minimal D application.",
"license": "public domain",
"name": "issue2684-recipe-file"
}
10 changes: 10 additions & 0 deletions test/issue2684-recipe-file/dubWithAnotherSource.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"authors": [
"Hipreme"
],
"copyright": "Copyright © 2023, Hipreme",
"description": "A minimal D application.",
"sourcePaths": ["anotherSource"],
"license": "public domain",
"name": "issue2684-recipe-file"
}
10 changes: 10 additions & 0 deletions test/issue2684-recipe-file/source/app.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module app;
import std.stdio;

void main()
{
writeln("This was built using dub.json.
Try using the other configuration by calling dub with:
dub --recipe=dubWithAnotherSource.json
");
}

0 comments on commit f86b06a

Please sign in to comment.