From 1ef29dcd6c52f761d3de7114e2fc2ccd013c0706 Mon Sep 17 00:00:00 2001 From: Xiphe Date: Thu, 28 May 2020 12:57:34 +0200 Subject: [PATCH] feat(beforeAdd): allow custom script before git add fix https://github.com/tschaub/gh-pages/issues/331 --- bin/gh-pages.js | 24 ++++++++++- lib/index.js | 5 +++ readme.md | 29 +++++++++++++ test/bin/fixtures/beforeAdd.js | 3 ++ test/bin/gh-pages.spec.js | 11 +++++ test/integration/beforeAdd.spec.js | 43 +++++++++++++++++++ .../beforeAdd/expected/hello-old-world.txt | 1 + .../beforeAdd/expected/hello-world.txt | 1 + .../fixtures/beforeAdd/local/hello-world.txt | 1 + .../beforeAdd/remote/hello-old-world.txt | 1 + .../beforeAdd/remote/hello-outdated-world.txt | 1 + 11 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 test/bin/fixtures/beforeAdd.js create mode 100644 test/integration/beforeAdd.spec.js create mode 100644 test/integration/fixtures/beforeAdd/expected/hello-old-world.txt create mode 100644 test/integration/fixtures/beforeAdd/expected/hello-world.txt create mode 100644 test/integration/fixtures/beforeAdd/local/hello-world.txt create mode 100644 test/integration/fixtures/beforeAdd/remote/hello-old-world.txt create mode 100644 test/integration/fixtures/beforeAdd/remote/hello-outdated-world.txt diff --git a/bin/gh-pages.js b/bin/gh-pages.js index f2057c7b..cb21967e 100755 --- a/bin/gh-pages.js +++ b/bin/gh-pages.js @@ -70,6 +70,10 @@ function main(args) { '-f, --no-history', 'Push force new commit without parent history' ) + .option( + '--before-add ', + 'Execute the function exported by before "git add"' + ) .parse(args); let user; @@ -83,6 +87,23 @@ function main(args) { } user = {name: parts.name, email: parts.address}; } + let beforeAdd; + if (program.beforeAdd) { + const m = require(require.resolve(program.beforeAdd, { + paths: [process.cwd()] + })); + + if (typeof m === 'function') { + beforeAdd = m; + } else if (typeof m === 'object' && typeof m.default === 'function') { + beforeAdd = m.default; + } else { + throw new Error( + `Could not find function to execute before adding files in ` + + `"${program.beforeAdd}".\n ` + ); + } + } const config = { repo: program.repo, @@ -100,7 +121,8 @@ function main(args) { remote: program.remote, push: !!program.push, history: !!program.history, - user: user + user: user, + beforeAdd: beforeAdd }; return publish(config); diff --git a/lib/index.js b/lib/index.js index 87d5c1d8..07b82d8c 100644 --- a/lib/index.js +++ b/lib/index.js @@ -176,6 +176,11 @@ exports.publish = function publish(basePath, config, callback) { } ); }) + .then(git => { + return Promise.resolve( + options.beforeAdd && options.beforeAdd(git) + ).then(() => git); + }) .then(git => { log('Adding all'); return git.add('.'); diff --git a/readme.md b/readme.md index 1b66863f..4d5ec226 100644 --- a/readme.md +++ b/readme.md @@ -289,6 +289,35 @@ ghpages.publish('dist', { ``` +#### options.beforeAdd + * type: `function` + * default: `null` + +Custom callback that is executed right before `git add`. + +The CLI expects a file exporting the beforeAdd function + +```bash +gh-pages --before-add ./cleanup.js +``` + +Example use of the `beforeAdd` option: + +```js +/** + * beforeAdd makes most sense when `add` option is active + * Assuming we want to keep everything on the gh-pages branch + * but remove just `some-outdated-file.txt` + */ +ghpages.publish('dist', { + add: true, + async beforeAdd(git) { + return git.rm('./some-outdated-file.txt'); + } +}, callback); +``` + + #### options.git * type: `string` * default: `'git'` diff --git a/test/bin/fixtures/beforeAdd.js b/test/bin/fixtures/beforeAdd.js new file mode 100644 index 00000000..9b461165 --- /dev/null +++ b/test/bin/fixtures/beforeAdd.js @@ -0,0 +1,3 @@ +module.exports = function myBeforeAdd() { + /* noop */ +}; diff --git a/test/bin/gh-pages.spec.js b/test/bin/gh-pages.spec.js index fea42be1..51160d44 100644 --- a/test/bin/gh-pages.spec.js +++ b/test/bin/gh-pages.spec.js @@ -2,6 +2,7 @@ const ghpages = require('../../lib/index'); const sinon = require('sinon'); const cli = require('../../bin/gh-pages'); const assert = require('../helper').assert; +const beforeAdd = require('./fixtures/beforeAdd'); describe('gh-pages', () => { describe('main', () => { @@ -71,6 +72,16 @@ describe('gh-pages', () => { dist: 'lib', config: {user: {name: 'Full Name', email: 'email@example.com'}} }, + { + args: [ + '--dist', + 'lib', + '--before-add', + require.resolve('./fixtures/beforeAdd') + ], + dist: 'lib', + config: {beforeAdd} + }, { args: ['--dist', 'lib', '-u', 'junk email'], dist: 'lib', diff --git a/test/integration/beforeAdd.spec.js b/test/integration/beforeAdd.spec.js new file mode 100644 index 00000000..64ba5e5e --- /dev/null +++ b/test/integration/beforeAdd.spec.js @@ -0,0 +1,43 @@ +const helper = require('../helper'); +const ghPages = require('../../lib/'); +const path = require('path'); + +const fixtures = path.join(__dirname, 'fixtures'); +const fixtureName = 'beforeAdd'; + +beforeEach(() => { + ghPages.clean(); +}); + +describe('the beforeAdd option', () => { + it('runs a provided async function before adding files', done => { + const local = path.join(fixtures, fixtureName, 'local'); + const expected = path.join(fixtures, fixtureName, 'expected'); + const branch = 'gh-pages'; + + helper.setupRemote(fixtureName, {branch}).then(url => { + const options = { + repo: url, + add: true, + beforeAdd(git) { + return Promise.resolve().then(() => { + return git.rm('hello-outdated-world.txt'); + }); + }, + user: { + name: 'User Name', + email: 'user@email.com' + } + }; + ghPages.publish(local, options, err => { + if (err) { + return done(err); + } + helper + .assertContentsMatch(expected, url, branch) + .then(() => done()) + .catch(done); + }); + }); + }); +}); diff --git a/test/integration/fixtures/beforeAdd/expected/hello-old-world.txt b/test/integration/fixtures/beforeAdd/expected/hello-old-world.txt new file mode 100644 index 00000000..b4a4d34f --- /dev/null +++ b/test/integration/fixtures/beforeAdd/expected/hello-old-world.txt @@ -0,0 +1 @@ +Hello Old World! \ No newline at end of file diff --git a/test/integration/fixtures/beforeAdd/expected/hello-world.txt b/test/integration/fixtures/beforeAdd/expected/hello-world.txt new file mode 100644 index 00000000..c57eff55 --- /dev/null +++ b/test/integration/fixtures/beforeAdd/expected/hello-world.txt @@ -0,0 +1 @@ +Hello World! \ No newline at end of file diff --git a/test/integration/fixtures/beforeAdd/local/hello-world.txt b/test/integration/fixtures/beforeAdd/local/hello-world.txt new file mode 100644 index 00000000..c57eff55 --- /dev/null +++ b/test/integration/fixtures/beforeAdd/local/hello-world.txt @@ -0,0 +1 @@ +Hello World! \ No newline at end of file diff --git a/test/integration/fixtures/beforeAdd/remote/hello-old-world.txt b/test/integration/fixtures/beforeAdd/remote/hello-old-world.txt new file mode 100644 index 00000000..b4a4d34f --- /dev/null +++ b/test/integration/fixtures/beforeAdd/remote/hello-old-world.txt @@ -0,0 +1 @@ +Hello Old World! \ No newline at end of file diff --git a/test/integration/fixtures/beforeAdd/remote/hello-outdated-world.txt b/test/integration/fixtures/beforeAdd/remote/hello-outdated-world.txt new file mode 100644 index 00000000..ce6cd608 --- /dev/null +++ b/test/integration/fixtures/beforeAdd/remote/hello-outdated-world.txt @@ -0,0 +1 @@ +Hello Outdated World! \ No newline at end of file