diff --git a/Earthfile b/Earthfile index 7fc85de3..a7c80e1e 100644 --- a/Earthfile +++ b/Earthfile @@ -102,6 +102,7 @@ devcontainer-base: # install neko COPY +neko/neko /usr/bin/neko + COPY +neko/nekotools /usr/bin/nekotools COPY +neko/libneko.so* /usr/lib/ RUN mkdir -p /usr/lib/neko/ COPY +neko/*.ndll /usr/lib/neko/ diff --git a/src/haxelib/api/Connection.hx b/src/haxelib/api/Connection.hx index 991735c5..2d7c6b2c 100644 --- a/src/haxelib/api/Connection.hx +++ b/src/haxelib/api/Connection.hx @@ -237,7 +237,7 @@ class Connection { `downloadProgress` is the function used to log download information. **/ #if js - public static function download(fileUrl:String, outPath:String, downloadProgress = null):Void { + public static function downloadFromSite(fileUrl:String, outPath:String, downloadProgress = null):Void { node_fetch.Fetch.call(fileUrl, { headers: { "User-Agent": 'haxelib ${Util.getHaxelibVersionLong()}', @@ -248,9 +248,13 @@ class Connection { .sync(); } #else - public static function download(filename:String, outPath:String, downloadProgress:DownloadProgress = null) { - final maxRetry = 3; + public static function downloadFromSite(filename:String, outPath:String, downloadProgress:DownloadProgress = null) { final fileUrl = haxe.io.Path.join([data.siteUrl, Data.REPOSITORY, filename]); + download(fileUrl, outPath, downloadProgress); + } + + public static function download(fileUrl:String, outPath:String, downloadProgress:DownloadProgress = null) { + final maxRetry = 3; var lastError = new haxe.Exception(""); for (i in 0...maxRetry) { diff --git a/src/haxelib/api/Installer.hx b/src/haxelib/api/Installer.hx index d2e20428..e3c08248 100644 --- a/src/haxelib/api/Installer.hx +++ b/src/haxelib/api/Installer.hx @@ -186,8 +186,33 @@ class Installer { /** Installs library from the zip file at `path`. **/ public function installLocal(path:String) { - final path = FileSystem.fullPath(path); - userInterface.log('Installing $path'); + installFromUri(path); + } + + /** Installs library from the zip file at `uri`. **/ + public function installFromUri(uri:String) { + var fileName = haxe.io.Path.withoutDirectory(uri); + var path:String; + + if (uri.startsWith("http://") || uri.startsWith("https://")) { + final progressFunction = switch userInterface.getDownloadProgressFunction() { + case null: + null; + case fn: + (f, c, m, d, t) -> { + fn('Downloading $uri', f, c, m, d, t); + }; + }; + + path = haxe.io.Path.join([repository.path, fileName]); + + Connection.download(uri, path, progressFunction); + userInterface.log('Installing $fileName'); + } else { + path = FileSystem.fullPath(uri); + userInterface.log('Installing $path'); + } + // read zip content final zip = FsUtils.unzip(path); @@ -693,7 +718,7 @@ class Installer { (f, c, m, d, t) -> {fn('Downloading $filename', f, c, m, d, t);}; }; - Connection.download(filename, filepath, progressFunction); + Connection.downloadFromSite(filename, filepath, progressFunction); final zip = try FsUtils.unzip(filepath) catch (e) { FileSystem.deleteFile(filepath); diff --git a/src/haxelib/client/Main.hx b/src/haxelib/client/Main.hx index 70c23afb..98340cf4 100644 --- a/src/haxelib/client/Main.hx +++ b/src/haxelib/client/Main.hx @@ -459,6 +459,8 @@ class Main { case jsonPath if (jsonPath.endsWith("haxelib.json")): return installer.installFromHaxelibJson(jsonPath); } + } else if ((toInstall.startsWith("https://") || toInstall.startsWith("http://")) && toInstall.endsWith(".zip")) { + return installer.installFromUri(toInstall); } // Name provided that wasn't a local hxml or zip, so try to install it from server final info = Connection.getInfo(ProjectName.ofString(toInstall)); diff --git a/test/tests/integration/TestInstall.hx b/test/tests/integration/TestInstall.hx index d857bf42..e964f893 100644 --- a/test/tests/integration/TestInstall.hx +++ b/test/tests/integration/TestInstall.hx @@ -7,6 +7,8 @@ class TestInstall extends IntegrationTests { final gitLibPath = "libraries/libBar"; final hgLibPath = "libraries/libBar"; + var fileServerProcess:sys.io.Process; + override function setup(){ super.setup(); @@ -21,11 +23,19 @@ class TestInstall extends IntegrationTests { assertSuccess(r); final r = haxelib(["submit", Path.join([IntegrationTests.projectRoot, "test/libraries/libFoo.zip"]), foo.pw]).result(); assertSuccess(r); + + fileServerProcess = new sys.io.Process("nekotools", [ + "server", + "-d", Path.join([IntegrationTests.projectRoot, "test/libraries" + ])]); } override function tearDown() { resetGitRepo(gitLibPath); resetHgRepo(hgLibPath); + + fileServerProcess.kill(); + super.tearDown(); } @@ -254,4 +264,13 @@ class TestInstall extends IntegrationTests { assertOutputEquals(["Error: Failed installing dependencies for Foo:", "Could not clone Git repository."], r.err.trim()); } + + function testZipFromHttp() { + final r = haxelib(["install", "http://localhost:2000/libBar.zip"]).result(); + assertSuccess(r); + + final r = haxelib(["list", "Bar"]).result(); + assertTrue(r.out.indexOf("Bar") >= 0); + assertSuccess(r); + } } diff --git a/www/documentation-files/using-haxelib.md b/www/documentation-files/using-haxelib.md index 265b4d93..ccecc414 100644 --- a/www/documentation-files/using-haxelib.md +++ b/www/documentation-files/using-haxelib.md @@ -130,8 +130,12 @@ haxelib install build.hxml ### haxelib install [library-file] Install the project contained in the zip file. -``` + +```sh +# from local file haxelib install actuate.zip +# from url +haxelib install https://github.com/openfl/actuate/archive/refs/tags/1.9.0.zip ```