Skip to content

Commit

Permalink
Separate archive.* files
Browse files Browse the repository at this point in the history
  • Loading branch information
mtorpey committed Sep 4, 2024
1 parent 51ddaf1 commit cb7852d
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 142 deletions.
12 changes: 0 additions & 12 deletions gap/PackageManager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,6 @@ SetInfoLevel(InfoPackageManager, 3);
#! <K>true</K> or <K>false</K>
DeclareGlobalFunction("InstallPackageFromInfo");

#! @Description
#! Attempts to download and install a package from an archive located at the
#! given URL. Returns <K>true</K> if the installation was successful, and
#! <K>false</K> otherwise.
#! @Arguments url
#! @Returns
#! <K>true</K> or <K>false</K>
DeclareGlobalFunction("InstallPackageFromArchive");

#! @Section Removing packages

#! @Description
Expand Down Expand Up @@ -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",
Expand Down
91 changes: 0 additions & 91 deletions gap/PackageManager.gi
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 10 additions & 0 deletions gap/archive.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#! @Description
#! Attempts to download and install a package from an archive located at the
#! given URL. Returns <K>true</K> if the installation was successful, and
#! <K>false</K> otherwise.
#! @Arguments url
#! @Returns
#! <K>true</K> or <K>false</K>
DeclareGlobalFunction("InstallPackageFromArchive");

PKGMAN_ArchiveFormats := [".tar.gz", ".tar.bz2"];
90 changes: 90 additions & 0 deletions gap/archive.gi
Original file line number Diff line number Diff line change
@@ -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);
1 change: 1 addition & 0 deletions init.g
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
1 change: 1 addition & 0 deletions read.g
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
39 changes: 0 additions & 39 deletions tst/PackageManager.tst
Original file line number Diff line number Diff line change
Expand Up @@ -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: <name> must be a string
Expand Down Expand Up @@ -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);;
Expand All @@ -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/"));
43 changes: 43 additions & 0 deletions tst/archive.tst
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit cb7852d

Please sign in to comment.