Skip to content

Commit

Permalink
builder: Automatically compress man pages. Resolves serpent-os#16
Browse files Browse the repository at this point in the history
Compress any man page files found in the manifest with zstd.

There are three considerations:-
- It _will_ increase the size of the resulting .stone file(s),
  compressing .stones with --long could resolve this.
- Info pages are currently ignored but could also be compressed.
- Updating symlinks is not yet tested.
  • Loading branch information
joebonrichie committed Sep 17, 2022
1 parent 1b1e9f9 commit 9a328db
Showing 1 changed file with 52 additions and 0 deletions.
52 changes: 52 additions & 0 deletions source/mason/build/builder.d
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ private:
/* Reject libtool (.la) files */
AnalysisChain("libtoolFiles", [&rejectLibToolFiles], 90),

/* Automatically compress any man pages with zstd */
AnalysisChain("compressManPages", [&compressManPages], 90),

/* Handle ELF files */
/* FIXME: Parallel debuginfo handling truncates hardlinked files! */
AnalysisChain("elves", [
Expand Down Expand Up @@ -463,6 +466,55 @@ private:
return AnalysisReturn.NextFunction;
}

static AnalysisReturn compressManPages(scope Analyser analyser, ref FileInfo fileInfo)
{
import std.file;
import std.stdio: toFile;
import std.string : format;
import zstd;

auto filename = fileInfo.path;
auto instance = analyser.userdata!Builder;

/* Find a man page file */
if (filename.canFind("man") && filename.endsWith("1", "2", "3", "4", "5", "6", "7", "8", "9"))
{
/* Already compressed */
if (filename.endsWith(".gz", ".bz2", ".lz", ".zst", ".xz"))
{
return AnalysisReturn.NextHandler;
}

/* We have a symlink file, update it to point to the compressed file */
// FIXME: Not tested
if ((fileInfo.type == FileType.Symlink) && (fileInfo.type != FileType.Directory))
{
auto actualpath = std.file.readLink(fileInfo.path);
std.file.symlink(format!"%s.zst"(actualpath), format!"%s.zst"(fileInfo.path));
instance.collectPath(format!"%s.zst"(fileInfo.fullPath), instance.profiles[0].installRoot);
// HACK: return ignorefile to drop the old link
return AnalysisReturn.IgnoreFile;
}

auto manfile = std.file.read(fileInfo.fullPath);

// Compress it in memory
auto compressedmanfile = compress(manfile, 19);
info(format!"[Man] Compressing: %s. Original size: %s Compressed size: %s"(fileInfo.path, manfile.length, compressedmanfile.length));

// Write the compressed file to disk
File f = File(format!"%s.zst"(fileInfo.fullPath), "w");
f.rawWrite(compressedmanfile);

// Ensure it's collected into the manifest
instance.collectPath(format!"%s.zst"(fileInfo.fullPath), instance.profiles[0].installRoot);

// HACK: Remove the original pre-compressed file.
return AnalysisReturn.IgnoreFile;
}
return AnalysisReturn.NextHandler;
}

/**
* Interface back with boulder instance for file stripping. This is specific
* to ELF files only (i.e. split for debuginfo)
Expand Down

0 comments on commit 9a328db

Please sign in to comment.