Skip to content

Commit

Permalink
Merge pull request #313 from atilaneves/dubVersion
Browse files Browse the repository at this point in the history
Allow dub dependencies to be specified by version and not only by path
  • Loading branch information
atilaneves authored Jun 24, 2024
2 parents 6ba93e8 + 8069f20 commit 7febb23
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 30 deletions.
2 changes: 1 addition & 1 deletion payload/reggae/dub/interop/dublib.d
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ private struct DubConfigurations {
}
}

package struct Dub {
public struct Dub {
import reggae.dub.info: DubInfo;
import reggae.options: Options;
import dub.dub: DubClass = Dub;
Expand Down
1 change: 1 addition & 0 deletions payload/reggae/options.d
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ struct Options {
bool buildReggaefileSingle; // single-threaded build using the binary backend
bool buildReggaefileOptimise; // compile the build description with optimisations
bool forceReggaefileDeps;
package bool includeReggaefileInSources; // for internal usage to build the reggaefile itself
string[string] userVars; // must be last

Options dup() @safe pure const nothrow scope {
Expand Down
27 changes: 22 additions & 5 deletions payload/reggae/rules/common.d
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,25 @@ Target[] objectFiles
) {

import reggae.config: options;
return objectFiles!sourcesFunc(flags, includes, stringImports);
}

/// ditto
Target[] objectFiles
(alias sourcesFunc = Sources!())
(
in imported!"reggae.options".Options options,
in CompilerFlags flags = CompilerFlags(),
in ImportPaths includes = ImportPaths(),
in StringImportPaths stringImports = StringImportPaths(),
)
{
const srcFiles = sourcesToFileNames!sourcesFunc(options);
return srcFilesToObjectTargets(options, srcFiles, flags, includes, stringImports);
}



/**
An object file, typically from one source file in a certain language
(although for D the default is a whole package). The language is determined
Expand Down Expand Up @@ -399,11 +413,14 @@ string[] sourcesToFileNames(alias sourcesFunc = Sources!())(in imported!"reggae.
modules ~= buildNormalizedPath(buildPath(options.projectPath, module_));
}

return modules.sort.
map!(a => removeProjectPath(options.projectPath, a)).
filter!(srcs.filterFunc).
filter!(a => a != "reggaefile.d").
array;
return modules
.sort
.map!(a => removeProjectPath(options.projectPath, a))
.filter!(srcs.filterFunc)
.filter!(a => a != "reggaefile.d" || options.includeReggaefileInSources)
.array
;

}

//run-time version
Expand Down
104 changes: 84 additions & 20 deletions payload/reggae/rules/dub/external.d
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ struct DubPath {
Configuration config;
}

/*
A dub version-based dependency.
*/
struct DubVersion {
import reggae.types: Configuration;
string name;
string version_;
Configuration config;
}

/**
The types of binaries that a target that has dub dependencies (but
isn't a dub package itself) can have.
Expand All @@ -33,6 +43,15 @@ imported!"reggae.build".Target dubPackage(in imported!"reggae.options".Options o
return DubPathDependency(options, dubPath).target;
}

imported!"reggae.build".Target dubPackage(DubVersion dubVersion)() {
import reggae.config: reggaeOptions = options; // the ones used to run reggae
return dubPackage(reggaeOptions, dubVersion);
}

imported!"reggae.build".Target dubPackage(in imported!"reggae.options".Options options, in DubVersion dubVersion) {
return DubPathDependency(options, dubVersion).target;
}

/**
A target that depends on dub packages but isn't one itself.
*/
Expand All @@ -42,6 +61,7 @@ imported!"reggae.build".Target dubDependant(
alias sourcesFunc,
// the other arguments can be:
// * DubPath
// * DubVersion
// * CompilerFlags
// * LinkerFlags
// * ImportPaths
Expand All @@ -63,6 +83,7 @@ imported!"reggae.build".Target dubDependant
DubPackageTargetType targetType,
// the other arguments can be:
// * DubPath
// * DubVersion
// * CompilerFlags
// * LinkerFlags
// * ImportPaths
Expand All @@ -78,12 +99,6 @@ imported!"reggae.build".Target dubDependant
import std.range: chain;
import std.traits: Unqual;

DubPath[] dubPaths;
static foreach(arg; args) {
static if(is(Unqual!(typeof(arg)) == DubPath))
dubPaths ~= arg;
}

template oneOptionalOf(T) {
import std.meta: staticIndexOf;
enum index = staticIndexOf!(T, A);
Expand All @@ -102,33 +117,51 @@ imported!"reggae.build".Target dubDependant
const importPaths = oneOptionalOf!ImportPaths;
const stringImportPaths = oneOptionalOf!StringImportPaths;

DubPath[] dubPaths;
static foreach(arg; args) {
static if(is(Unqual!(typeof(arg)) == DubPath))
dubPaths ~= arg;
}

DubVersion[] dubVersions;
static foreach(arg; args) {
static if(is(Unqual!(typeof(arg)) == DubVersion))
dubVersions ~= arg;
}

auto dubPathDependencies = dubPaths
.map!(p => DubPathDependency(options, p))
.map!(d => DubPathDependency(options, d))
.array
;

auto allImportPaths = dubPathDependencies
.map!(d => d.dubInfo.packages.map!(p => p.importPaths).joiner)
.joiner
.chain(importPaths.value)
auto dubVersDependencies = dubVersions
.map!(d => DubPathDependency(options, d))
.array
;

auto allStringImportPaths = dubPathDependencies
.map!(d => d.dubInfo.packages.map!(p => p.stringImportPaths).joiner)
.joiner
.chain(stringImportPaths.value)
;
auto allImportPaths = chain(
importPaths.value,
dubPathDependencies.map!(d => d.dubInfo.packages.map!(p => p.importPaths).joiner).joiner,
dubVersDependencies.map!(d => d.dubInfo.packages.map!(p => p.importPaths).joiner).joiner,
);

auto allStringImportPaths = chain(
stringImportPaths.value,
dubVersDependencies.map!(d => d.dubInfo.packages.map!(p => p.stringImportPaths).joiner).joiner,
dubVersDependencies.map!(d => d.dubInfo.packages.map!(p => p.stringImportPaths).joiner).joiner,
);

auto objs = objectFiles!sourcesFunc(
options,
compilerFlags,
const ImportPaths(allImportPaths),
const StringImportPaths(allStringImportPaths),
);

auto dubDepsObjs = dubPathDependencies
.map!(d => d.target)
.array
;
auto dubDepsObjs = chain(
dubPathDependencies.map!(d => d.target),
dubVersDependencies.map!(d => d.target),
).array;

const targetNameWithExt = withExtension(targetName, targetType);

Expand All @@ -148,6 +181,37 @@ private struct DubPathDependency {
Options subOptions; // options for the dub dependency
DubInfo dubInfo;

this(in Options reggaeOptions, in DubVersion dubVersion) {
import std.path: buildPath;
import std.file: exists;
import std.process: execute;
import std.conv: text;

const path = buildPath(dubPkgsDir, dubVersion.name, dubVersion.version_, dubVersion.name);

if(!path.exists) {
const ret = execute(["dub", "fetch", dubVersion.name ~ "@" ~ dubVersion.version_]);
if(ret.status != 0)
throw new Exception(text("Could not fetch ", dubVersion, ": ", ret.output));
if(!path.exists)
throw new Exception(text("Expected path ", path, " does not exist after dub fetch"));
}

this(reggaeOptions, DubPath(path, dubVersion.config));
}

static private string dubPkgsDir() {
import std.process: environment;
import std.path: buildPath;

version(Windows)
const root = buildPath(environment["LOCALAPPDATA"], "dub");
else
const root = buildPath(environment["HOME"], ".dub");

return buildPath(root, "packages");
}

this(in Options reggaeOptions, in DubPath dubPath) {
import reggae.dub.interop: dubInfos;
import std.stdio: stdout;
Expand Down
30 changes: 26 additions & 4 deletions tests/it/runtime/dub/dependencies.d
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ unittest {
}
}

@("dubPackage.exe.naked")
@("dubPackage.path.exe.naked")
@Tags("dub", "ninja")
unittest {
with(immutable ReggaeSandbox()) {
Expand Down Expand Up @@ -507,7 +507,29 @@ unittest {
}
}

@("dubPackage.exe.phony")
@("dubPackage.version.exe.naked")
@Tags("dub", "ninja")
unittest {
with(immutable ReggaeSandbox()) {
writeFile(
"reggaefile.d",
q{
import reggae;
alias dubDep = dubPackage!(DubVersion("dubnull", "0.0.1"));
mixin build!dubDep;
}
);

runReggae("-b", "ninja");
ninja.shouldExecuteOk;
version(linux) {
fileShouldContain(inSandboxPath("build.ninja"), "libdubnull.a");
}
}
}


@("dubPackage.path.exe.phony")
@Tags("dub", "ninja")
unittest {
with(immutable ReggaeSandbox()) {
Expand Down Expand Up @@ -546,7 +568,7 @@ unittest {
}


@("dubPackage.lib.config")
@("dubPackage.path.lib.config")
@Tags("dub", "ninja")
unittest {
import reggae.rules.common: exeExt;
Expand Down Expand Up @@ -589,7 +611,7 @@ unittest {
}
}

@("dubPackage.lib.timing")
@("dubPackage.path.lib.timing")
@Flaky
@Tags("dub", "ninja")
unittest {
Expand Down

0 comments on commit 7febb23

Please sign in to comment.