Skip to content

Commit

Permalink
Experimental 'hx with' and internal tools for bundled haxe
Browse files Browse the repository at this point in the history
  • Loading branch information
kLabz committed May 20, 2024
1 parent de84ca0 commit 80313c5
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 19 deletions.
71 changes: 71 additions & 0 deletions src/BundledHaxe.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import sys.io.File;
import haxe.io.Path;
import sys.FileSystem;

import tools.DownloadHelper;
import tools.Utils;

class BundledHaxe {
static var OS = ["Linux", "Mac", "Windows"];
static var current = Path.join([Utils.bundleDir, ".current"]);

public static function getBundledVersion():String {
return StringTools.trim(File.getContent(current));
}

public static function setBundledVersion(version:String):Void {
final v = HaxeNightlies.resolve(version);

function getOsPath(os) {
return switch os {
case "Linux": "linux64";
case "Windows": "windows64";
case "Mac": "mac";
case _: throw 'Unexpected os $os';
}
}

function updateCurrent() {
final prev = getBundledVersion();

if (prev != version) {
for (os in OS) {
final path = Path.join([Utils.bundleDir, getOsPath(os) + "_" + prev]);
Utils.rmdir(path);
Sys.println('Removed $path');
}

File.saveContent(current, version);
// TODO: git operations
Sys.println('Set current bundled haxe version as $version');
}
}

final os = OS.copy();

function next() {
if (os.length == 0) return updateCurrent();

final os = os.pop();
final dest = Path.join([Utils.bundleDir, getOsPath(os) + "_" + version]);
if (FileSystem.exists(dest)) {
Sys.println('Bundled version $version for $os already exists');
return next();
}

final url = Utils.getBuildUrl(v, os);
final filename = Path.withoutDirectory(url[1]);
final path = Path.join([Utils.bundleDir, filename]);

DownloadHelper.download(url[0] + filename, path, () -> {
Sys.println('Downloaded $filename');
final out = DownloadHelper.extract(path);
FileSystem.deleteFile(path);
FileSystem.rename(Path.join([Utils.bundleDir, out]), dest);
next();
});
}

next();
}
}
14 changes: 14 additions & 0 deletions src/HaxeManager.hx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ class HaxeManager {
case ["--help", ["download"]]: HaxeDownload.displayUsage();
case ["--help", ["select"]]: HaxeSelect.displayUsage();

// Experimental commands

// Note: this is not suited for eval (or -cmd) using stdin, as that
// will not be forwarded properly
case ["with", args] if (args.length > 0):
var v = args.shift();
if (v == "rc") v = HaxeRc.getRc();
final path = Utils.find(v);
Utils.runHaxe(path, args);

// Internal commands
case ["bundled", []]: Sys.println(BundledHaxe.getBundledVersion());
case ["bundle", [version]]: BundledHaxe.setBundledVersion(version);

case [v, []]: HaxeSelect.select(v);
case _: throw 'Invalid arguments';
}
Expand Down
53 changes: 38 additions & 15 deletions src/HaxeRc.hx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,17 @@ import haxe.io.Path;

import tools.Utils;

enum HaxeRcError {
NotFound;
ParseError(err:String);
}

class HaxeRc {
public static function resolve() {
public static function safeGetRc():Null<String> {
return try getRc() catch(_) null;
}

public static function getRc():Null<String> {
final cwd = Utils.getCallSite();

// TODO (?): check parent directories too
Expand All @@ -16,23 +25,37 @@ class HaxeRc {
if (FileSystem.exists(rc)) {
try {
final version = Json.parse(File.getContent(rc)).version;

if (SemVer.isValid(version)) {
HaxeDownload.downloadRelease(version, r -> HaxeSelect.select(r));
} else if (HaxeNightlies.isValid(version)) {
switch (Utils.resolveRelease(version)) {
case null:
HaxeDownload.downloadNightly(version, r -> HaxeSelect.select(r));
case r:
HaxeSelect.select(r);
}
}
return version;
} catch (e) {
Utils.displayError('Could not get Haxe version from .haxerc: $e');
Sys.exit(1);
throw ParseError(Std.string(e));
}
} else {
Utils.displayError('Did not find any .haxerc to apply');
throw NotFound;
}
}

public static function resolve() {
try {
final version = getRc();

if (SemVer.isValid(version)) {
HaxeDownload.downloadRelease(version, r -> HaxeSelect.select(r));
} else if (HaxeNightlies.isValid(version)) {
switch (Utils.resolveRelease(version)) {
case null:
HaxeDownload.downloadNightly(version, r -> HaxeSelect.select(r));
case r:
HaxeSelect.select(r);
}
}
} catch (e:HaxeRcError) {
switch e {
case NotFound:
Utils.displayError('Did not find any .haxerc to apply');
case ParseError(e):
Utils.displayError('Could not get Haxe version from .haxerc: $e');
}

Sys.exit(1);
}
}
Expand Down
64 changes: 60 additions & 4 deletions src/tools/Utils.hx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import sys.FileSystem;
import sys.io.Process;

import ansi.ANSI;
using tools.NullTools;

class Utils {
public static inline var binDir = "bin";
public static inline var bundleDir = "build";
public static inline var currentDir = "current";
public static inline var versionsDir = "versions";
public static inline var releasesDir = "releases";
Expand All @@ -34,9 +36,9 @@ class Utils {
Sys.stderr().flush();
}

public static function getBuildUrl(v:String):Array<String> {
public static function getBuildUrl(v:String, ?os:String):Array<String> {
// TODO: arch variants
return switch Sys.systemName() {
return switch os.or(Sys.systemName()) {
case "Linux":
['https://build.haxe.org/builds/haxe/linux64/', 'haxe_$v.tar.gz'];
case "Mac":
Expand Down Expand Up @@ -95,6 +97,28 @@ class Utils {
};
}

public static function runHaxe(path:String, args:Array<String>):Void {
final exe = switch Sys.systemName() {
case "Windows": "haxe.exe";
case _: "haxe";
};

final cwd = Sys.getCwd();
final path = Path.join([cwd, path]);
final old_std = Sys.getEnv("HAXE_STD_PATH");

Sys.setCwd(Utils.getCallSite());
Sys.putEnv("HAXE_STD_PATH", Path.join([path, "std"]));

var ret = Sys.command(Path.join([path, exe]), args);

Sys.putEnv("HAXE_STD_PATH", old_std);
Sys.setCwd(cwd);

Sys.exit(ret);
}

// TODO: factorize with runHaxe
public static function getVersionString(path:String):Null<String> {
final exe = switch Sys.systemName() {
case "Windows": "haxe.exe";
Expand All @@ -114,6 +138,18 @@ class Utils {
}
}

public static function find(v:String, ?rec:Bool = false):Null<String> {
var dir = Path.join([versionsDir, v]);
if (FileSystem.exists(dir)) return dir;

dir = Path.join([releasesDir, v]);
if (FileSystem.exists(dir)) return dir;

v = resolveRelease(v);
if (v != null) return Path.join([releasesDir, v]);
return null;
}

public static function hasVersion(v:String):Bool {
final dir = Path.join([versionsDir, v]);
return FileSystem.exists(dir);
Expand All @@ -135,9 +171,18 @@ class Utils {
return null;
}

public static function selectRelease(r:String):Void {
public static function hasRelease(r:String):Bool {
final dir = Path.join([releasesDir, r]);
if (!FileSystem.exists(dir)) throw 'Version $r is not installed';
return FileSystem.exists(dir);
}

public static function selectRelease(r:String):Void {
var dir = Path.join([releasesDir, r]);
if (!hasRelease(r)) {
r = resolveRelease(r);
if (r == null) throw 'Version $r is not installed';
dir = Path.join([releasesDir, r]);
}

unlinkCurrent();
link(dir);
Expand All @@ -161,4 +206,15 @@ class Utils {
FileSync.symlink(dir, currentDir, [SYMLINK_DIR]);
}
}

public static function rmdir(dir:String) {
if (!FileSystem.isDirectory(dir)) return; // TODO: error?

for (entry in FileSystem.readDirectory(dir)) {
final path = Path.join([dir, entry]);
try FileSystem.deleteFile(path) catch(_) rmdir(path);
}

FileSystem.deleteDirectory(dir);
}
}

0 comments on commit 80313c5

Please sign in to comment.