Skip to content
Merged
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
2 changes: 1 addition & 1 deletion dub.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ldcup",
"version": "1.1.7",
"version": "1.1.8",
"description": "Download and manage D compiler [ldc2].",
"license": "Apache-2.0",
"targetPath": "bin",
Expand Down
25 changes: 17 additions & 8 deletions source/app.d
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct Args
bool help;
bool verbose;
bool remote;
bool compilerSet;
string installDir;
string platform;
string command;
Expand All @@ -36,7 +37,7 @@ void printHelp(string programName) @safe
writeln(" install [compiler] Install a compiler (default: ldc2-latest)");
writeln(" uninstall <compiler> Uninstall an installed compiler");
writeln(" list List installed compilers");
writeln(" run -- <flags> Run ldc2 with the given flags");
writeln(" run [compiler] -- <flags> Run ldc2 with the given flags");
writeln();
writeln("Compiler specifiers:");
writeln(" ldc2-latest Latest stable LDC2 release (default)");
Expand Down Expand Up @@ -88,9 +89,22 @@ Args parseArgs(string[] argv) @safe
break;
}
else if (arg.startsWith("ldc2-") || arg.startsWith("opend-"))
{
parsed.compiler = normaliseCompilerSpec(arg);
else if (arg.canFind("redub"))
parsed.compilerSet = true;
}
else if (arg == "redub")
{
parsed.compiler = arg;
parsed.compilerSet = true;
}
else if (arg.among("dmd", "gdc"))
throw new Exception("Only ldc2 and opend compilers are supported.");
else if (arg.startsWith("v") && arg.length > 1 && arg[1].isDigit)
{
parsed.compiler = normaliseCompilerSpec(arg);
parsed.compilerSet = true;
}
else if (parsed.command.empty)
parsed.command = arg;
else
Expand Down Expand Up @@ -118,12 +132,6 @@ int main(string[] argv) @safe
return 0;
}

if (parsed.compiler.among("dmd", "gdc"))
{
writeln("Error: only ldc2 and opend compilers are supported.");
return 1;
}

if (parsed.command.empty)
{
writeln("Error: no command specified.");
Expand All @@ -143,6 +151,7 @@ int main(string[] argv) @safe
break;

case "uninstall":
enforce(parsed.compilerSet, "uninstall requires a compiler specifier, e.g. ldc2-1.42.0");
manager.uninstallCompiler(parsed.compiler);
break;

Expand Down
53 changes: 37 additions & 16 deletions source/impl.d
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ private:
Arch currentArch;
ReleaseType releaseType;

version (Windows)
immutable string ext = ".7z";
else
immutable string ext = ".tar.xz";
private string ext() const @safe pure
{
return (currentOS == OS.windows) ? ".7z" : ".tar.xz";
}

public:
bool verbose;
Expand Down Expand Up @@ -137,6 +137,9 @@ public:
enforce(parts.length == 2, "Invalid platform format (expected OS-ARCH): " ~ platform);
currentOS = fromString!OS(parts[0]);
currentArch = fromString!Arch(parts[1]);
// Windows releases use x64/x86/multilib naming, not x86_64
if (currentOS == OS.windows && currentArch == Arch.x86_64)
currentArch = Arch.x64;
}
}

Expand All @@ -150,9 +153,9 @@ public:
auto downloadUrl = getCompilerDownloadUrl(resolvedCompiler);
auto targetPath = buildPath(root, resolvedCompiler);

downloadAndExtract(downloadUrl, targetPath, resolvedCompiler.startsWith("opend-"));
bool isOpend = resolvedCompiler.startsWith("opend-");
downloadAndExtract(downloadUrl, targetPath, isOpend);

bool isOpend = compilerSpec.startsWith("opend-");
string prefix = isOpend ? "opend" : "ldc2";
compilerPath = buildPath(
targetPath,
Expand Down Expand Up @@ -198,25 +201,28 @@ public:

void runCompiler(string compilerSpec, string[] args) @safe
{
enforce(args.length > 0, "No flags provided. Use 'run -- <flags>'");
enforce(args.length > 0, "No flags provided. Use 'run [compiler] -- <flags>'");
log("Running compiler: %s", compilerSpec);
compilerPath = findLDC2Path();
enforce(!compilerPath.empty, "No LDC2 installation found");
compilerPath = findLDC2Path(compilerSpec);

auto cmd = [compilerPath] ~ args;
auto result = execute(cmd);
writeln(result.output);
enforce(result.status == 0, "LDC2 execution failed with status %d".format(result.status));
}

string findLDC2Path() @safe
string findLDC2Path(string compilerSpec = "") @safe
{
auto installed = listInstalledCompilers().filter!(v => v.startsWith("ldc2-")).array;
enforce(!installed.empty, "No LDC2 installation found in %s".format(root));

string ver = installed[0]["ldc2-".length .. $];
// Use the requested spec if it's installed; otherwise fall back to the first entry.
string entry = (compilerSpec.startsWith("ldc2-") && installed.canFind(compilerSpec))
? compilerSpec : installed[0];

string ver = entry["ldc2-".length .. $];
string ldc2Dir = buildPath(
root, installed[0],
root, entry,
format("ldc2-%s-%s-%s", ver, currentOS, currentArch),
"bin"
);
Expand Down Expand Up @@ -467,7 +473,7 @@ public:
else if (compilerSpec.endsWith("nightly") || compilerSpec.endsWith("master"))
{
releaseType = ReleaseType.nightly;
url = "https://github.com/ldc-developers/ldc/commits/master.atom";
url = "https://api.github.com/repos/ldc-developers/ldc/releases/tags/CI";
}
else // Explicit version — use as-is; normalise prefix if missing.
return compilerSpec.startsWith("ldc2-") ? compilerSpec : "ldc2-" ~ compilerSpec;
Expand All @@ -485,9 +491,24 @@ public:
format("HTTP %d when resolving %s version", res.code, releaseType));

string response = (cast(string) res.responseBody.data).strip;
string dversion = (releaseType == ReleaseType.nightly)
? response.split("<id>tag:github.com,2008:Grit::Commit/")[1].split(
"</id>")[0][0 .. 8] : response;
string dversion;
if (releaseType == ReleaseType.nightly)
{
string suffix = format("-%s-%s%s", currentOS, currentArch, ext);
foreach (asset; parseJSON(response)["assets"].array)
{
string name = asset["name"].str;
if (name.startsWith("ldc2-") && name.endsWith(suffix))
{
dversion = name["ldc2-".length .. $ - suffix.length];
break;
}
}
enforce(!dversion.empty,
"No CI nightly build found for %s-%s".format(currentOS, currentArch));
}
else
dversion = response;

log("Resolved %s version: ldc2-%s", releaseType, dversion);
return "ldc2-" ~ dversion;
Expand Down
Loading