Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Install latest DMD
uses: dlang-community/setup-dlang@v1
uses: dlang-community/setup-dlang@v2
- name: Checkout
uses: actions/checkout@v4
- name: Run tests
Expand All @@ -52,7 +52,7 @@ jobs:
fail-fast: false
matrix:
# Latest stable version, update at will
os: [ macOS-13, ubuntu-22.04, windows-2022 ]
os: [ macOS-14, ubuntu-22.04, windows-2022 ]
dc:
# Always test latest as that is what we use to compile on release
- dmd-latest
Expand All @@ -77,9 +77,9 @@ jobs:
exclude:
# Error with those versions:
# ld: multiple errors: symbol count from symbol table and dynamic symbol table differ in [.../dub.o]; address=0x0 points to section(2) with no content in '[...]/osx/lib/libphobos2.a[3177](config_a68_4c3.o)'
- { os: macOS-13, dc: dmd-2.100.2 }
- { os: macOS-13, dc: dmd-2.103.1 }
- { os: macOS-13, dc: dmd-2.106.1 }
- { os: macOS-14, dc: dmd-2.100.2 }
- { os: macOS-14, dc: dmd-2.103.1 }
- { os: macOS-14, dc: dmd-2.106.1 }

runs-on: ${{ matrix.os }}
steps:
Expand All @@ -100,7 +100,7 @@ jobs:

# Compiler to test with
- name: Prepare compiler
uses: dlang-community/setup-dlang@v1
uses: dlang-community/setup-dlang@v2
with:
compiler: ${{ matrix.dc }}

Expand Down
4 changes: 2 additions & 2 deletions source/dub/commandline.d
Original file line number Diff line number Diff line change
Expand Up @@ -1602,7 +1602,7 @@ class BuildCommand : GenerateCommand {
if (packageParts.name.startsWith(":"))
return 0;

const baseName = PackageName(packageParts.name).main;
const baseName = PackageName(packageParts.name).base;
// Found locally
if (dub.packageManager.getBestPackage(baseName, packageParts.range))
return 0;
Expand Down Expand Up @@ -2833,7 +2833,7 @@ class DustmiteCommand : PackageBuildCommand {
static void fixPathDependency(in PackageName name, ref Dependency dep) {
dep.visit!(
(NativePath path) {
dep = Dependency(NativePath("../") ~ name.main.toString());
dep = Dependency(NativePath("../") ~ name.base.toString());
},
(any) { /* Nothing to do */ },
);
Expand Down
31 changes: 19 additions & 12 deletions source/dub/dependency.d
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,19 @@ import std.exception;
import std.string;

/// Represents a fully-qualified package name
public struct PackageName
struct PackageName
{
/// The underlying full name of the package
private string fullName;
/// Where the separator lies, if any
private size_t separator;
private {
/// The underlying full name of the package
string fullName;
/// Where the separator lies, if any
size_t separator;
}

@safe pure:

/// Creates a new instance of this struct
public this(string fn) @safe pure
this(string fn)
{
this.fullName = fn;
if (auto idx = fn.indexOf(':'))
Expand All @@ -38,20 +42,23 @@ public struct PackageName
}

/// Private constructor to have nothrow / @nogc
private this(string fn, size_t sep) @safe pure nothrow @nogc
private this(string fn, size_t sep) nothrow @nogc
{
this.fullName = fn;
this.separator = sep;
}

/// The base package name in which the subpackages may live
public PackageName main () const return @safe pure nothrow @nogc
PackageName base() const return nothrow @nogc
{
return PackageName(this.fullName[0 .. this.separator], this.separator);
}

deprecated("Use .base instead.")
alias main = base;

/// The subpackage name, or an empty string if there isn't
public string sub () const return @safe pure nothrow @nogc
string sub() const return nothrow @nogc
{
// Return `null` instead of an empty string so that
// it can be used in a boolean context, e.g.
Expand All @@ -62,20 +69,20 @@ public struct PackageName
}

/// Human readable representation
public string toString () const return scope @safe pure nothrow @nogc
string toString() const return scope nothrow @nogc
{
return this.fullName;
}

///
public int opCmp (in PackageName other) const scope @safe pure nothrow @nogc
int opCmp(in PackageName other) const scope nothrow @nogc
{
import core.internal.string : dstrcmp;
return dstrcmp(this.toString(), other.toString());
}

///
public bool opEquals (in PackageName other) const scope @safe pure nothrow @nogc
bool opEquals(in PackageName other) const scope nothrow @nogc
{
return this.toString() == other.toString();
}
Expand Down
26 changes: 13 additions & 13 deletions source/dub/dependencyresolver.d
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class DependencyResolver(CONFIGS, CONFIG) {

CONFIG[PackageName] resolve(TreeNode root, bool throw_on_failure = true)
{
auto rootbase = root.pack.main;
auto rootbase = root.pack.base;

// build up the dependency graph, eliminating as many configurations/
// versions as possible
Expand Down Expand Up @@ -180,7 +180,7 @@ class DependencyResolver(CONFIGS, CONFIG) {
*/
private void constrain(TreeNode n, ref ResolveContext context, ref ulong max_iterations)
{
auto base = n.pack.main;
auto base = n.pack.base;
assert(base in context.configs);
if (context.isVisited(n.pack)) return;
context.setVisited(n.pack);
Expand All @@ -189,7 +189,7 @@ class DependencyResolver(CONFIGS, CONFIG) {

foreach (dep; dependencies) {
// lazily load all dependency configurations
auto depbase = dep.pack.main;
auto depbase = dep.pack.base;
auto di = depbase in context.configs;
if (!di) {
context.configs[depbase] =
Expand Down Expand Up @@ -243,7 +243,7 @@ class DependencyResolver(CONFIGS, CONFIG) {
~ " recipe that reproduces this error.");

auto dep = &dependencies[depidx];
auto depbase = dep.pack.main;
auto depbase = dep.pack.base;
auto depconfigs = context.configs[depbase];

Exception first_err;
Expand Down Expand Up @@ -291,9 +291,9 @@ class DependencyResolver(CONFIGS, CONFIG) {
{
if (node.pack in visited) return;
visited[node.pack] = true;
required[node.pack.main] = true;
required[node.pack.base] = true;
foreach (dep; getChildren(node).filter!(dep => dep.depType != DependencyType.optional))
if (auto dp = dep.pack.main in configs)
if (auto dp = dep.pack.base in configs)
markRecursively(TreeNode(dep.pack, *dp));
}

Expand All @@ -314,12 +314,12 @@ class DependencyResolver(CONFIGS, CONFIG) {

this(TreeNode parent, TreeNodes dep, const scope ref ResolveContext context, string file = __FILE__, size_t line = __LINE__)
{
auto m = format("Unresolvable dependencies to package %s:", dep.pack.main);
auto m = format("Unresolvable dependencies to package %s:", dep.pack.base);
super(m, file, line);

this.failedNode = dep.pack;

auto failbase = failedNode.main;
auto failbase = failedNode.base;

// Get partial results
CONFIG[PackageName] partial_result;
Expand All @@ -332,18 +332,18 @@ class DependencyResolver(CONFIGS, CONFIG) {

// get the list of all dependencies to the failed package
auto deps = context.visited.byKey
.filter!(p => !!(p.main in partial_result))
.map!(p => TreeNode(p, partial_result[p.main]))
.filter!(p => !!(p.base in partial_result))
.map!(p => TreeNode(p, partial_result[p.base]))
.map!(n => getChildren(n)
.filter!(d => d.pack.main == failbase)
.filter!(d => d.pack.base == failbase)
.map!(d => tuple(n, d))
)
.join
.sort!((a, b) => a[0].pack < b[0].pack);

foreach (d; deps) {
// filter out trivial self-dependencies
if (d[0].pack.main == failbase
if (d[0].pack.base == failbase
&& matches(d[1].configs, d[0].config))
continue;
msg ~= format("\n %s %s depends on %s %s", d[0].pack, d[0].config, d[1].pack, d[1].configs);
Expand Down Expand Up @@ -395,7 +395,7 @@ unittest {
foreach (p_; m_children.byKey) {
// Note: We abuse subpackage notation to store configs
const p = PackageName(p_);
if (p.main != pack.main) continue;
if (p.base != pack.base) continue;
ret ~= ic(p.sub.to!uint);
}
ret.data.sort!"a>b"();
Expand Down
44 changes: 22 additions & 22 deletions source/dub/dub.d
Original file line number Diff line number Diff line change
Expand Up @@ -696,12 +696,12 @@ class Dub {

if (options & UpgradeOptions.dryRun) {
bool any = false;
string rootbasename = PackageName(m_project.rootPackage.name).main.toString();
string rootbasename = PackageName(m_project.rootPackage.name).base.toString();

foreach (p, ver; versions) {
if (!ver.path.empty || !ver.repository.empty) continue;

auto basename = p.main;
auto basename = p.base;
if (basename.toString() == rootbasename) continue;

if (!m_project.selections.hasSelectedVersion(basename)) {
Expand Down Expand Up @@ -1028,7 +1028,7 @@ class Dub {
PackageSupplier supplier;
foreach(ps; m_packageSuppliers){
try {
pinfo = ps.fetchPackageRecipe(name.main, range, (options & FetchOptions.usePrerelease) != 0);
pinfo = ps.fetchPackageRecipe(name.base, range, (options & FetchOptions.usePrerelease) != 0);
if (pinfo.type == Json.Type.null_)
continue;
supplier = ps;
Expand All @@ -1049,7 +1049,7 @@ class Dub {
if (existing && existing.version_ != ver)
logInfo("A new version for %s is available (%s -> %s). Run \"%s\" to switch.",
name.toString().color(Mode.bold), existing, ver,
text("dub upgrade ", name.main).color(Mode.bold));
text("dub upgrade ", name.base).color(Mode.bold));
return null;
}

Expand Down Expand Up @@ -1078,17 +1078,17 @@ class Dub {
{
import std.zip : ZipException;

auto data = supplier.fetchPackage(name.main, range, (options & FetchOptions.usePrerelease) != 0); // Q: continue on fail?
auto data = supplier.fetchPackage(name.base, range, (options & FetchOptions.usePrerelease) != 0); // Q: continue on fail?
if (tag !is IntegrityTag.init)
enforce(tag.matches(data), ("Hash of downloaded package does " ~
"not match integrity tag for %s@%s - This can happen if " ~
"the version has been re-tagged").format(name.main, range));
"the version has been re-tagged").format(name.base, range));
else
tag = IntegrityTag.make(data);
logDiagnostic("Placing to %s...", location.toString());

try {
return m_packageManager.store(data, location, name.main, ver);
return m_packageManager.store(data, location, name.base, ver);
} catch (ZipException e) {
logInfo("Failed to extract zip archive for %s@%s...", name, ver);
// re-throw the exception at the end of the loop
Expand Down Expand Up @@ -1138,9 +1138,9 @@ class Dub {
void remove(in PackageName name, PlacementLocation location,
scope size_t delegate(in Package[] packages) resolve_version)
{
enforce(name.main.toString().length);
enforce(name.base.toString().length);
enforce(!name.sub.length, "Cannot remove subpackage %s, remove %s instead"
.format(name, name.main));
.format(name, name.base));
if (location == PlacementLocation.local) {
logInfo("To remove a locally placed package, make sure you don't have any data"
~ "\nleft in it's directory and then simply remove the whole directory.");
Expand Down Expand Up @@ -1915,7 +1915,7 @@ private class DependencyVersionResolver : DependencyResolver!(Dependency, Depend
auto basepack = pack.basePackage;

foreach (d; pack.getAllDependenciesRange()) {
auto dbasename = d.name.main.toString();
auto dbasename = d.name.base.toString();

// detect dependencies to the root package (or sub packages thereof)
if (dbasename == basepack.name) {
Expand All @@ -1926,7 +1926,7 @@ private class DependencyVersionResolver : DependencyResolver!(Dependency, Depend
auto desireddeppath = basepack.path;
desireddeppath.endsWithSlash = true;

auto altdeppath = d.name == d.name.main ? basepack.path : subpack.path;
auto altdeppath = d.name == d.name.base ? basepack.path : subpack.path;
altdeppath.endsWithSlash = true;

if (!d.spec.path.empty && absdeppath != desireddeppath)
Expand All @@ -1950,14 +1950,14 @@ private class DependencyVersionResolver : DependencyResolver!(Dependency, Depend
Dependency dspec = d.spec.mapToPath(pack.path);

// if not upgrading, use the selected version
if (!(m_options & UpgradeOptions.upgrade) && m_selectedVersions.hasSelectedVersion(d.name.main))
dspec = m_selectedVersions.getSelectedVersion(d.name.main);
if (!(m_options & UpgradeOptions.upgrade) && m_selectedVersions.hasSelectedVersion(d.name.base))
dspec = m_selectedVersions.getSelectedVersion(d.name.base);

// keep selected optional dependencies and avoid non-selected optional-default dependencies by default
if (!m_selectedVersions.bare) {
if (dt == DependencyType.optionalDefault && !m_selectedVersions.hasSelectedVersion(d.name.main))
if (dt == DependencyType.optionalDefault && !m_selectedVersions.hasSelectedVersion(d.name.base))
dt = DependencyType.optional;
else if (dt == DependencyType.optional && m_selectedVersions.hasSelectedVersion(d.name.main))
else if (dt == DependencyType.optional && m_selectedVersions.hasSelectedVersion(d.name.base))
dt = DependencyType.optionalDefault;
}

Expand Down Expand Up @@ -1988,9 +1988,9 @@ private class DependencyVersionResolver : DependencyResolver!(Dependency, Depend

// for sub packages, first try to get them from the base package
// FIXME: avoid this, PackageManager.getSubPackage() is costly
if (name.main != name) {
if (name.base != name) {
auto subname = name.sub;
auto basepack = getPackage(name.main, dep);
auto basepack = getPackage(name.base, dep);
if (!basepack) return null;
if (auto sp = m_dub.m_packageManager.getSubPackage(basepack, subname, true))
return sp;
Expand All @@ -1999,7 +1999,7 @@ private class DependencyVersionResolver : DependencyResolver!(Dependency, Depend
}

// shortcut if the referenced package is the root package
if (name.main.toString() == m_rootPackage.basePackage.name)
if (name.base.toString() == m_rootPackage.basePackage.name)
return m_rootPackage.basePackage;

if (!dep.repository.empty) {
Expand Down Expand Up @@ -2029,7 +2029,7 @@ private class DependencyVersionResolver : DependencyResolver!(Dependency, Depend
auto prerelease = (m_options & UpgradeOptions.preRelease) != 0;

foreach (ps; m_dub.m_packageSuppliers) {
if (name.main == name) {
if (name.base == name) {
try {
auto desc = ps.fetchPackageRecipe(name, VersionRange(vers, vers), prerelease);
if (desc.type == Json.Type.null_)
Expand All @@ -2048,16 +2048,16 @@ private class DependencyVersionResolver : DependencyResolver!(Dependency, Depend
try {
FetchOptions fetchOpts;
fetchOpts |= prerelease ? FetchOptions.usePrerelease : FetchOptions.none;
m_dub.fetch(name.main, vers, fetchOpts, m_dub.defaultPlacementLocation, "need sub package description");
m_dub.fetch(name.base, vers, fetchOpts, m_dub.defaultPlacementLocation, "need sub package description");
auto ret = m_dub.m_packageManager.getBestPackage(name, vers);
if (!ret) {
logWarn("Package %s %s doesn't have a sub package %s", name.main, dep, name);
logWarn("Package %s %s doesn't have a sub package %s", name.base, dep, name);
return null;
}
m_remotePackages[key] = ret;
return ret;
} catch (Exception e) {
logDiagnostic("Package %s could not be downloaded from %s: %s", name.main, ps.description, e.msg);
logDiagnostic("Package %s could not be downloaded from %s: %s", name.base, ps.description, e.msg);
logDebug("Full error: %s", e.toString().sanitize);
}
}
Expand Down
Loading
Loading