diff --git a/README.md b/README.md index 868aacd..665ca62 100644 --- a/README.md +++ b/README.md @@ -59,9 +59,27 @@ the `--help` output: --git-dir set the path to the repository --git-path set the path to the git binary -q, --quiet suppress warning message if branch differs + -r, --regex match as a regular expression -v, --verbose print a message if the branch matches -V, --version output the version number +## Additional Command Examples + +### Regular Expression Matching + +To check that the current branch starts with `release/` using a regular +expression: + +``` +$ git-branch-is -r "^release/" +Error: Current branch "master" does not match "^release/". +$ echo $? +1 +``` + +Note: Be careful to quote patterns to avoid shell expansion or special +handling (e.g. POSIX shells expand `*` and `cmd.exe` treats `^` specially). + ## API Usage To use the API with a callback function: diff --git a/bin/git-branch-is.js b/bin/git-branch-is.js index c4e58ee..531ce6f 100755 --- a/bin/git-branch-is.js +++ b/bin/git-branch-is.js @@ -64,6 +64,7 @@ function gitBranchIsCmd(args, callback) { .option('--git-dir ', 'set the path to the repository') .option('--git-path ', 'set the path to the git binary') .option('-q, --quiet', 'suppress warning message if branch differs') + .option('-r, --regex', 'match as a regular expression') .option('-v, --verbose', 'print a message if the branch matches') .version(packageJson.version) .parse(args); @@ -81,13 +82,38 @@ function gitBranchIsCmd(args, callback) { command.gitArgs = command.gitArg; var expectedBranch = command.args[0]; + + var expectedBranchRegExp; + if (command.regex) { + try { + expectedBranchRegExp = new RegExp(expectedBranch); + } catch (errRegExp) { + callback(null, { + code: 2, + stderr: 'Error: Invalid RegExp "' + expectedBranch + '": ' + + errRegExp + '\n' + }); + return undefined; + } + } + gitBranchIs.getBranch(command, function(err, currentBranch) { if (err) { callback(err); return; } - if (currentBranch !== expectedBranch) { + if (expectedBranchRegExp) { + if (!expectedBranchRegExp.test(currentBranch)) { + callback(null, { + code: 1, + stderr: command.quiet ? '' : + 'Error: Current branch "' + currentBranch + '" does not match "' + + expectedBranch + '".\n' + }); + return; + } + } else if (currentBranch !== expectedBranch) { callback(null, { code: 1, stderr: command.quiet ? '' : diff --git a/test/git-branch-is-cmd.js b/test/git-branch-is-cmd.js index a42f440..2e65a40 100644 --- a/test/git-branch-is-cmd.js +++ b/test/git-branch-is-cmd.js @@ -48,6 +48,72 @@ describe('git-branch-is', function() { }); }); + it('exit 0 silently for matching anchored regex branch name', function(done) { + var args = ARGS.concat('-r', '^' + BRANCH_CURRENT + '$'); + gitBranchIsCmd(args, function(err, result) { + assert.ifError(err); + assert.strictEqual(result.code, 0); + assert(!result.stdout); + assert(!result.stderr); + done(); + }); + }); + + it('exit 0 silently for matching substr regex branch name', function(done) { + var args = ARGS.concat('-r', BRANCH_CURRENT.slice(1, -1)); + gitBranchIsCmd(args, function(err, result) { + assert.ifError(err); + assert.strictEqual(result.code, 0); + assert(!result.stdout); + assert(!result.stderr); + done(); + }); + }); + + it('exit 0 silently for matching empty regex branch name', function(done) { + var args = ARGS.concat('-r', ''); + gitBranchIsCmd(args, function(err, result) { + assert.ifError(err); + assert.strictEqual(result.code, 0); + assert(!result.stdout); + assert(!result.stderr); + done(); + }); + }); + + it('exit 1 with warning for non-match regex branch name', function(done) { + gitBranchIsCmd(ARGS.concat('-r', 'invalid'), function(err, result) { + assert.ifError(err); + assert.strictEqual(result.code, 1); + assert(!result.stdout); + assertMatch(result.stderr, /\binvalid\b/); + assertMatch(result.stderr, BRANCH_CURRENT_RE); + done(); + }); + }); + + it('exit 2 with warning for invalid regex', function(done) { + gitBranchIsCmd(ARGS.concat('-r', 'b[ad'), function(err, result) { + assert.ifError(err); + assert.strictEqual(result.code, 2); + assert(!result.stdout); + assertMatch(result.stderr, /\bb\[ad\b/); + done(); + }); + }); + + // --quiet does not suppress notification of caller errors + // If this behavior is desired, consider using repeated -q option. + it('exit 2 with warning for invalid regex with quiet', function(done) { + gitBranchIsCmd(ARGS.concat('-q', '-r', 'b[ad'), function(err, result) { + assert.ifError(err); + assert.strictEqual(result.code, 2); + assert(!result.stdout); + assertMatch(result.stderr, /\bb\[ad\b/); + done(); + }); + }); + it('exit code 1 silently with quiet option', function(done) { var args = ARGS.concat('-q', 'invalid'); gitBranchIsCmd(args, function(err, result) {