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,
if enabled by the packager.

There are three considerations:-
- It _will_ increase the size of the resulting .stone file(s),
  (compressing .stones with --long could resolve this, in the future).
- Info pages are currently ignored but could also be compressed.
- Updating symlinks is not yet tested.
  • Loading branch information
joebonrichie committed Jan 14, 2023
1 parent ca9e003 commit 3b58b18
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 0 deletions.
80 changes: 80 additions & 0 deletions source/mason/build/analysers/compressman.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* SPDX-FileCopyrightText: Copyright © 2020-2023 Serpent OS Developers
*
* SPDX-License-Identifier: Zlib
*/

/**
* mason.build.analysers.compressman;
*
* Compress man pages with zstd
*
* Authors: Copyright © 2020-2023 Serpent OS Developers
* License: Zlib
*/

module mason.build.analysers.compressman;

import mason.build.builder : Builder;
import mason.build.context;
import moss.core.sizing : formattedSize;
import std.algorithm : canFind, endsWith;
import std.experimental.logger;
import std.file;
import std.stdio: File, toFile;
import std.string : format;
import zstd : compress;
import std.conv : to;
public import moss.deps.analysis;

/**
* Detect man pages and compress them with zstd
*
* Params:
* analyser = Scoped analyser for this run
* fileInfo = Current file to run analysis on
* Returns: AnalysisReturn.NextFunction always
*/
static AnalysisReturn compressManPages(scope Analyser analyser, ref FileInfo fileInfo)
{
if (!buildContext.spec.options.compressman || fileInfo.type != FileType.Regular)
{
return AnalysisReturn.NextHandler;
}

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"))
{
/* 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(filename);
std.file.symlink(format!"%s.zst"(actualpath), format!"%s.zst"(filename));
/* Collect the updated symlink into the manifest */
instance.collectPath(format!"%s.zst"(fileInfo.fullPath), instance.installRoot);
/* Remove the original file */
return AnalysisReturn.IgnoreFile;
}

/* Compress it in memory */
auto manfile = std.file.read(fileInfo.fullPath);
auto compressedmanfile = compress(manfile, 19);
immutable double presize = manfile.length;
immutable double postsize = compressedmanfile.length;
info(format!"[Man] Compressing: %s. Original size: %s Compressed size: %s"(filename, formattedSize(presize),
formattedSize(postsize)));

/* Write the compressed file to disk */
File f = File(format!"%s.zst"(fileInfo.fullPath), "w");
f.rawWrite(compressedmanfile);
/* Collect the compressed file into the manifest */
instance.collectPath(format!"%s.zst"(fileInfo.fullPath), instance.installRoot);
/* Remove the original pre-compressed file */
return AnalysisReturn.IgnoreFile;
}
return AnalysisReturn.NextHandler;
}
1 change: 1 addition & 0 deletions source/mason/build/analysers/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module mason.build.analysers;

public import mason.build.analysers.binary;
public import mason.build.analysers.cmake;
public import mason.build.analysers.compressman;
public import mason.build.analysers.elves;
public import mason.build.analysers.rejects;
public import mason.build.analysers.pkgconfig;
3 changes: 3 additions & 0 deletions source/mason/build/builder.d
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,9 @@ private:
&acceptCmakeFiles, &handleCmakeFiles, &includeFile
], 50),

/* Compress man pages if enabled */
AnalysisChain("compressman", [&compressManPages], 40),

/* Default inclusion policy */
AnalysisChain("default", [&includeFile], 0),
];
Expand Down
1 change: 1 addition & 0 deletions source/mason/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ libmason_sources = [
'package.d',
'build/analysers/binary.d',
'build/analysers/cmake.d',
'build/analysers/compressman.d',
'build/analysers/elves.d',
'build/analysers/package.d',
'build/analysers/pkgconfig.d',
Expand Down

0 comments on commit 3b58b18

Please sign in to comment.