diff --git a/gap/PackageManager.gd b/gap/PackageManager.gd
index 4cad0c1..dddf03e 100644
--- a/gap/PackageManager.gd
+++ b/gap/PackageManager.gd
@@ -132,15 +132,6 @@ SetInfoLevel(InfoPackageManager, 3);
#! true or false
DeclareGlobalFunction("InstallPackageFromInfo");
-#! @Description
-#! Attempts to download and install a package from an archive located at the
-#! given URL. Returns true if the installation was successful, and
-#! false otherwise.
-#! @Arguments url
-#! @Returns
-#! true or false
-DeclareGlobalFunction("InstallPackageFromArchive");
-
#! @Section Removing packages
#! @Description
@@ -173,9 +164,6 @@ DeclareGlobalFunction("PKGMAN_RefreshPackageInfo");
DeclareGlobalFunction("PKGMAN_ValidatePackageInfo");
DeclareGlobalFunction("PKGMAN_InfoWithIndent");
-# Hidden variables
-PKGMAN_ArchiveFormats := [".tar.gz", ".tar.bz2"];
-
# PackageInfo must at least contain the following to pass:
PKGMAN_RequiredPackageInfoFields := ["PackageName",
"PackageDoc",
diff --git a/gap/PackageManager.gi b/gap/PackageManager.gi
index 289f404..dd8c712 100644
--- a/gap/PackageManager.gi
+++ b/gap/PackageManager.gi
@@ -110,97 +110,6 @@ function(info, version...)
return InstallPackageFromArchive(url);
end);
-InstallGlobalFunction(InstallPackageFromArchive,
-function(url)
- local get, user_pkg_dir, url_parts, filename, path, tar, options, exec,
- files, topdir, dir, movedname;
-
- # Download archive
- Info(InfoPackageManager, 3, "Downloading archive from URL ", url, " ...");
- get := PKGMAN_DownloadURL(url);
- if get.success <> true then
- Info(InfoPackageManager, 1, "Could not download from ", url);
- return false;
- fi;
- user_pkg_dir := PKGMAN_PackageDir();
- url_parts := SplitString(url, "/");
- filename := url_parts[Length(url_parts)];
- path := Filename(DirectoryTemporary(), filename);
- path := Concatenation(path, ".pkgman"); # TEMP: hack till GAP #4110 is merged
- FileString(path, get.result);
- Info(InfoPackageManager, 2, "Saved archive to ", path);
-
- # Check which version of tar we are using
- tar := PKGMAN_Exec(".", "tar", "--version");
- if StartsWith(tar.output, "tar (GNU tar)") then
- options := "--warning=none";
- else
- options := "";
- fi;
-
- # Check contents
- exec := PKGMAN_Exec(".", "tar", options, "-tf", path);
- if exec.code <> 0 then
- Info(InfoPackageManager, 1, "Could not inspect tarball contents");
- return false;
- fi;
- files := SplitString(exec.output, "", "\n");
- topdir := Set(files, f -> SplitString(f, "/")[1]);
- if Length(topdir) <> 1 then
- Info(InfoPackageManager, 1,
- "Archive should contain 1 directory (not ", Length(topdir), ")");
- return false;
- fi;
- topdir := topdir[1];
-
- # Check availability of target location
- dir := Filename(Directory(user_pkg_dir), topdir);
- if not PKGMAN_IsValidTargetDir(dir) then
- if IsDirectoryPath(dir) and IsWritableFile(dir) and IsReadableFile(dir) then
- # old version installed with the same name: change dir name
- movedname := Concatenation(dir, ".old");
- Info(InfoPackageManager, 1, "Appending '.old' to old version directory");
- exec := PKGMAN_Exec(".", "mv", dir, movedname);
- PKGMAN_RefreshPackageInfo();
- if exec.code <> 0 then
- Info(InfoPackageManager, 1, "Could not rename old package directory");
- return false;
- fi;
- else
- return false;
- fi;
- fi;
-
- # Extract package
- Info(InfoPackageManager, 2, "Extracting to ", dir, " ...");
- exec := PKGMAN_Exec(".", "tar", "xf", path, "-C", user_pkg_dir);
- if exec.code <> 0 then
- Info(InfoPackageManager, 1, "Extraction unsuccessful");
- return false;
- fi;
- Info(InfoPackageManager, 4, "Extracted successfully");
-
- # Install dependencies
- if PKGMAN_InstallDependencies(dir) <> true then
- Info(InfoPackageManager, 1, "Dependencies not satisfied for ", topdir);
- if ValueOption("keepDirectory") <> true then
- PKGMAN_RemoveDir(dir);
- fi;
- return false;
- fi;
-
- # Check validity
- if PKGMAN_CheckPackage(dir) = false then
- if ValueOption("keepDirectory") <> true then
- PKGMAN_RemoveDir(dir);
- fi;
- return false;
- fi;
- PKGMAN_RefreshPackageInfo();
-
- return true;
-end);
-
BindGlobal("PKGMAN_GetPackageInfo",
function(dir_or_stream)
local fname, info;
diff --git a/gap/archive.gd b/gap/archive.gd
new file mode 100644
index 0000000..28b9e39
--- /dev/null
+++ b/gap/archive.gd
@@ -0,0 +1,10 @@
+#! @Description
+#! Attempts to download and install a package from an archive located at the
+#! given URL. Returns true if the installation was successful, and
+#! false otherwise.
+#! @Arguments url
+#! @Returns
+#! true or false
+DeclareGlobalFunction("InstallPackageFromArchive");
+
+PKGMAN_ArchiveFormats := [".tar.gz", ".tar.bz2"];
diff --git a/gap/archive.gi b/gap/archive.gi
new file mode 100644
index 0000000..62dd5d6
--- /dev/null
+++ b/gap/archive.gi
@@ -0,0 +1,90 @@
+InstallGlobalFunction(InstallPackageFromArchive,
+function(url)
+ local get, user_pkg_dir, url_parts, filename, path, tar, options, exec,
+ files, topdir, dir, movedname;
+
+ # Download archive
+ Info(InfoPackageManager, 3, "Downloading archive from URL ", url, " ...");
+ get := PKGMAN_DownloadURL(url);
+ if get.success <> true then
+ Info(InfoPackageManager, 1, "Could not download from ", url);
+ return false;
+ fi;
+ user_pkg_dir := PKGMAN_PackageDir();
+ url_parts := SplitString(url, "/");
+ filename := url_parts[Length(url_parts)];
+ path := Filename(DirectoryTemporary(), filename);
+ path := Concatenation(path, ".pkgman"); # TEMP: hack till GAP #4110 is merged
+ FileString(path, get.result);
+ Info(InfoPackageManager, 2, "Saved archive to ", path);
+
+ # Check which version of tar we are using
+ tar := PKGMAN_Exec(".", "tar", "--version");
+ if StartsWith(tar.output, "tar (GNU tar)") then
+ options := "--warning=none";
+ else
+ options := "";
+ fi;
+
+ # Check contents
+ exec := PKGMAN_Exec(".", "tar", options, "-tf", path);
+ if exec.code <> 0 then
+ Info(InfoPackageManager, 1, "Could not inspect tarball contents");
+ return false;
+ fi;
+ files := SplitString(exec.output, "", "\n");
+ topdir := Set(files, f -> SplitString(f, "/")[1]);
+ if Length(topdir) <> 1 then
+ Info(InfoPackageManager, 1,
+ "Archive should contain 1 directory (not ", Length(topdir), ")");
+ return false;
+ fi;
+ topdir := topdir[1];
+
+ # Check availability of target location
+ dir := Filename(Directory(user_pkg_dir), topdir);
+ if not PKGMAN_IsValidTargetDir(dir) then
+ if IsDirectoryPath(dir) and IsWritableFile(dir) and IsReadableFile(dir) then
+ # old version installed with the same name: change dir name
+ movedname := Concatenation(dir, ".old");
+ Info(InfoPackageManager, 1, "Appending '.old' to old version directory");
+ exec := PKGMAN_Exec(".", "mv", dir, movedname);
+ PKGMAN_RefreshPackageInfo();
+ if exec.code <> 0 then
+ Info(InfoPackageManager, 1, "Could not rename old package directory");
+ return false;
+ fi;
+ else
+ return false;
+ fi;
+ fi;
+
+ # Extract package
+ Info(InfoPackageManager, 2, "Extracting to ", dir, " ...");
+ exec := PKGMAN_Exec(".", "tar", "xf", path, "-C", user_pkg_dir);
+ if exec.code <> 0 then
+ Info(InfoPackageManager, 1, "Extraction unsuccessful");
+ return false;
+ fi;
+ Info(InfoPackageManager, 4, "Extracted successfully");
+
+ # Install dependencies
+ if PKGMAN_InstallDependencies(dir) <> true then
+ Info(InfoPackageManager, 1, "Dependencies not satisfied for ", topdir);
+ if ValueOption("keepDirectory") <> true then
+ PKGMAN_RemoveDir(dir);
+ fi;
+ return false;
+ fi;
+
+ # Check validity
+ if PKGMAN_CheckPackage(dir) = false then
+ if ValueOption("keepDirectory") <> true then
+ PKGMAN_RemoveDir(dir);
+ fi;
+ return false;
+ fi;
+ PKGMAN_RefreshPackageInfo();
+
+ return true;
+end);
diff --git a/init.g b/init.g
index c639168..f1c7152 100644
--- a/init.g
+++ b/init.g
@@ -5,6 +5,7 @@
#
ReadPackage("PackageManager", "gap/PackageManager.gd");
+ReadPackage("PackageManager", "gap/archive.gd");
ReadPackage("PackageManager", "gap/compile.gd");
ReadPackage("PackageManager", "gap/directories.gd");
ReadPackage("PackageManager", "gap/distro.gd");
diff --git a/read.g b/read.g
index 0bf8975..f8f7520 100644
--- a/read.g
+++ b/read.g
@@ -5,6 +5,7 @@
#
ReadPackage("PackageManager", "gap/PackageManager.gi");
+ReadPackage("PackageManager", "gap/archive.gi");
ReadPackage("PackageManager", "gap/compile.gi");
ReadPackage("PackageManager", "gap/directories.gi");
ReadPackage("PackageManager", "gap/distro.gi");
diff --git a/tst/PackageManager.tst b/tst/PackageManager.tst
index 231f791..4825117 100644
--- a/tst/PackageManager.tst
+++ b/tst/PackageManager.tst
@@ -19,15 +19,6 @@ true
gap> RemovePackage("autpgrp", false);
true
-# Install a package from a .tar.gz archive
-gap> InstallPackage("https://github.com/gap-packages/example/releases/download/v4.2.1/Example-4.2.1.tar.gz");
-true
-gap> ForAny(DirectoryContents(PKGMAN_PackageDir()),
-> f -> StartsWith(LowercaseString(f), "example"));
-true
-gap> RemovePackage("example", false);
-true
-
# RemovePackage failure
gap> RemovePackage(3);
Error, PackageManager: RemovePackage: must be a string
@@ -80,20 +71,6 @@ gap> InstallPackage("http://www.nothing.rubbish/PackageInfo.g");
#I Unable to download from http://www.nothing.rubbish/PackageInfo.g
false
-# InstallPackageFromArchive failure
-gap> InstallPackage("www.gap.rubbish/somepackage.tar.gz");
-#I Could not download from www.gap.rubbish/somepackage.tar.gz
-false
-gap> InstallPackage("https://gap-packages.github.io/PackageManager/dummy/bad-tarball.tar.gz");
-#I Could not inspect tarball contents
-false
-gap> InstallPackage("https://gap-packages.github.io/PackageManager/dummy/twodirs.tar.gz");
-#I Archive should contain 1 directory (not 2)
-false
-gap> InstallPackage("https://gap-packages.github.io/PackageManager/dummy/badpackage.tar.gz");
-#I PackageInfo.g lacks PackageName field
-false
-
# Check a bad package directory
gap> baddir := Filename(Directory(PKGMAN_PackageDir()), "badpkg");;
gap> CreateDir(baddir);;
@@ -119,22 +96,6 @@ true
gap> InstallPackage("https://github.com/gap-packages/toric/releases/download/v1.9.5/Toric-1.9.5.tar.gz");
true
-# Updating old package that doesn't have the version number in its directory name
-gap> InstallPackage("https://www.math.colostate.edu/~hulpke/transgrp/transgrp3.6.4.tar.gz");
-true
-gap> oldinfo := First(PackageInfo("transgrp"), x -> x.Version = "3.6.4");;
-gap> oldinfo <> fail;
-true
-gap> PositionSublist(oldinfo.InstallationPath, "3.6.4"); # version number not in dir name
-fail
-gap> UpdatePackage("transgrp", false);
-#I Package already installed at target location
-#I Appending '.old' to old version directory
-true
-gap> newinfo := PackageInfo("transgrp")[1];;
-gap> CompareVersionNumbers(newinfo.Version, ">=3.6.5");
-true
-
# FINAL TEST
# (keep this at the end of the file)
gap> PKGMAN_SetCustomPackageDir(Filename(DirectoryTemporary(), "pkg/"));
diff --git a/tst/archive.tst b/tst/archive.tst
new file mode 100644
index 0000000..18423f7
--- /dev/null
+++ b/tst/archive.tst
@@ -0,0 +1,43 @@
+# Install a package from a .tar.gz archive
+gap> InstallPackage("https://github.com/gap-packages/example/releases/download/v4.2.1/Example-4.2.1.tar.gz");
+true
+gap> ForAny(DirectoryContents(PKGMAN_PackageDir()),
+> f -> StartsWith(LowercaseString(f), "example"));
+true
+gap> RemovePackage("example", false);
+true
+
+# InstallPackageFromArchive failure
+gap> InstallPackage("www.gap.rubbish/somepackage.tar.gz");
+#I Could not download from www.gap.rubbish/somepackage.tar.gz
+false
+gap> InstallPackage("https://gap-packages.github.io/PackageManager/dummy/bad-tarball.tar.gz");
+#I Could not inspect tarball contents
+false
+gap> InstallPackage("https://gap-packages.github.io/PackageManager/dummy/twodirs.tar.gz");
+#I Archive should contain 1 directory (not 2)
+false
+gap> InstallPackage("https://gap-packages.github.io/PackageManager/dummy/badpackage.tar.gz");
+#I PackageInfo.g lacks PackageName field
+false
+
+# Updating old package that doesn't have the version number in its directory name
+gap> InstallPackage("https://www.math.colostate.edu/~hulpke/transgrp/transgrp3.6.4.tar.gz");
+true
+gap> oldinfo := First(PackageInfo("transgrp"), x -> x.Version = "3.6.4");;
+gap> oldinfo <> fail;
+true
+gap> PositionSublist(oldinfo.InstallationPath, "3.6.4"); # version number not in dir name
+fail
+gap> UpdatePackage("transgrp", false);
+#I Package already installed at target location
+#I Appending '.old' to old version directory
+true
+gap> newinfo := PackageInfo("transgrp")[1];;
+gap> CompareVersionNumbers(newinfo.Version, ">=3.6.5");
+true
+gap> RemoveDirectoryRecursively(newinfo.InstallationPath); # clean up for future tests
+true
+gap> PKGMAN_RefreshPackageInfo();
+gap> RemovePackage("transgrp", false);
+true