Skip to content

Commit a2e4a98

Browse files
authored
chore(build): fix rpm man page directory MONGOSH-1066 (#1148)
* chore(build): avoid hardcoding manpage name This implements the (optional) review comment in #1144 (comment), it’s nice to avoid hardcoding things that are also available through the build config file. * fixup: refactor rpm manpage inclusion code * chore: add man page checks to test rpm/deb docker setups
1 parent c87bc88 commit a2e4a98

22 files changed

+74
-22
lines changed

.evergreen.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8740,6 +8740,7 @@ buildvariants:
87408740
tasks:
87418741
- name: pkg_test_docker_centos7_rpm
87428742
- name: pkg_test_docker_centos8_rpm
8743+
- name: pkg_test_docker_fedora34_rpm
87438744
- name: pkg_test_docker_suse12_rpm
87448745
- name: pkg_test_docker_suse15_rpm
87458746
- name: pkg_test_docker_amazonlinux1_rpm

.evergreen/evergreen.yml.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,7 @@ buildvariants:
10531053
tasks:
10541054
- name: pkg_test_docker_centos7_rpm
10551055
- name: pkg_test_docker_centos8_rpm
1056+
- name: pkg_test_docker_fedora34_rpm
10561057
- name: pkg_test_docker_suse12_rpm
10571058
- name: pkg_test_docker_suse15_rpm
10581059
- name: pkg_test_docker_amazonlinux1_rpm

packages/build/src/packaging/download-manpage.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ describe('packaging download manpage', () => {
1313
);
1414

1515
const destination = join(__dirname, '..', '..', 'tmp', 'manpage');
16-
const name = 'manpages.gz';
16+
const name = 'foobar.1.gz';
1717
await downloadManpage('http://example.com', destination, name);
1818
await fs.access(join(destination, name));
1919
});

packages/build/src/packaging/download-manpage.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import fetch from 'node-fetch';
22
import tar from 'tar';
33
import { createReadStream, createWriteStream, promises as fs } from 'fs';
44
import { promisify } from 'util';
5-
import { join } from 'path';
5+
import { join, basename } from 'path';
66
import { pipeline } from 'stream';
77
import { createGzip } from 'zlib';
88

@@ -14,7 +14,7 @@ export async function downloadManpage(url: string, destination: string, name: st
1414
tar.x({ cwd: destination })
1515
);
1616
await promisify(pipeline)(
17-
createReadStream(join(destination, 'mongosh.1')),
17+
createReadStream(join(destination, basename(name, '.gz'))),
1818
createGzip(),
1919
createWriteStream(join(destination, name))
2020
);

packages/build/src/packaging/package/debian.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ describe('tarball debian', () => {
3030
expect(stdout).to.match(/^-rw-r.-r--.+\/usr\/share\/doc\/foobar\/LICENSE_foo$/m);
3131
expect(stdout).to.match(/^-rw-r.-r--.+\/usr\/share\/doc\/foobar\/README$/m);
3232
expect(stdout).to.match(/^-rw-r.-r--.+\/usr\/share\/doc\/foobar\/copyright$/m);
33-
expect(stdout).to.match(/^-rw-r.-r--.+\/usr\/share\/man\/man1\/mongosh.1.gz$/m);
33+
expect(stdout).to.match(/^-rw-r.-r--.+\/usr\/share\/man\/man1\/foobar.1.gz$/m);
3434
}
3535
{
3636
const { stdout } = await execFile('dpkg', ['-I', tarball.path]);

packages/build/src/packaging/package/debian.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { constants, promises as fs } from 'fs';
22
import path from 'path';
33
import rimraf from 'rimraf';
44
import { promisify } from 'util';
5-
import { execFile as execFileFn, generateDirFromTemplate } from './helpers';
5+
import { execFile as execFileFn, generateDirFromTemplate, getManSection } from './helpers';
66
import { PackageInformation } from './package-information';
77
import { Arch, getDebArchName } from '../../config';
88

@@ -38,7 +38,7 @@ export async function createDebianPackage(
3838

3939
if (pkg.manpage) {
4040
// Put manpage file in /usr/share/man/man1/.
41-
const manualDir = path.join(dir, pkg.metadata.debName, 'usr', 'share', 'man', 'man1');
41+
const manualDir = path.join(dir, pkg.metadata.debName, 'usr', 'share', 'man', 'man' + getManSection(pkg.manpage.packagedFilePath));
4242
await fs.mkdir(manualDir, { recursive: true });
4343
await fs.copyFile(pkg.manpage.sourceFilePath, path.join(manualDir, pkg.manpage.packagedFilePath), COPYFILE_FICLONE);
4444
}

packages/build/src/packaging/package/helpers.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,12 @@ export function sanitizeVersion(version: string, variant: 'rpm' | 'msi'): string
9393
if (variant === 'rpm') return rpmVersion;
9494
return rpmVersion.split('.').slice(0, 3).join('.');
9595
}
96+
97+
/// Transforms e.g. 'mongosh.1.gz' -> '1'
98+
export function getManSection(filename: string): string {
99+
const { section } = filename.match(/^.+\.(?<section>\d+)(?:\.gz)?$/)?.groups ?? {};
100+
if (!section) {
101+
throw new Error(`Invalid man page name: ${filename}`);
102+
}
103+
return section;
104+
}

packages/build/src/packaging/package/redhat.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ describe('tarball redhat', () => {
3838
expect(stdout).to.match(/^\/usr\/share\/doc\/foobar-1.0.0\/README$/m);
3939
expect(stdout).to.match(/^\/usr\/share\/licenses\/foobar-1.0.0\/LICENSE_bar$/m);
4040
expect(stdout).to.match(/^\/usr\/share\/licenses\/foobar-1.0.0\/LICENSE_foo$/m);
41-
expect(stdout).to.match(/^\/usr\/share\/man\/man1\/mongosh.1.gz$/m);
41+
expect(stdout).to.match(/^\/usr\/share\/man\/man1\/foobar.1.gz$/m);
4242
});
4343

4444
it('determines and copies created RPM', async() => {

packages/build/src/packaging/package/redhat.ts

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,19 @@ import { constants, promises as fs } from 'fs';
22
import path from 'path';
33
import rimraf from 'rimraf';
44
import { promisify } from 'util';
5-
import { execFile as execFileFn, generateDirFromTemplate, sanitizeVersion } from './helpers';
5+
import { execFile as execFileFn, generateDirFromTemplate, sanitizeVersion, getManSection } from './helpers';
66
import { PackageInformation } from './package-information';
77
import { Arch, getRPMArchName } from '../../config';
88

99
const { COPYFILE_FICLONE } = constants;
1010

11+
interface InstallFile {
12+
fromFilename: string;
13+
toFilename: string;
14+
category: 'man' | 'bin' | 'libexec';
15+
mode: string;
16+
}
17+
1118
/**
1219
* Creates an RPM archive.
1320
*/
@@ -23,10 +30,26 @@ export async function createRedhatPackage(
2330
// this package contains both Apache-2.0 and non-free software.
2431
// https://fedoraproject.org/wiki/Packaging:LicensingGuidelines#Multiple_Licensing_Scenarios
2532
const licenseRpm = pkg.binaries.map(({ license }) => license.rpmIdentifier).join(' and ');
26-
// Put the binaries in their expected locations.
27-
const installscriptRpm = pkg.binaries.map(({ sourceFilePath, category }) =>
28-
`mkdir -p %{buildroot}/%{_${category}dir}\n` +
29-
`install -m 755 ${path.basename(sourceFilePath)} %{buildroot}/%{_${category}dir}/${path.basename(sourceFilePath)}`)
33+
// Put buildroot files in their expected locations. This includes the binary files
34+
// and the man page.
35+
const installFiles: InstallFile[] = pkg.binaries.map(({ sourceFilePath, category }) =>
36+
({
37+
fromFilename: path.basename(sourceFilePath),
38+
toFilename: path.basename(sourceFilePath),
39+
category,
40+
mode: '755'
41+
}));
42+
if (pkg.manpage) {
43+
installFiles.push({
44+
fromFilename: pkg.manpage.packagedFilePath,
45+
toFilename: `man${getManSection(pkg.manpage.packagedFilePath)}/${pkg.manpage.packagedFilePath}`,
46+
category: 'man',
47+
mode: '644'
48+
});
49+
}
50+
const installscriptRpm = installFiles.map(({ fromFilename, toFilename, category, mode }) =>
51+
`mkdir -p %{buildroot}/%{_${category}dir}/${path.dirname(toFilename)}\n` +
52+
`install -m ${mode} ${fromFilename} %{buildroot}/%{_${category}dir}/${toFilename}`)
3053
.join('\n');
3154
// Add binaries to the package, and list license and other documentation files.
3255
// rpm will automatically put license and doc files in the directories where
@@ -38,7 +61,7 @@ export async function createRedhatPackage(
3861
...pkg.otherDocFilePaths.map(({ packagedFilePath }) => `%doc ${packagedFilePath}`),
3962
];
4063
if (pkg.manpage) {
41-
filelistRpm.push(`%doc ${pkg.manpage.packagedFilePath}`);
64+
filelistRpm.push(`%{_mandir}/man${getManSection(pkg.manpage.packagedFilePath)}/${pkg.manpage.packagedFilePath}`);
4265
}
4366
const version = sanitizeVersion(pkg.metadata.version, 'rpm');
4467
const dir = await generateDirFromTemplate(templateDir, {
-15.6 KB
Binary file not shown.

0 commit comments

Comments
 (0)