From 97412fbb26e6a0855430ee14eef6e98b51e15a77 Mon Sep 17 00:00:00 2001 From: Benjamin Houdu Date: Sun, 30 Jan 2022 19:46:03 +0100 Subject: [PATCH 1/6] :see_no_evil: ignore test folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b2eba31..f3a0c45 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ lerna-debug.log* /reports /.nyc_output test-report.html +test-folder # IDEs and editors .idea From 737538c0319b2fb8437bc3d8d85057b5712acc6c Mon Sep 17 00:00:00 2001 From: Benjamin Houdu Date: Sun, 30 Jan 2022 20:12:45 +0100 Subject: [PATCH 2/6] :zap: refactor function code, add test --- src/zambda.ts | 107 +++++------------------------------------------ src/zip.spec.ts | 29 +++++++++++++ src/zip.ts | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 96 deletions(-) create mode 100644 src/zip.spec.ts create mode 100644 src/zip.ts diff --git a/src/zambda.ts b/src/zambda.ts index 30d0234..9030862 100644 --- a/src/zambda.ts +++ b/src/zambda.ts @@ -1,94 +1,6 @@ #!/usr/bin/env node -import fs from 'fs'; -import archiver from 'archiver'; - -interface ZambdaFile { - source: string; - destination: string; -} - -type ZambdaFolder = string | ZambdaFile; - -interface ZambdaZip { - name: string; - folders: ZambdaFolder[]; - files: ZambdaFile[]; -} - -interface ZambdaConfig { - workDir: string; - zip: ZambdaZip; -} - -async function zipLambda( - configFilePath: string, -): Promise { - const configJson: string = fs.readFileSync(configFilePath, { - encoding: 'UTF-8', - }); - if (!configJson) { - throw new Error('JSON file: ' + configFilePath + ' cannot be read!'); - } - - const zambdaConfig = JSON.parse(configJson) as ZambdaConfig; - const workPath = zambdaConfig.workDir.endsWith('/') ? zambdaConfig.workDir : zambdaConfig.workDir + '/'; - return new Promise((resolve, reject) => { - const destinationPath = workPath + zambdaConfig.zip.name; - - // Init archive - const output = fs.createWriteStream(destinationPath); - const archive = archiver('zip', { - zlib: { level: 9 }, // Sets the compression level. - }); - - // Listeners on zip - output.on('close', function close(): void { - console.log(archive.pointer() + ' total bytes'); - resolve(true); - }); - output.on('end', reject); - - // Listeners on archive - archive.on('warning', function warn(err): void { - if (err.code === 'ENOENT') { - // log warning - console.warn('Error found: ' + err); - return; - } - reject(err); - }); - archive.on('error', reject); - archive.pipe(output); - - // Append files - zambdaConfig.zip?.files.forEach(f => { - const filePath = f.source; - const fileName = !!f.destination ? f.destination : f.source; - archive.file(filePath, { name: fileName }); - }); - zambdaConfig.zip?.folders.forEach(f => { - const isString = typeof f === 'string' || f instanceof String; - if (isString) { - const folder = f as string; - const directory = folder.endsWith('/') ? f : f + '/'; - const destination = folder.endsWith('/') ? folder.substring(0, folder.length - 1) : folder; - archive.directory(directory, destination); - } else { - const zambdaFile = f as ZambdaFile; - const source = zambdaFile.source.endsWith('/') ? zambdaFile.source - : zambdaFile.source + '/'; - const destination = zambdaFile.destination.endsWith('/') ? - zambdaFile.destination.substring(0, zambdaFile.destination.length - 1) - : zambdaFile.destination; - archive.directory(source, destination); - } - }); - - // Do the archive! - archive.finalize(); - }); -} +import { zip } from "./zip"; const isOK = process.argv.length > 2; if (!isOK) { @@ -96,11 +8,14 @@ if (!isOK) { process.exit(1); } -// Generate package +// Zip! const confFile = process.argv[2]; -zipLambda(confFile).then(function handler(): void { - console.log('Zambda archive for conf: ' + confFile + ' has been generated!'); -}).catch(e => { - console.error(e + ''); - process.exit(1); -}); +zip(confFile) + .then(function handler(): void { + console.log('Zambda archive for conf: ' + confFile + ' has been generated!'); + process.exit(0); + }) + .catch(e => { + console.error(e + ''); + process.exit(1); + }); diff --git a/src/zip.spec.ts b/src/zip.spec.ts new file mode 100644 index 0000000..207e0c6 --- /dev/null +++ b/src/zip.spec.ts @@ -0,0 +1,29 @@ +import { zipWithConf } from "./zip"; + +describe('zip.ts', () => { + it('should zip file from given json conf', async () => { + const result = await zipWithConf({ + workDir: 'test-folder', + zip: { + name: 'test.zip', + files: [ + { + source: 'README.md' + }, + { + source: 'package.json', + destination: 'subpath/package.json', + } + ], + folders: [ + 'resources', + { + source: 'src', + destination: 'subpath/src', + } + ], + } + }); + expect(result).toBeTruthy(); + }, 10000); +}); diff --git a/src/zip.ts b/src/zip.ts new file mode 100644 index 0000000..39792ea --- /dev/null +++ b/src/zip.ts @@ -0,0 +1,108 @@ +import fs from "fs"; +import archiver from 'archiver'; +import * as mkdirp from "mkdirp"; + +interface ZambdaFile { + source: string; + destination?: string; +} + +type ZambdaFolder = string | ZambdaFile; + +interface ZambdaZip { + name: string; + folders: ZambdaFolder[]; + files: ZambdaFile[]; +} + +interface ZambdaConfig { + workDir: string; + zip: ZambdaZip; +} + +export function zipWithConf( + zambdaConfig: ZambdaConfig, +): Promise { + // Define workPath + const workPath = zambdaConfig.workDir.endsWith('/') ? zambdaConfig.workDir : zambdaConfig.workDir + '/'; + return new Promise((resolve, reject) => { + // Create work dir + mkdirp.sync(workPath); + + // Define target zip file + const destinationPath = workPath + zambdaConfig.zip.name; + + // Init archive + const output = fs.createWriteStream(destinationPath); + const archive = archiver('zip', { + zlib: { level: 9 }, // Sets the compression level. + }); + + // Listeners on zip + output.on('close', function close(): void { + console.log(archive.pointer() + ' total bytes'); + resolve(true); + }); + output.on('end', reject); + + // Listeners on archive + archive.on('warning', function warn(err): void { + if (err.code === 'ENOENT') { + // log warning + console.warn('Error found: ' + err); + return; + } + reject(err); + }); + archive.on('error', reject); + + // Append files + zambdaConfig.zip?.files.forEach(f => { + const filePath = f.source; + const fileName = !!f.destination ? f.destination : f.source; + archive.file(filePath, { name: fileName }); + }); + + // Append folders + zambdaConfig.zip?.folders.forEach(f => { + const isString = typeof f === 'string' || f instanceof String; + if (isString) { + const folder = f as string; + const directory = folder.endsWith('/') ? f : f + '/'; + const destination = folder.endsWith('/') ? folder.substring(0, folder.length - 1) : folder; + archive.directory(directory, destination); + } else { + const zambdaFile = f as ZambdaFile; + const source = zambdaFile.source.endsWith('/') ? zambdaFile.source + : zambdaFile.source + '/'; + const destination = zambdaFile.destination.endsWith('/') ? + zambdaFile.destination.substring(0, zambdaFile.destination.length - 1) + : zambdaFile.destination; + archive.directory(source, destination); + } + }); + + // Pipe all the files + archive.pipe(output); + + // Do the archive! + archive.finalize(); + }); +} + +export async function zip( + configFilePath: string, +): Promise { + const configJson: string = fs.readFileSync(configFilePath, { + encoding: 'UTF-8', + }); + if (!configJson) { + throw new Error('JSON file: ' + configFilePath + ' cannot be read!'); + } + // Parse configuration + const zambdaConfig = JSON.parse(configJson) as ZambdaConfig; + return zipWithConf(zambdaConfig).then(() => { + console.log('gfg'); + return true; + }); +} From 4cbc3b24ad3453d4e53e80a27df3393cd1c40ec0 Mon Sep 17 00:00:00 2001 From: Benjamin Houdu Date: Sun, 30 Jan 2022 20:14:44 +0100 Subject: [PATCH 3/6] :tv: add test in github actions --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 670fc55..bc19af5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,6 +18,7 @@ jobs: - run: yarn install --frozen-lockfile - run: yarn lint - run: yarn build + - run: yarn test - run: yarn verify || true - uses: actions/upload-artifact@v2 with: From e5026e6472e21fcc5f48036aa0ef9667f381830d Mon Sep 17 00:00:00 2001 From: Benjamin Houdu Date: Sun, 30 Jan 2022 20:19:39 +0100 Subject: [PATCH 4/6] :abc: update README with badges --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d9b763b..1802c36 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Zambda: zipping things for AWS Lambda +[![npm version](https://badge.fury.io/js/zambda.svg)](https://badge.fury.io/js/zambda) [![Build Status](https://github.com/bhoudu/zambda/actions/workflows/build.yml/badge.svg?branch=develop)](https://github.com/bhoudu/zambda/actions?query=branch%3Adevelop) Zambda is a basic CLI to package files in a zip based on JSON file. ## Usage From 046c241baf1ac1cecb54c1b20a1c562074b0b292 Mon Sep 17 00:00:00 2001 From: Benjamin Houdu Date: Sun, 30 Jan 2022 20:26:41 +0100 Subject: [PATCH 5/6] :abc: update semantic-release conf --- release.config.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/release.config.js b/release.config.js index 80a70b1..a68a789 100644 --- a/release.config.js +++ b/release.config.js @@ -28,7 +28,6 @@ module.exports = { ':zap:', ':fire:', ':alembic:', - ':tada:', ':rocket:', ], }, @@ -43,8 +42,12 @@ module.exports = { ':package:', ':recycle:', ':abc:', + ':pencil:', + ':recycle:', ":bento:", - ":arrow_up:" + ":arrow_up:", + ':wrench:', + ':robot:' ] } } @@ -67,7 +70,7 @@ module.exports = { 'README.md', 'package.json' ], - message: 'chore(release): Release <%= nextRelease.version %> - <%= new Date().toLocaleDateString(\'en-US\', {year: \'numeric\', month: \'short\', day: \'numeric\', hour: \'numeric\', minute: \'numeric\' }) %> [skip ci]\\n\\n<%= nextRelease.notes %>' + message: ':tada: Release <%= nextRelease.version %> - <%= new Date().toLocaleDateString(\'en-US\', {year: \'numeric\', month: \'short\', day: \'numeric\', hour: \'numeric\', minute: \'numeric\' }) %> [skip ci]\\n\\n<%= nextRelease.notes %>' } ], '@semantic-release/npm', From 3e416500b25ca85e68d0f88bc9a73067effec527 Mon Sep 17 00:00:00 2001 From: Benjamin Houdu Date: Sun, 30 Jan 2022 20:30:27 +0100 Subject: [PATCH 6/6] :abc: clean readme --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 1802c36..87390ed 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,15 @@ -# Zambda: zipping things for AWS Lambda - +# Zambda: zipping things for AWS Lambda [![npm version](https://badge.fury.io/js/zambda.svg)](https://badge.fury.io/js/zambda) [![Build Status](https://github.com/bhoudu/zambda/actions/workflows/build.yml/badge.svg?branch=develop)](https://github.com/bhoudu/zambda/actions?query=branch%3Adevelop) -Zambda is a basic CLI to package files in a zip based on JSON file. -## Usage +Zambda is a basic CLI to package files in a zip based on JSON file. Installation - yarn install zambda + yarn install -g zambda -Configuration example file +You then write a JSON zambda configuration file `lambda_handler.zambda.json` for instance. { "workDir": "zambda-dist", @@ -35,8 +33,8 @@ Configuration example file ] } -Example of command +You run zambda with your conf file as parameter. zambda lambda_handler.zambda.json -This will procuce a zip file `my_lambda.zip` in `zambda-dist` folder. \ No newline at end of file +This will procuce a zip file `my_lambda.zip` in `zambda-dist` folder as a result. \ No newline at end of file