From 9e8b8998a32c7720b8a161bf180eab7c8c7dad57 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Tue, 26 Oct 2021 12:54:33 +0200 Subject: [PATCH 01/23] feat(manfile): setup npm script to fetch manual file --- package.json | 1 + scripts/pull-manfile.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 scripts/pull-manfile.ts diff --git a/package.json b/package.json index 8ff1e96222..58bc3ddb7f 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "report-supported-api": "lerna run --stream --scope @mongosh/shell-api report-supported-api", "post-process-nyc": "ts-node scripts/nyc/post-process-nyc-output.ts", "pre-process-coverage": "ts-node scripts/nyc/pre-process-coverage.ts", + "pull-manfile": "ts-node -P config/tsconfig.base.json scripts/pull-manfile.ts", "report-coverage": "nyc report --reporter=text --reporter=html && nyc check-coverage --lines=95", "report-coverage-ci": "npm run pre-process-coverage && nyc report --reporter=text --reporter=html && nyc check-coverage --lines=95", "generate-error-overview": "lerna run --stream --scope @mongosh/errors generate-error-overview", diff --git a/scripts/pull-manfile.ts b/scripts/pull-manfile.ts new file mode 100644 index 0000000000..33fd324d23 --- /dev/null +++ b/scripts/pull-manfile.ts @@ -0,0 +1,26 @@ +import fetch from 'node-fetch'; +import { writeFileSync } from 'fs'; +import { join } from 'path'; + +const MAN_URL = 'https://docs.mongodb.com/mongodb-shell/manpages.tar.gz'; + +const fetchData = async (): Promise => { + const response = await fetch(MAN_URL); + const data = await response.arrayBuffer(); + return Buffer.from(data); +} + +const writeDataToFile = (data: Buffer, file: string): void => { + writeFileSync(file, data); +} + +(async () => { + try { + const data = await fetchData(); + const file = join(__dirname, '..', 'manpages.tar.gz'); + writeDataToFile(data, file); + console.log('Manual file saved.'); + } catch (e) { + console.error(`Failed to write manual file. Error: ${e}`); + } +})(); \ No newline at end of file From 0887a63ee3586f077d0457cad55020667c71b8b8 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Tue, 26 Oct 2021 12:55:07 +0200 Subject: [PATCH 02/23] feat(manfile): github action to commit manual file --- .github/workflows/cron-tasks.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/cron-tasks.yml b/.github/workflows/cron-tasks.yml index cbbaba059e..d9156f10fc 100644 --- a/.github/workflows/cron-tasks.yml +++ b/.github/workflows/cron-tasks.yml @@ -52,3 +52,8 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} branch: main + - name: Update manpages.tar.gz + run: npm run pull-manfile + - name: Commit manpages.tar.gz changes + run: | + git commit --no-allow-empty -m "chore: update manpages.tar.gz" || true From 3c6446b2dfb5da90f92089283ed35278c2f252fe Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Tue, 26 Oct 2021 12:56:47 +0200 Subject: [PATCH 03/23] chore(manfile): extract file name --- scripts/pull-manfile.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/pull-manfile.ts b/scripts/pull-manfile.ts index 33fd324d23..ea2d04fd6f 100644 --- a/scripts/pull-manfile.ts +++ b/scripts/pull-manfile.ts @@ -3,6 +3,7 @@ import { writeFileSync } from 'fs'; import { join } from 'path'; const MAN_URL = 'https://docs.mongodb.com/mongodb-shell/manpages.tar.gz'; +const MAN_FILE_NAME = 'manpages.tar.gz'; const fetchData = async (): Promise => { const response = await fetch(MAN_URL); @@ -17,7 +18,7 @@ const writeDataToFile = (data: Buffer, file: string): void => { (async () => { try { const data = await fetchData(); - const file = join(__dirname, '..', 'manpages.tar.gz'); + const file = join(__dirname, '..', MAN_FILE_NAME); writeDataToFile(data, file); console.log('Manual file saved.'); } catch (e) { From aa9fac44777db411a45a2a55676ae33767632cf4 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Tue, 26 Oct 2021 14:22:33 +0200 Subject: [PATCH 04/23] feat(manfile): add manfile in tarball build --- config/build.conf.js | 4 ++++ .../build/src/packaging/package/package-information.ts | 3 +++ packages/build/src/packaging/package/tarball.ts | 7 ++++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/config/build.conf.js b/config/build.conf.js index 66e52e09fe..b51bff728c 100644 --- a/config/build.conf.js +++ b/config/build.conf.js @@ -131,6 +131,10 @@ module.exports = { } } ], + manualFile: { + sourceFilePath: path.resolve(__dirname, '..', 'manpages.tar.gz'), + packagedFilePath: 'manpages.tar.gz' + }, otherDocFilePaths: [ { sourceFilePath: path.resolve(__dirname, '..', 'packaging', 'README'), diff --git a/packages/build/src/packaging/package/package-information.ts b/packages/build/src/packaging/package/package-information.ts index e998f41bc4..b4873bbfb0 100644 --- a/packages/build/src/packaging/package/package-information.ts +++ b/packages/build/src/packaging/package/package-information.ts @@ -3,6 +3,8 @@ interface DocumentationFile { packagedFilePath: string; } +type ManualFile = DocumentationFile; + interface LicenseInformation extends DocumentationFile { debIdentifier: string; debCopyright: string; @@ -16,6 +18,7 @@ export interface PackageInformation { category: 'bin' | 'libexec'; license: LicenseInformation; }[]; + manualFile: ManualFile; otherDocFilePaths: DocumentationFile[]; metadata: { name: string; diff --git a/packages/build/src/packaging/package/tarball.ts b/packages/build/src/packaging/package/tarball.ts index c70e7738e7..1dafaef776 100644 --- a/packages/build/src/packaging/package/tarball.ts +++ b/packages/build/src/packaging/package/tarball.ts @@ -1,4 +1,4 @@ -import { promises as fs } from 'fs'; +import { promises as fs, copyFileSync, constants } from 'fs'; import path from 'path'; import rimraf from 'rimraf'; import tar from 'tar'; @@ -12,6 +12,11 @@ import { PackageInformation } from './package-information'; export async function createTarballPackage(pkg: PackageInformation, outFile: string): Promise { const filename = path.basename(outFile).replace(/\.[^.]+$/, ''); const tmpDir = await createCompressedArchiveContents(filename, pkg); + + // Copy MAN file in tmpDir + const { sourceFilePath: manualSource, packagedFilePath: manualName } = pkg.manualFile; + copyFileSync(manualSource, path.join(tmpDir, manualName), constants.COPYFILE_FICLONE); + await tar.c({ gzip: true, file: outFile, From ef3d97c3a3ee7008b76a3be241e56e4fd156f871 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Tue, 26 Oct 2021 15:53:19 +0200 Subject: [PATCH 05/23] test(manfile): add fixtures and fix tests --- packages/build/src/packaging/package/tarball.ts | 4 ++-- packages/build/test/fixtures/manpages.tar.gz | Bin 0 -> 20480 bytes packages/build/test/fixtures/pkgconf.js | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 packages/build/test/fixtures/manpages.tar.gz diff --git a/packages/build/src/packaging/package/tarball.ts b/packages/build/src/packaging/package/tarball.ts index 1dafaef776..f7dee0aa7d 100644 --- a/packages/build/src/packaging/package/tarball.ts +++ b/packages/build/src/packaging/package/tarball.ts @@ -1,4 +1,4 @@ -import { promises as fs, copyFileSync, constants } from 'fs'; +import { promises as fs, constants } from 'fs'; import path from 'path'; import rimraf from 'rimraf'; import tar from 'tar'; @@ -15,7 +15,7 @@ export async function createTarballPackage(pkg: PackageInformation, outFile: str // Copy MAN file in tmpDir const { sourceFilePath: manualSource, packagedFilePath: manualName } = pkg.manualFile; - copyFileSync(manualSource, path.join(tmpDir, manualName), constants.COPYFILE_FICLONE); + await fs.copyFile(manualSource, path.join(tmpDir, filename, manualName), constants.COPYFILE_FICLONE); await tar.c({ gzip: true, diff --git a/packages/build/test/fixtures/manpages.tar.gz b/packages/build/test/fixtures/manpages.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..f3d1428221bb6d3a80a1701b20a01707116d4372 GIT binary patch literal 20480 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 Date: Tue, 26 Oct 2021 23:15:43 +0200 Subject: [PATCH 06/23] feat(manfile): add manfile to every distribution --- config/build.conf.js | 10 +++++----- .../build/src/packaging/package/package-information.ts | 3 --- packages/build/src/packaging/package/tarball.ts | 6 +----- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/config/build.conf.js b/config/build.conf.js index b51bff728c..103194b5b9 100644 --- a/config/build.conf.js +++ b/config/build.conf.js @@ -131,10 +131,6 @@ module.exports = { } } ], - manualFile: { - sourceFilePath: path.resolve(__dirname, '..', 'manpages.tar.gz'), - packagedFilePath: 'manpages.tar.gz' - }, otherDocFilePaths: [ { sourceFilePath: path.resolve(__dirname, '..', 'packaging', 'README'), @@ -143,7 +139,11 @@ module.exports = { { sourceFilePath: path.resolve(__dirname, '..', 'THIRD_PARTY_NOTICES.md'), packagedFilePath: 'THIRD_PARTY_NOTICES' - } + }, + { + sourceFilePath: path.resolve(__dirname, '..', 'manpages.tar.gz'), + packagedFilePath: 'manpages.tar.gz' + }, ], metadata: { name: 'mongosh', diff --git a/packages/build/src/packaging/package/package-information.ts b/packages/build/src/packaging/package/package-information.ts index b4873bbfb0..e998f41bc4 100644 --- a/packages/build/src/packaging/package/package-information.ts +++ b/packages/build/src/packaging/package/package-information.ts @@ -3,8 +3,6 @@ interface DocumentationFile { packagedFilePath: string; } -type ManualFile = DocumentationFile; - interface LicenseInformation extends DocumentationFile { debIdentifier: string; debCopyright: string; @@ -18,7 +16,6 @@ export interface PackageInformation { category: 'bin' | 'libexec'; license: LicenseInformation; }[]; - manualFile: ManualFile; otherDocFilePaths: DocumentationFile[]; metadata: { name: string; diff --git a/packages/build/src/packaging/package/tarball.ts b/packages/build/src/packaging/package/tarball.ts index f7dee0aa7d..3e71237c8d 100644 --- a/packages/build/src/packaging/package/tarball.ts +++ b/packages/build/src/packaging/package/tarball.ts @@ -1,4 +1,4 @@ -import { promises as fs, constants } from 'fs'; +import { promises as fs } from 'fs'; import path from 'path'; import rimraf from 'rimraf'; import tar from 'tar'; @@ -13,10 +13,6 @@ export async function createTarballPackage(pkg: PackageInformation, outFile: str const filename = path.basename(outFile).replace(/\.[^.]+$/, ''); const tmpDir = await createCompressedArchiveContents(filename, pkg); - // Copy MAN file in tmpDir - const { sourceFilePath: manualSource, packagedFilePath: manualName } = pkg.manualFile; - await fs.copyFile(manualSource, path.join(tmpDir, filename, manualName), constants.COPYFILE_FICLONE); - await tar.c({ gzip: true, file: outFile, From 127a94b11f0a6335b4f8bf57874ebc815fa68cdb Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Tue, 26 Oct 2021 23:16:14 +0200 Subject: [PATCH 07/23] test(manfile): fix tests --- packages/build/src/packaging/package/zip.spec.ts | 2 +- packages/build/test/fixtures/pkgconf.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/build/src/packaging/package/zip.spec.ts b/packages/build/src/packaging/package/zip.spec.ts index c1c0ba037f..d3801b3113 100644 --- a/packages/build/src/packaging/package/zip.spec.ts +++ b/packages/build/src/packaging/package/zip.spec.ts @@ -30,7 +30,7 @@ describe('package zip', () => { expect(unzip.stderr).to.be.empty; const lines = unzip.stdout.split('\n'); - expect(lines).to.have.length(13); + expect(lines).to.have.length(14); for (let i = 3; i < 10; i++) { const filename = /([^\s]+)$/.exec(lines[i])?.[1] ?? ''; diff --git a/packages/build/test/fixtures/pkgconf.js b/packages/build/test/fixtures/pkgconf.js index 3d42675e73..97acfc18ca 100644 --- a/packages/build/test/fixtures/pkgconf.js +++ b/packages/build/test/fixtures/pkgconf.js @@ -25,15 +25,15 @@ module.exports = { } } ], - manualFile: { - sourceFilePath: path.resolve(__dirname, 'manpages.tar.gz'), - packagedFilePath: 'manpages.tar.gz' - }, otherDocFilePaths: [ { sourceFilePath: path.resolve(__dirname, 'README'), packagedFilePath: 'README' }, + { + sourceFilePath: path.resolve(__dirname, 'manpages.tar.gz'), + packagedFilePath: 'manpages.tar.gz' + }, ], metadata: { version: '1.0.0', From 5d88895edd2e751794825d76f8452bb604a6791a Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Tue, 26 Oct 2021 23:16:48 +0200 Subject: [PATCH 08/23] chore(manfile): better var names --- scripts/pull-manfile.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/pull-manfile.ts b/scripts/pull-manfile.ts index ea2d04fd6f..af21c19fcf 100644 --- a/scripts/pull-manfile.ts +++ b/scripts/pull-manfile.ts @@ -2,11 +2,11 @@ import fetch from 'node-fetch'; import { writeFileSync } from 'fs'; import { join } from 'path'; -const MAN_URL = 'https://docs.mongodb.com/mongodb-shell/manpages.tar.gz'; -const MAN_FILE_NAME = 'manpages.tar.gz'; +const MANPAGE_URL = 'https://docs.mongodb.com/mongodb-shell/manpages.tar.gz'; +const MANPAGE_NAME = 'manpages.tar.gz'; const fetchData = async (): Promise => { - const response = await fetch(MAN_URL); + const response = await fetch(MANPAGE_URL); const data = await response.arrayBuffer(); return Buffer.from(data); } @@ -18,7 +18,7 @@ const writeDataToFile = (data: Buffer, file: string): void => { (async () => { try { const data = await fetchData(); - const file = join(__dirname, '..', MAN_FILE_NAME); + const file = join(__dirname, '..', MANPAGE_NAME); writeDataToFile(data, file); console.log('Manual file saved.'); } catch (e) { From 7b365a5679198fcf210248ac3765f2c01e29490c Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Tue, 26 Oct 2021 23:18:39 +0200 Subject: [PATCH 09/23] chore(manfile): clean up --- packages/build/src/packaging/package/tarball.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/build/src/packaging/package/tarball.ts b/packages/build/src/packaging/package/tarball.ts index 3e71237c8d..c70e7738e7 100644 --- a/packages/build/src/packaging/package/tarball.ts +++ b/packages/build/src/packaging/package/tarball.ts @@ -12,7 +12,6 @@ import { PackageInformation } from './package-information'; export async function createTarballPackage(pkg: PackageInformation, outFile: string): Promise { const filename = path.basename(outFile).replace(/\.[^.]+$/, ''); const tmpDir = await createCompressedArchiveContents(filename, pkg); - await tar.c({ gzip: true, file: outFile, From b51314c62fd4a9f73d7c5d9d56e67410f1bf8a2e Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Wed, 27 Oct 2021 09:56:41 +0200 Subject: [PATCH 10/23] feat(manfile): include manfile in all packages --- config/build.conf.js | 4 ++++ packages/build/src/packaging/package/debian.ts | 6 ++++++ packages/build/src/packaging/package/helpers.ts | 3 ++- .../build/src/packaging/package/package-information.ts | 3 +++ packages/build/src/packaging/package/redhat.ts | 5 ++++- packages/build/test/fixtures/pkgconf.js | 8 ++++---- 6 files changed, 23 insertions(+), 6 deletions(-) diff --git a/config/build.conf.js b/config/build.conf.js index 103194b5b9..bbef111890 100644 --- a/config/build.conf.js +++ b/config/build.conf.js @@ -145,6 +145,10 @@ module.exports = { packagedFilePath: 'manpages.tar.gz' }, ], + manfile: { + sourceFilePath: path.resolve(__dirname, '..', 'manpages.tar.gz'), + packagedFilePath: 'mongosh.1.gz' + }, metadata: { name: 'mongosh', rpmName: 'mongodb-mongosh', diff --git a/packages/build/src/packaging/package/debian.ts b/packages/build/src/packaging/package/debian.ts index 5479a9f1e6..704bb54a82 100644 --- a/packages/build/src/packaging/package/debian.ts +++ b/packages/build/src/packaging/package/debian.ts @@ -35,6 +35,12 @@ export async function createDebianPackage( for (const { sourceFilePath, packagedFilePath } of docFiles) { await fs.copyFile(sourceFilePath, path.join(docdir, packagedFilePath), COPYFILE_FICLONE); } + + // Put manfile file in /usr/share/man/man1/. + const manualDir = path.join(dir, pkg.metadata.debName, 'usr', 'share', 'man', 'man1'); + await fs.mkdir(manualDir, { recursive: true }); + await fs.copyFile(pkg.manfile.sourceFilePath, path.join(manualDir, pkg.manfile.packagedFilePath), COPYFILE_FICLONE); + // Debian packages should contain a 'copyright' file. // https://www.debian.org/doc/debian-policy/ch-archive.html#s-pkgcopyright await fs.writeFile(path.join(docdir, 'copyright'), await generateDebianCopyright(pkg)); diff --git a/packages/build/src/packaging/package/helpers.ts b/packages/build/src/packaging/package/helpers.ts index 11f459733d..09d48d24a4 100644 --- a/packages/build/src/packaging/package/helpers.ts +++ b/packages/build/src/packaging/package/helpers.ts @@ -34,7 +34,8 @@ export async function createCompressedArchiveContents(archiveRootName: string, p await fs.mkdir(archiveRoot, { recursive: true }); const docFiles = [ ...pkg.otherDocFilePaths, - ...pkg.binaries.map(({ license }) => license) + ...pkg.binaries.map(({ license }) => license), + pkg.manfile, ]; for (const { sourceFilePath, packagedFilePath } of docFiles) { await fs.copyFile(sourceFilePath, path.join(archiveRoot, packagedFilePath), COPYFILE_FICLONE); diff --git a/packages/build/src/packaging/package/package-information.ts b/packages/build/src/packaging/package/package-information.ts index e998f41bc4..0cbecaaa4f 100644 --- a/packages/build/src/packaging/package/package-information.ts +++ b/packages/build/src/packaging/package/package-information.ts @@ -9,6 +9,8 @@ interface LicenseInformation extends DocumentationFile { rpmIdentifier: string; } +type Manfile = DocumentationFile; + // This is filled in by the build config file. export interface PackageInformation { binaries: { @@ -17,6 +19,7 @@ export interface PackageInformation { license: LicenseInformation; }[]; otherDocFilePaths: DocumentationFile[]; + manfile: Manfile; metadata: { name: string; debName: string; diff --git a/packages/build/src/packaging/package/redhat.ts b/packages/build/src/packaging/package/redhat.ts index f3d9b87194..1c1bd12cb8 100644 --- a/packages/build/src/packaging/package/redhat.ts +++ b/packages/build/src/packaging/package/redhat.ts @@ -35,7 +35,8 @@ export async function createRedhatPackage( const filelistRpm = [ ...pkg.binaries.map(({ sourceFilePath, category }) => `%{_${category}dir}/${path.basename(sourceFilePath)}`), ...pkg.binaries.map(({ license }) => `%license ${license.packagedFilePath}`), - ...pkg.otherDocFilePaths.map(({ packagedFilePath }) => `%doc ${packagedFilePath}`) + ...pkg.otherDocFilePaths.map(({ packagedFilePath }) => `%doc ${packagedFilePath}`), + `%doc ${pkg.manfile.packagedFilePath}`, ].join('\n'); const version = sanitizeVersion(pkg.metadata.version, 'rpm'); const dir = await generateDirFromTemplate(templateDir, { @@ -55,6 +56,8 @@ export async function createRedhatPackage( for (const { sourceFilePath, packagedFilePath } of pkg.otherDocFilePaths) { await fs.copyFile(sourceFilePath, path.join(dir, 'BUILD', packagedFilePath), COPYFILE_FICLONE); } + // Copy manual file + await fs.copyFile(pkg.manfile.sourceFilePath, path.join(dir, 'BUILD', pkg.manfile.packagedFilePath), COPYFILE_FICLONE); // Create the package. await execFile('rpmbuild', [ diff --git a/packages/build/test/fixtures/pkgconf.js b/packages/build/test/fixtures/pkgconf.js index 97acfc18ca..0810687070 100644 --- a/packages/build/test/fixtures/pkgconf.js +++ b/packages/build/test/fixtures/pkgconf.js @@ -30,11 +30,11 @@ module.exports = { sourceFilePath: path.resolve(__dirname, 'README'), packagedFilePath: 'README' }, - { - sourceFilePath: path.resolve(__dirname, 'manpages.tar.gz'), - packagedFilePath: 'manpages.tar.gz' - }, ], + manfile: { + sourceFilePath: path.resolve(__dirname, 'manpages.tar.gz'), + packagedFilePath: 'manpages.tar.gz' + }, metadata: { version: '1.0.0', fullName: 'Very dumb dummy package', From 52cacc7b28f328fe8937d5e22d06b340791cb1bf Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Wed, 27 Oct 2021 10:29:38 +0200 Subject: [PATCH 11/23] test(manfile): add test conditions for rpm and deb --- packages/build/src/packaging/package/debian.spec.ts | 1 + packages/build/src/packaging/package/redhat.spec.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/build/src/packaging/package/debian.spec.ts b/packages/build/src/packaging/package/debian.spec.ts index f19ff57081..a27dfd7e95 100644 --- a/packages/build/src/packaging/package/debian.spec.ts +++ b/packages/build/src/packaging/package/debian.spec.ts @@ -30,6 +30,7 @@ describe('tarball debian', () => { expect(stdout).to.match(/^-rw-r.-r--.+\/usr\/share\/doc\/foobar\/LICENSE_foo$/m); expect(stdout).to.match(/^-rw-r.-r--.+\/usr\/share\/doc\/foobar\/README$/m); expect(stdout).to.match(/^-rw-r.-r--.+\/usr\/share\/doc\/foobar\/copyright$/m); + expect(stdout).to.match(/^-rw-r.-r--.+\/usr\/share\/man\/man1\/mongosh.1.gz$/m); } { const { stdout } = await execFile('dpkg', ['-I', tarball.path]); diff --git a/packages/build/src/packaging/package/redhat.spec.ts b/packages/build/src/packaging/package/redhat.spec.ts index 2e215e7af2..ac6e1998b8 100644 --- a/packages/build/src/packaging/package/redhat.spec.ts +++ b/packages/build/src/packaging/package/redhat.spec.ts @@ -38,6 +38,7 @@ describe('tarball redhat', () => { expect(stdout).to.match(/^\/usr\/share\/doc\/foobar-1.0.0\/README$/m); expect(stdout).to.match(/^\/usr\/share\/licenses\/foobar-1.0.0\/LICENSE_bar$/m); expect(stdout).to.match(/^\/usr\/share\/licenses\/foobar-1.0.0\/LICENSE_foo$/m); + expect(stdout).to.match(/^\/usr\/share\/man\/man1\/mongosh.1.gz$/m); }); it('determines and copies created RPM', async() => { From 54431746ebe4a76c8b6c62e34e58d303d9c80e8c Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Wed, 27 Oct 2021 11:14:35 +0200 Subject: [PATCH 12/23] test(manfile): download manpage in packag step --- .github/workflows/cron-tasks.yml | 5 ----- config/build.conf.js | 2 +- package.json | 1 - .../build/src/packaging/download-manfile.ts | 22 ++++++++----------- packages/build/src/packaging/run-package.ts | 5 +++++ 5 files changed, 15 insertions(+), 20 deletions(-) rename scripts/pull-manfile.ts => packages/build/src/packaging/download-manfile.ts (57%) diff --git a/.github/workflows/cron-tasks.yml b/.github/workflows/cron-tasks.yml index d9156f10fc..cbbaba059e 100644 --- a/.github/workflows/cron-tasks.yml +++ b/.github/workflows/cron-tasks.yml @@ -52,8 +52,3 @@ jobs: with: github_token: ${{ secrets.GITHUB_TOKEN }} branch: main - - name: Update manpages.tar.gz - run: npm run pull-manfile - - name: Commit manpages.tar.gz changes - run: | - git commit --no-allow-empty -m "chore: update manpages.tar.gz" || true diff --git a/config/build.conf.js b/config/build.conf.js index bbef111890..25c56123ab 100644 --- a/config/build.conf.js +++ b/config/build.conf.js @@ -146,7 +146,7 @@ module.exports = { }, ], manfile: { - sourceFilePath: path.resolve(__dirname, '..', 'manpages.tar.gz'), + sourceFilePath: path.resolve(__dirname, '..', 'tmp', 'manpages.tar.gz'), packagedFilePath: 'mongosh.1.gz' }, metadata: { diff --git a/package.json b/package.json index 58bc3ddb7f..8ff1e96222 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,6 @@ "report-supported-api": "lerna run --stream --scope @mongosh/shell-api report-supported-api", "post-process-nyc": "ts-node scripts/nyc/post-process-nyc-output.ts", "pre-process-coverage": "ts-node scripts/nyc/pre-process-coverage.ts", - "pull-manfile": "ts-node -P config/tsconfig.base.json scripts/pull-manfile.ts", "report-coverage": "nyc report --reporter=text --reporter=html && nyc check-coverage --lines=95", "report-coverage-ci": "npm run pre-process-coverage && nyc report --reporter=text --reporter=html && nyc check-coverage --lines=95", "generate-error-overview": "lerna run --stream --scope @mongosh/errors generate-error-overview", diff --git a/scripts/pull-manfile.ts b/packages/build/src/packaging/download-manfile.ts similarity index 57% rename from scripts/pull-manfile.ts rename to packages/build/src/packaging/download-manfile.ts index af21c19fcf..76ef7ec5b7 100644 --- a/scripts/pull-manfile.ts +++ b/packages/build/src/packaging/download-manfile.ts @@ -5,23 +5,19 @@ import { join } from 'path'; const MANPAGE_URL = 'https://docs.mongodb.com/mongodb-shell/manpages.tar.gz'; const MANPAGE_NAME = 'manpages.tar.gz'; -const fetchData = async (): Promise => { +const fetchData = async(): Promise => { const response = await fetch(MANPAGE_URL); const data = await response.arrayBuffer(); return Buffer.from(data); -} +}; const writeDataToFile = (data: Buffer, file: string): void => { writeFileSync(file, data); -} +}; -(async () => { - try { - const data = await fetchData(); - const file = join(__dirname, '..', MANPAGE_NAME); - writeDataToFile(data, file); - console.log('Manual file saved.'); - } catch (e) { - console.error(`Failed to write manual file. Error: ${e}`); - } -})(); \ No newline at end of file +export async function downloadManpage(destination: string) { + const data = await fetchData(); + const file = join(destination, MANPAGE_NAME); + writeDataToFile(data, file); + console.info('Manual file saved.'); +} diff --git a/packages/build/src/packaging/run-package.ts b/packages/build/src/packaging/run-package.ts index e59ea4f11e..8054568ca6 100644 --- a/packages/build/src/packaging/run-package.ts +++ b/packages/build/src/packaging/run-package.ts @@ -3,6 +3,7 @@ import path from 'path'; import os from 'os'; import { Config, Platform, validateBuildVariant } from '../config'; import { downloadMongocrypt } from './download-mongocryptd'; +import { downloadManpage } from './download-manfile'; import { macOSSignAndNotarize } from './macos-sign'; import { notarizeMsi } from './msi-sign'; import { createPackage, PackageFile } from './package'; @@ -28,6 +29,10 @@ export async function runPackage( fsConstants.COPYFILE_FICLONE); } + await downloadManpage( + path.resolve(__dirname, '..', '..', '..', '..', 'tmp') // ./mongosh/tmp + ); + const runCreatePackage = async(): Promise => { return await createPackage( config.outputDir, From 5eafecf19bfefe8050781da9fd66bef2f39dc621 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Wed, 27 Oct 2021 11:18:58 +0200 Subject: [PATCH 13/23] chore(manfile): clean up download --- packages/build/src/packaging/download-manfile.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/build/src/packaging/download-manfile.ts b/packages/build/src/packaging/download-manfile.ts index 76ef7ec5b7..7b15a0ad4c 100644 --- a/packages/build/src/packaging/download-manfile.ts +++ b/packages/build/src/packaging/download-manfile.ts @@ -1,5 +1,5 @@ import fetch from 'node-fetch'; -import { writeFileSync } from 'fs'; +import { promises as fs } from 'fs'; import { join } from 'path'; const MANPAGE_URL = 'https://docs.mongodb.com/mongodb-shell/manpages.tar.gz'; @@ -11,13 +11,8 @@ const fetchData = async(): Promise => { return Buffer.from(data); }; -const writeDataToFile = (data: Buffer, file: string): void => { - writeFileSync(file, data); -}; - export async function downloadManpage(destination: string) { const data = await fetchData(); - const file = join(destination, MANPAGE_NAME); - writeDataToFile(data, file); + await fs.writeFile(data, join(destination, MANPAGE_NAME)); console.info('Manual file saved.'); } From dfab808a775480ea2cecd455a06d71585631e0f6 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Wed, 27 Oct 2021 11:19:25 +0200 Subject: [PATCH 14/23] fix(manfile): clean up build config --- config/build.conf.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/config/build.conf.js b/config/build.conf.js index 25c56123ab..95e2ac5018 100644 --- a/config/build.conf.js +++ b/config/build.conf.js @@ -139,11 +139,7 @@ module.exports = { { sourceFilePath: path.resolve(__dirname, '..', 'THIRD_PARTY_NOTICES.md'), packagedFilePath: 'THIRD_PARTY_NOTICES' - }, - { - sourceFilePath: path.resolve(__dirname, '..', 'manpages.tar.gz'), - packagedFilePath: 'manpages.tar.gz' - }, + } ], manfile: { sourceFilePath: path.resolve(__dirname, '..', 'tmp', 'manpages.tar.gz'), From f02e068d3613b7a02454bfe75959c2cafce15cd6 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Wed, 27 Oct 2021 11:53:33 +0200 Subject: [PATCH 15/23] fix(manfile): extract manpage config --- packages/build/src/config/index.ts | 1 + packages/build/src/config/manpage-config.ts | 4 ++++ packages/build/src/packaging/download-manfile.ts | 8 +++----- 3 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 packages/build/src/config/manpage-config.ts diff --git a/packages/build/src/config/index.ts b/packages/build/src/config/index.ts index 823c7627e8..ca94f6fc25 100644 --- a/packages/build/src/config/index.ts +++ b/packages/build/src/config/index.ts @@ -4,3 +4,4 @@ export * from './get-release-version-from-tag'; export * from './platform'; export * from './should-do-public-release'; export * from './redact-config'; +export * from './manpage-config'; diff --git a/packages/build/src/config/manpage-config.ts b/packages/build/src/config/manpage-config.ts new file mode 100644 index 0000000000..ec7dabacc8 --- /dev/null +++ b/packages/build/src/config/manpage-config.ts @@ -0,0 +1,4 @@ +export const manpage = { + downloadUrl: 'https://docs.mongodb.com/mongodb-shell/manpages.tar.gz', + fileName: 'manpages.tar.gz', +}; diff --git a/packages/build/src/packaging/download-manfile.ts b/packages/build/src/packaging/download-manfile.ts index 7b15a0ad4c..adee024198 100644 --- a/packages/build/src/packaging/download-manfile.ts +++ b/packages/build/src/packaging/download-manfile.ts @@ -1,18 +1,16 @@ import fetch from 'node-fetch'; import { promises as fs } from 'fs'; import { join } from 'path'; - -const MANPAGE_URL = 'https://docs.mongodb.com/mongodb-shell/manpages.tar.gz'; -const MANPAGE_NAME = 'manpages.tar.gz'; +import { manpage as config } from './../config'; const fetchData = async(): Promise => { - const response = await fetch(MANPAGE_URL); + const response = await fetch(config.downloadUrl); const data = await response.arrayBuffer(); return Buffer.from(data); }; export async function downloadManpage(destination: string) { const data = await fetchData(); - await fs.writeFile(data, join(destination, MANPAGE_NAME)); + await fs.writeFile(join(destination, config.fileName), data); console.info('Manual file saved.'); } From 9ae2f9d2786c44408a10a6623d8ba1779856f172 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Wed, 27 Oct 2021 12:20:35 +0200 Subject: [PATCH 16/23] fix(manfile): correct filename in fixtures --- packages/build/test/fixtures/pkgconf.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/build/test/fixtures/pkgconf.js b/packages/build/test/fixtures/pkgconf.js index 0810687070..17b4ad2c30 100644 --- a/packages/build/test/fixtures/pkgconf.js +++ b/packages/build/test/fixtures/pkgconf.js @@ -33,7 +33,7 @@ module.exports = { ], manfile: { sourceFilePath: path.resolve(__dirname, 'manpages.tar.gz'), - packagedFilePath: 'manpages.tar.gz' + packagedFilePath: 'mongosh.1.gz' }, metadata: { version: '1.0.0', From e0223fec21f318ce318bbd1b24a45fa3ea0a3666 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Wed, 27 Oct 2021 13:16:25 +0200 Subject: [PATCH 17/23] feat(manfile): optional manfile in build config --- packages/build/src/packaging/package/debian.ts | 10 ++++++---- packages/build/src/packaging/package/helpers.ts | 5 ++++- .../src/packaging/package/package-information.ts | 2 +- packages/build/src/packaging/package/redhat.ts | 14 +++++++++----- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/packages/build/src/packaging/package/debian.ts b/packages/build/src/packaging/package/debian.ts index 704bb54a82..4bca62c7f5 100644 --- a/packages/build/src/packaging/package/debian.ts +++ b/packages/build/src/packaging/package/debian.ts @@ -36,10 +36,12 @@ export async function createDebianPackage( await fs.copyFile(sourceFilePath, path.join(docdir, packagedFilePath), COPYFILE_FICLONE); } - // Put manfile file in /usr/share/man/man1/. - const manualDir = path.join(dir, pkg.metadata.debName, 'usr', 'share', 'man', 'man1'); - await fs.mkdir(manualDir, { recursive: true }); - await fs.copyFile(pkg.manfile.sourceFilePath, path.join(manualDir, pkg.manfile.packagedFilePath), COPYFILE_FICLONE); + if (pkg.manfile) { + // Put manfile file in /usr/share/man/man1/. + const manualDir = path.join(dir, pkg.metadata.debName, 'usr', 'share', 'man', 'man1'); + await fs.mkdir(manualDir, { recursive: true }); + await fs.copyFile(pkg.manfile.sourceFilePath, path.join(manualDir, pkg.manfile.packagedFilePath), COPYFILE_FICLONE); + } // Debian packages should contain a 'copyright' file. // https://www.debian.org/doc/debian-policy/ch-archive.html#s-pkgcopyright diff --git a/packages/build/src/packaging/package/helpers.ts b/packages/build/src/packaging/package/helpers.ts index 09d48d24a4..7789191af7 100644 --- a/packages/build/src/packaging/package/helpers.ts +++ b/packages/build/src/packaging/package/helpers.ts @@ -35,8 +35,11 @@ export async function createCompressedArchiveContents(archiveRootName: string, p const docFiles = [ ...pkg.otherDocFilePaths, ...pkg.binaries.map(({ license }) => license), - pkg.manfile, ]; + if (pkg.manfile) { + docFiles.push(pkg.manfile); + } + for (const { sourceFilePath, packagedFilePath } of docFiles) { await fs.copyFile(sourceFilePath, path.join(archiveRoot, packagedFilePath), COPYFILE_FICLONE); } diff --git a/packages/build/src/packaging/package/package-information.ts b/packages/build/src/packaging/package/package-information.ts index 0cbecaaa4f..f16a76a2af 100644 --- a/packages/build/src/packaging/package/package-information.ts +++ b/packages/build/src/packaging/package/package-information.ts @@ -19,7 +19,7 @@ export interface PackageInformation { license: LicenseInformation; }[]; otherDocFilePaths: DocumentationFile[]; - manfile: Manfile; + manfile?: Manfile; metadata: { name: string; debName: string; diff --git a/packages/build/src/packaging/package/redhat.ts b/packages/build/src/packaging/package/redhat.ts index 1c1bd12cb8..be1593c5a6 100644 --- a/packages/build/src/packaging/package/redhat.ts +++ b/packages/build/src/packaging/package/redhat.ts @@ -36,14 +36,16 @@ export async function createRedhatPackage( ...pkg.binaries.map(({ sourceFilePath, category }) => `%{_${category}dir}/${path.basename(sourceFilePath)}`), ...pkg.binaries.map(({ license }) => `%license ${license.packagedFilePath}`), ...pkg.otherDocFilePaths.map(({ packagedFilePath }) => `%doc ${packagedFilePath}`), - `%doc ${pkg.manfile.packagedFilePath}`, - ].join('\n'); + ]; + if (pkg.manfile) { + filelistRpm.push(`%doc ${pkg.manfile.packagedFilePath}`); + } const version = sanitizeVersion(pkg.metadata.version, 'rpm'); const dir = await generateDirFromTemplate(templateDir, { ...pkg.metadata, licenseRpm, installscriptRpm, - filelistRpm, + filelistRpm: filelistRpm.join('\n'), version }); // Copy all files that we want to ship into the BUILD directory. @@ -56,8 +58,10 @@ export async function createRedhatPackage( for (const { sourceFilePath, packagedFilePath } of pkg.otherDocFilePaths) { await fs.copyFile(sourceFilePath, path.join(dir, 'BUILD', packagedFilePath), COPYFILE_FICLONE); } - // Copy manual file - await fs.copyFile(pkg.manfile.sourceFilePath, path.join(dir, 'BUILD', pkg.manfile.packagedFilePath), COPYFILE_FICLONE); + + if (pkg.manfile) { + await fs.copyFile(pkg.manfile.sourceFilePath, path.join(dir, 'BUILD', pkg.manfile.packagedFilePath), COPYFILE_FICLONE); + } // Create the package. await execFile('rpmbuild', [ From 5e855ae84f760715021b91ad25232858261a0db0 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Thu, 28 Oct 2021 10:30:09 +0200 Subject: [PATCH 18/23] feat(manfile): correctly zip manfile and clean up config --- config/build.conf.js | 22 ++++++++++++++++--- packages/build/src/config/config.ts | 7 ++++++ .../build/src/packaging/download-manfile.ts | 22 ++++++++++++++----- packages/build/src/packaging/run-package.ts | 11 +++++++--- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/config/build.conf.js b/config/build.conf.js index 95e2ac5018..8016a6a35e 100644 --- a/config/build.conf.js +++ b/config/build.conf.js @@ -8,6 +8,11 @@ const os = require('os'); */ const ROOT = path.join(__dirname, '..'); +/** + * The tmp folder location. + */ + const TMP_DIR = path.join(ROOT, 'tmp'); + /** * The mongosh package. */ @@ -44,7 +49,7 @@ const EXECUTABLE_PATH = path.join(OUTPUT_DIR, process.platform === 'win32' ? 'mo * We use the name mongocryptd-mongosh to avoid conflicts with users * potentially installing the 'proper' mongocryptd package. */ -const MONGOCRYPTD_PATH = path.resolve(__dirname, '..', 'tmp', 'mongocryptd-mongosh' + (process.platform === 'win32' ? '.exe' : '')); +const MONGOCRYPTD_PATH = path.resolve(TMP_DIR, 'mongocryptd-mongosh' + (process.platform === 'win32' ? '.exe' : '')); /** * Build info JSON data file. @@ -66,6 +71,12 @@ const REVISION = process.env.GITHUB_COMMIT ?? process.env.REVISION; */ const COPYRIGHT = `${new Date().getYear() + 1900} MongoDB, Inc.`; +/** + * The manual file name. Will be downloaded with this name, + * extracted and then compressed correctly (gz) into same. + */ +const MAN_FILE_NAME = 'manpages.tar.gz'; + /** * Export the configuration for the build. */ @@ -142,7 +153,7 @@ module.exports = { } ], manfile: { - sourceFilePath: path.resolve(__dirname, '..', 'tmp', 'manpages.tar.gz'), + sourceFilePath: path.resolve(TMP_DIR, MAN_FILE_NAME), packagedFilePath: 'mongosh.1.gz' }, metadata: { @@ -163,5 +174,10 @@ module.exports = { debTemplateDir: path.resolve(__dirname, '..', 'packaging', 'deb-template'), rpmTemplateDir: path.resolve(__dirname, '..', 'packaging', 'rpm-template'), msiTemplateDir: path.resolve(__dirname, '..', 'packaging', 'msi-template') - } + }, + manfile: { + sourceUrl: 'https://docs.mongodb.com/mongodb-shell/manpages.tar.gz', + downloadPath: TMP_DIR, + fileName: MAN_FILE_NAME, + }, }; diff --git a/packages/build/src/config/config.ts b/packages/build/src/config/config.ts index d4f3fea76c..771af97255 100644 --- a/packages/build/src/config/config.ts +++ b/packages/build/src/config/config.ts @@ -1,6 +1,12 @@ import type { PackageInformation } from '../packaging/package'; import { BuildVariant } from './build-variant'; +interface ManFileConfig { + sourceUrl: string; + downloadPath: string; + fileName: string; +} + /** * Defines the configuration interface for the build system. */ @@ -42,4 +48,5 @@ export interface Config { mongocryptdPath: string; packageInformation?: PackageInformation; artifactUrlFile?: string; + manfile?: ManFileConfig; } diff --git a/packages/build/src/packaging/download-manfile.ts b/packages/build/src/packaging/download-manfile.ts index adee024198..3e8983b326 100644 --- a/packages/build/src/packaging/download-manfile.ts +++ b/packages/build/src/packaging/download-manfile.ts @@ -1,16 +1,26 @@ import fetch from 'node-fetch'; +import tar from 'tar'; import { promises as fs } from 'fs'; import { join } from 'path'; -import { manpage as config } from './../config'; -const fetchData = async(): Promise => { - const response = await fetch(config.downloadUrl); +const fetchData = async(url: string): Promise => { + const response = await fetch(url); const data = await response.arrayBuffer(); return Buffer.from(data); }; -export async function downloadManpage(destination: string) { - const data = await fetchData(); - await fs.writeFile(join(destination, config.fileName), data); +export async function downloadManpage(url: string, destination: string, name: string) { + const data = await fetchData(url); + + const manFilePath = join(destination, name); + await fs.writeFile(manFilePath, data); + + await tar.x({ file: manFilePath, cwd: destination }); + + await tar.c({ + gzip: true, + file: manFilePath, + }, [join(destination, 'mongosh.1')]); + console.info('Manual file saved.'); } diff --git a/packages/build/src/packaging/run-package.ts b/packages/build/src/packaging/run-package.ts index 8054568ca6..f99b041ecd 100644 --- a/packages/build/src/packaging/run-package.ts +++ b/packages/build/src/packaging/run-package.ts @@ -29,9 +29,14 @@ export async function runPackage( fsConstants.COPYFILE_FICLONE); } - await downloadManpage( - path.resolve(__dirname, '..', '..', '..', '..', 'tmp') // ./mongosh/tmp - ); + const { manfile } = config; + if (manfile) { + await downloadManpage( + manfile.sourceUrl, + manfile.downloadPath, + manfile.fileName + ); + } const runCreatePackage = async(): Promise => { return await createPackage( From 5b05084900eb0d571623832983d03edb3fdb781a Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Thu, 28 Oct 2021 10:48:18 +0200 Subject: [PATCH 19/23] chore(manfile): remove man config --- packages/build/src/config/index.ts | 1 - packages/build/src/config/manpage-config.ts | 4 ---- 2 files changed, 5 deletions(-) delete mode 100644 packages/build/src/config/manpage-config.ts diff --git a/packages/build/src/config/index.ts b/packages/build/src/config/index.ts index ca94f6fc25..823c7627e8 100644 --- a/packages/build/src/config/index.ts +++ b/packages/build/src/config/index.ts @@ -4,4 +4,3 @@ export * from './get-release-version-from-tag'; export * from './platform'; export * from './should-do-public-release'; export * from './redact-config'; -export * from './manpage-config'; diff --git a/packages/build/src/config/manpage-config.ts b/packages/build/src/config/manpage-config.ts deleted file mode 100644 index ec7dabacc8..0000000000 --- a/packages/build/src/config/manpage-config.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const manpage = { - downloadUrl: 'https://docs.mongodb.com/mongodb-shell/manpages.tar.gz', - fileName: 'manpages.tar.gz', -}; From 2871f30c5d3ce91bf72f76ed1f9acb09892f32d4 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Thu, 28 Oct 2021 12:05:25 +0200 Subject: [PATCH 20/23] chore(manfile): consistent naming --- config/build.conf.js | 12 ++++++------ packages/build/src/config/config.ts | 4 ++-- .../{download-manfile.ts => download-manpage.ts} | 10 +++++----- packages/build/src/packaging/package/debian.ts | 6 +++--- packages/build/src/packaging/package/helpers.ts | 4 ++-- .../src/packaging/package/package-information.ts | 4 ++-- packages/build/src/packaging/package/redhat.ts | 8 ++++---- packages/build/src/packaging/run-package.ts | 12 ++++++------ 8 files changed, 30 insertions(+), 30 deletions(-) rename packages/build/src/packaging/{download-manfile.ts => download-manpage.ts} (70%) diff --git a/config/build.conf.js b/config/build.conf.js index 8016a6a35e..e98ccfa064 100644 --- a/config/build.conf.js +++ b/config/build.conf.js @@ -72,10 +72,10 @@ const REVISION = process.env.GITHUB_COMMIT ?? process.env.REVISION; const COPYRIGHT = `${new Date().getYear() + 1900} MongoDB, Inc.`; /** - * The manual file name. Will be downloaded with this name, + * The manual page name. Will be downloaded with this name, * extracted and then compressed correctly (gz) into same. */ -const MAN_FILE_NAME = 'manpages.tar.gz'; +const MANPAGE_NAME = 'manpages.tar.gz'; /** * Export the configuration for the build. @@ -152,8 +152,8 @@ module.exports = { packagedFilePath: 'THIRD_PARTY_NOTICES' } ], - manfile: { - sourceFilePath: path.resolve(TMP_DIR, MAN_FILE_NAME), + manpage: { + sourceFilePath: path.resolve(TMP_DIR, MANPAGE_NAME), packagedFilePath: 'mongosh.1.gz' }, metadata: { @@ -175,9 +175,9 @@ module.exports = { rpmTemplateDir: path.resolve(__dirname, '..', 'packaging', 'rpm-template'), msiTemplateDir: path.resolve(__dirname, '..', 'packaging', 'msi-template') }, - manfile: { + manpage: { sourceUrl: 'https://docs.mongodb.com/mongodb-shell/manpages.tar.gz', downloadPath: TMP_DIR, - fileName: MAN_FILE_NAME, + fileName: MANPAGE_NAME, }, }; diff --git a/packages/build/src/config/config.ts b/packages/build/src/config/config.ts index 771af97255..5327e5bed2 100644 --- a/packages/build/src/config/config.ts +++ b/packages/build/src/config/config.ts @@ -1,7 +1,7 @@ import type { PackageInformation } from '../packaging/package'; import { BuildVariant } from './build-variant'; -interface ManFileConfig { +interface ManPageConfig { sourceUrl: string; downloadPath: string; fileName: string; @@ -48,5 +48,5 @@ export interface Config { mongocryptdPath: string; packageInformation?: PackageInformation; artifactUrlFile?: string; - manfile?: ManFileConfig; + manpage?: ManPageConfig; } diff --git a/packages/build/src/packaging/download-manfile.ts b/packages/build/src/packaging/download-manpage.ts similarity index 70% rename from packages/build/src/packaging/download-manfile.ts rename to packages/build/src/packaging/download-manpage.ts index 3e8983b326..70e8808369 100644 --- a/packages/build/src/packaging/download-manfile.ts +++ b/packages/build/src/packaging/download-manpage.ts @@ -12,15 +12,15 @@ const fetchData = async(url: string): Promise => { export async function downloadManpage(url: string, destination: string, name: string) { const data = await fetchData(url); - const manFilePath = join(destination, name); - await fs.writeFile(manFilePath, data); + const manPagePath = join(destination, name); + await fs.writeFile(manPagePath, data); - await tar.x({ file: manFilePath, cwd: destination }); + await tar.x({ file: manPagePath, cwd: destination }); await tar.c({ gzip: true, - file: manFilePath, + file: manPagePath, }, [join(destination, 'mongosh.1')]); - console.info('Manual file saved.'); + console.info('Manual page saved.'); } diff --git a/packages/build/src/packaging/package/debian.ts b/packages/build/src/packaging/package/debian.ts index 4bca62c7f5..84942527b5 100644 --- a/packages/build/src/packaging/package/debian.ts +++ b/packages/build/src/packaging/package/debian.ts @@ -36,11 +36,11 @@ export async function createDebianPackage( await fs.copyFile(sourceFilePath, path.join(docdir, packagedFilePath), COPYFILE_FICLONE); } - if (pkg.manfile) { - // Put manfile file in /usr/share/man/man1/. + if (pkg.manpage) { + // Put manpage file in /usr/share/man/man1/. const manualDir = path.join(dir, pkg.metadata.debName, 'usr', 'share', 'man', 'man1'); await fs.mkdir(manualDir, { recursive: true }); - await fs.copyFile(pkg.manfile.sourceFilePath, path.join(manualDir, pkg.manfile.packagedFilePath), COPYFILE_FICLONE); + await fs.copyFile(pkg.manpage.sourceFilePath, path.join(manualDir, pkg.manpage.packagedFilePath), COPYFILE_FICLONE); } // Debian packages should contain a 'copyright' file. diff --git a/packages/build/src/packaging/package/helpers.ts b/packages/build/src/packaging/package/helpers.ts index 7789191af7..ed1bb06070 100644 --- a/packages/build/src/packaging/package/helpers.ts +++ b/packages/build/src/packaging/package/helpers.ts @@ -36,8 +36,8 @@ export async function createCompressedArchiveContents(archiveRootName: string, p ...pkg.otherDocFilePaths, ...pkg.binaries.map(({ license }) => license), ]; - if (pkg.manfile) { - docFiles.push(pkg.manfile); + if (pkg.manpage) { + docFiles.push(pkg.manpage); } for (const { sourceFilePath, packagedFilePath } of docFiles) { diff --git a/packages/build/src/packaging/package/package-information.ts b/packages/build/src/packaging/package/package-information.ts index f16a76a2af..f440723467 100644 --- a/packages/build/src/packaging/package/package-information.ts +++ b/packages/build/src/packaging/package/package-information.ts @@ -9,7 +9,7 @@ interface LicenseInformation extends DocumentationFile { rpmIdentifier: string; } -type Manfile = DocumentationFile; +type ManPage = DocumentationFile; // This is filled in by the build config file. export interface PackageInformation { @@ -19,7 +19,7 @@ export interface PackageInformation { license: LicenseInformation; }[]; otherDocFilePaths: DocumentationFile[]; - manfile?: Manfile; + manpage?: ManPage; metadata: { name: string; debName: string; diff --git a/packages/build/src/packaging/package/redhat.ts b/packages/build/src/packaging/package/redhat.ts index be1593c5a6..d538c51d61 100644 --- a/packages/build/src/packaging/package/redhat.ts +++ b/packages/build/src/packaging/package/redhat.ts @@ -37,8 +37,8 @@ export async function createRedhatPackage( ...pkg.binaries.map(({ license }) => `%license ${license.packagedFilePath}`), ...pkg.otherDocFilePaths.map(({ packagedFilePath }) => `%doc ${packagedFilePath}`), ]; - if (pkg.manfile) { - filelistRpm.push(`%doc ${pkg.manfile.packagedFilePath}`); + if (pkg.manpage) { + filelistRpm.push(`%doc ${pkg.manpage.packagedFilePath}`); } const version = sanitizeVersion(pkg.metadata.version, 'rpm'); const dir = await generateDirFromTemplate(templateDir, { @@ -59,8 +59,8 @@ export async function createRedhatPackage( await fs.copyFile(sourceFilePath, path.join(dir, 'BUILD', packagedFilePath), COPYFILE_FICLONE); } - if (pkg.manfile) { - await fs.copyFile(pkg.manfile.sourceFilePath, path.join(dir, 'BUILD', pkg.manfile.packagedFilePath), COPYFILE_FICLONE); + if (pkg.manpage) { + await fs.copyFile(pkg.manpage.sourceFilePath, path.join(dir, 'BUILD', pkg.manpage.packagedFilePath), COPYFILE_FICLONE); } // Create the package. diff --git a/packages/build/src/packaging/run-package.ts b/packages/build/src/packaging/run-package.ts index f99b041ecd..12600e6522 100644 --- a/packages/build/src/packaging/run-package.ts +++ b/packages/build/src/packaging/run-package.ts @@ -3,7 +3,7 @@ import path from 'path'; import os from 'os'; import { Config, Platform, validateBuildVariant } from '../config'; import { downloadMongocrypt } from './download-mongocryptd'; -import { downloadManpage } from './download-manfile'; +import { downloadManpage } from './download-manpage'; import { macOSSignAndNotarize } from './macos-sign'; import { notarizeMsi } from './msi-sign'; import { createPackage, PackageFile } from './package'; @@ -29,12 +29,12 @@ export async function runPackage( fsConstants.COPYFILE_FICLONE); } - const { manfile } = config; - if (manfile) { + const { manpage } = config; + if (manpage) { await downloadManpage( - manfile.sourceUrl, - manfile.downloadPath, - manfile.fileName + manpage.sourceUrl, + manpage.downloadPath, + manpage.fileName ); } From e2d817befa4445327c1103c20e778e9ac9a375a5 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Thu, 28 Oct 2021 15:23:29 +0200 Subject: [PATCH 21/23] chore(manfile): cr clean up, ensure file is zipped --- config/build.conf.js | 7 ++--- .../build/src/packaging/download-manpage.ts | 30 +++++++------------ 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/config/build.conf.js b/config/build.conf.js index e98ccfa064..7a2b5a129d 100644 --- a/config/build.conf.js +++ b/config/build.conf.js @@ -72,8 +72,7 @@ const REVISION = process.env.GITHUB_COMMIT ?? process.env.REVISION; const COPYRIGHT = `${new Date().getYear() + 1900} MongoDB, Inc.`; /** - * The manual page name. Will be downloaded with this name, - * extracted and then compressed correctly (gz) into same. + * The manual page file name */ const MANPAGE_NAME = 'manpages.tar.gz'; @@ -153,7 +152,7 @@ module.exports = { } ], manpage: { - sourceFilePath: path.resolve(TMP_DIR, MANPAGE_NAME), + sourceFilePath: path.resolve(TMP_DIR, 'manpage', MANPAGE_NAME), packagedFilePath: 'mongosh.1.gz' }, metadata: { @@ -177,7 +176,7 @@ module.exports = { }, manpage: { sourceUrl: 'https://docs.mongodb.com/mongodb-shell/manpages.tar.gz', - downloadPath: TMP_DIR, + downloadPath: path.resolve(TMP_DIR, 'manpage'), fileName: MANPAGE_NAME, }, }; diff --git a/packages/build/src/packaging/download-manpage.ts b/packages/build/src/packaging/download-manpage.ts index 70e8808369..b70c3aed1f 100644 --- a/packages/build/src/packaging/download-manpage.ts +++ b/packages/build/src/packaging/download-manpage.ts @@ -1,26 +1,18 @@ import fetch from 'node-fetch'; import tar from 'tar'; import { promises as fs } from 'fs'; +import { promisify } from 'util'; import { join } from 'path'; - -const fetchData = async(url: string): Promise => { - const response = await fetch(url); - const data = await response.arrayBuffer(); - return Buffer.from(data); -}; +import { pipeline } from 'stream'; +import { execFile } from './package/helpers'; export async function downloadManpage(url: string, destination: string, name: string) { - const data = await fetchData(url); - - const manPagePath = join(destination, name); - await fs.writeFile(manPagePath, data); - - await tar.x({ file: manPagePath, cwd: destination }); - - await tar.c({ - gzip: true, - file: manPagePath, - }, [join(destination, 'mongosh.1')]); - - console.info('Manual page saved.'); + await fs.mkdir(destination, { recursive: true }); + const response = await fetch(url); + await promisify(pipeline)( + response.body, + tar.x({ cwd: destination }) + ); + await execFile('zip', ['-r', name, '.'], { cwd: destination }); + console.info(`Saved manpage: ${join(destination, name)}`); } From 38feb998d3a9e88e88d1f04739316c2c7c8a0579 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Fri, 29 Oct 2021 12:44:40 +0200 Subject: [PATCH 22/23] test(manfile): fix tests and test for manpage --- .../src/packaging/download-manpage.spec.ts | 20 +++++++++++++++++++ packages/build/test/fixtures/pkgconf.js | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 packages/build/src/packaging/download-manpage.spec.ts diff --git a/packages/build/src/packaging/download-manpage.spec.ts b/packages/build/src/packaging/download-manpage.spec.ts new file mode 100644 index 0000000000..913d675fae --- /dev/null +++ b/packages/build/src/packaging/download-manpage.spec.ts @@ -0,0 +1,20 @@ +import nock from 'nock'; +import { join } from 'path'; +import { promises as fs } from 'fs'; +import { downloadManpage } from './download-manpage'; + +describe('packaging download manpage', () => { + it('downloads manpage', async() => { + nock('http://example.com') + .get('/') + .replyWithFile( + 200, + join(__dirname, '..', '..', 'test', 'fixtures', 'manpages.tar.gz') + ); + + const destination = join(__dirname, '..', '..', 'tmp', 'manpage'); + const name = 'manpages.gz'; + await downloadManpage('http://example.com', destination, name); + await fs.access(join(destination, name)); + }); +}); diff --git a/packages/build/test/fixtures/pkgconf.js b/packages/build/test/fixtures/pkgconf.js index 17b4ad2c30..8fcc51c23d 100644 --- a/packages/build/test/fixtures/pkgconf.js +++ b/packages/build/test/fixtures/pkgconf.js @@ -31,7 +31,7 @@ module.exports = { packagedFilePath: 'README' }, ], - manfile: { + manpage: { sourceFilePath: path.resolve(__dirname, 'manpages.tar.gz'), packagedFilePath: 'mongosh.1.gz' }, From 5da23860c2683074ebe04440498e15ec35bcd6b7 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Mon, 1 Nov 2021 10:11:32 +0100 Subject: [PATCH 23/23] chore(manfile): cr clean up, gzip implementation --- config/build.conf.js | 4 ++-- packages/build/src/packaging/download-manpage.ts | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/config/build.conf.js b/config/build.conf.js index 7a2b5a129d..601ba1a0f9 100644 --- a/config/build.conf.js +++ b/config/build.conf.js @@ -74,7 +74,7 @@ const COPYRIGHT = `${new Date().getYear() + 1900} MongoDB, Inc.`; /** * The manual page file name */ -const MANPAGE_NAME = 'manpages.tar.gz'; +const MANPAGE_NAME = 'mongosh.1.gz' /** * Export the configuration for the build. @@ -153,7 +153,7 @@ module.exports = { ], manpage: { sourceFilePath: path.resolve(TMP_DIR, 'manpage', MANPAGE_NAME), - packagedFilePath: 'mongosh.1.gz' + packagedFilePath: MANPAGE_NAME, }, metadata: { name: 'mongosh', diff --git a/packages/build/src/packaging/download-manpage.ts b/packages/build/src/packaging/download-manpage.ts index b70c3aed1f..7c1b6d004a 100644 --- a/packages/build/src/packaging/download-manpage.ts +++ b/packages/build/src/packaging/download-manpage.ts @@ -1,10 +1,10 @@ import fetch from 'node-fetch'; import tar from 'tar'; -import { promises as fs } from 'fs'; +import { createReadStream, createWriteStream, promises as fs } from 'fs'; import { promisify } from 'util'; import { join } from 'path'; import { pipeline } from 'stream'; -import { execFile } from './package/helpers'; +import { createGzip } from 'zlib'; export async function downloadManpage(url: string, destination: string, name: string) { await fs.mkdir(destination, { recursive: true }); @@ -13,6 +13,10 @@ export async function downloadManpage(url: string, destination: string, name: st response.body, tar.x({ cwd: destination }) ); - await execFile('zip', ['-r', name, '.'], { cwd: destination }); + await promisify(pipeline)( + createReadStream(join(destination, 'mongosh.1')), + createGzip(), + createWriteStream(join(destination, name)) + ); console.info(`Saved manpage: ${join(destination, name)}`); }