diff --git a/__tests__/fs-helper.test.ts b/__tests__/fs-helper.test.ts index f30909c..c178c9a 100644 --- a/__tests__/fs-helper.test.ts +++ b/__tests__/fs-helper.test.ts @@ -212,3 +212,50 @@ describe('readFileContents', () => { expect(fsHelper.readFileContents(tempFile).toString()).toEqual(fileContent) }) }) + +describe('ensureCorrectShaCheckedOut', () => { + let dir: string + let commit1: string + let commit2: string + const tag1 = 'tag1' + const tag2 = 'tag2' + + beforeEach(() => { + dir = fsHelper.createTempDir(tmpFileDir, 'subdir') + + // Set up a git repository with two commits + execSync('git init', { cwd: dir }) + execSync('git commit --allow-empty -m "test"', { cwd: dir }) + execSync('git commit --allow-empty -m "test"', { cwd: dir }) + + // Grab the two commits + commit1 = execSync('git rev-parse HEAD~1', { cwd: dir }).toString().trim() + commit2 = execSync('git rev-parse HEAD', { cwd: dir }).toString().trim() + + // Create a tag for each commit + execSync(`git tag ${tag1} ${commit1}`, { cwd: dir }) + execSync(`git tag ${tag2} ${commit2}`, { cwd: dir }) + }) + + afterEach(() => { + fs.rmSync(dir, { recursive: true }) + }) + + it('does not throw an error if the correct SHA is checked out', async () => { + await expect( + fsHelper.ensureCorrectShaCheckedOut(`refs/tags/${tag2}`, commit2, dir) + ).resolves.toBeUndefined() + }) + + it('throws an error if the correct SHA is not checked out', async () => { + await expect( + fsHelper.ensureCorrectShaCheckedOut(`refs/tags/${tag1}`, commit1, dir) + ).rejects.toThrow() + }) + + it('throws an error if the sha of the tag does not match expected sha', async () => { + await expect(async () => + fsHelper.ensureCorrectShaCheckedOut(`refs/tags/${tag1}`, commit2, dir) + ).rejects.toThrow() + }) +}) diff --git a/__tests__/main.test.ts b/__tests__/main.test.ts index 703a39b..6c700df 100644 --- a/__tests__/main.test.ts +++ b/__tests__/main.test.ts @@ -23,6 +23,7 @@ let setOutputMock: jest.SpyInstance let createTempDirMock: jest.SpyInstance let createArchivesMock: jest.SpyInstance let stageActionFilesMock: jest.SpyInstance +let ensureCorrectShaCheckedOutMock: jest.SpyInstance let publishOCIArtifactMock: jest.SpyInstance // Mock the config resolution @@ -49,6 +50,9 @@ describe('run', () => { stageActionFilesMock = jest .spyOn(fsHelper, 'stageActionFiles') .mockImplementation() + ensureCorrectShaCheckedOutMock = jest + .spyOn(fsHelper, 'ensureCorrectShaCheckedOut') + .mockImplementation() // GHCR Client mocks publishOCIArtifactMock = jest @@ -93,9 +97,24 @@ describe('run', () => { } }) + it('fails if ensuring the correct SHA is checked out errors', async () => { + resolvePublishActionOptionsMock.mockReturnValue(baseOptions()) + + ensureCorrectShaCheckedOutMock.mockImplementation(() => { + throw new Error('Something went wrong') + }) + + // Run the action + await main.run() + + // Check the results + expect(setFailedMock).toHaveBeenCalledWith('Something went wrong') + }) + it('fails if creating staging temp directory fails', async () => { resolvePublishActionOptionsMock.mockReturnValue(baseOptions()) + ensureCorrectShaCheckedOutMock.mockImplementation(() => {}) createTempDirMock.mockImplementation(() => { throw new Error('Something went wrong') }) @@ -110,6 +129,8 @@ describe('run', () => { it('fails if staging files fails', async () => { resolvePublishActionOptionsMock.mockReturnValue(baseOptions()) + ensureCorrectShaCheckedOutMock.mockImplementation(() => {}) + createTempDirMock.mockImplementation(() => { return 'tmpDir/staging' }) @@ -128,6 +149,8 @@ describe('run', () => { it('fails if creating archives temp directory fails', async () => { resolvePublishActionOptionsMock.mockReturnValue(baseOptions()) + ensureCorrectShaCheckedOutMock.mockImplementation(() => {}) + createTempDirMock.mockImplementation((_, path: string) => { if (path === 'staging') { return 'staging' @@ -147,6 +170,8 @@ describe('run', () => { it('fails if creating archives fails', async () => { resolvePublishActionOptionsMock.mockReturnValue(baseOptions()) + ensureCorrectShaCheckedOutMock.mockImplementation(() => {}) + createTempDirMock.mockImplementation(() => { return 'stagingOrArchivesDir' }) @@ -167,6 +192,8 @@ describe('run', () => { it('fails if publishing OCI artifact fails', async () => { resolvePublishActionOptionsMock.mockReturnValue(baseOptions()) + ensureCorrectShaCheckedOutMock.mockImplementation(() => {}) + createTempDirMock.mockImplementation(() => { return 'stagingOrArchivesDir' }) @@ -202,6 +229,8 @@ describe('run', () => { it('fails if creating attestation fails', async () => { resolvePublishActionOptionsMock.mockReturnValue(baseOptions()) + ensureCorrectShaCheckedOutMock.mockImplementation(() => {}) + createTempDirMock.mockImplementation(() => { return 'stagingOrArchivesDir' }) @@ -246,6 +275,8 @@ describe('run', () => { options.isEnterprise = true resolvePublishActionOptionsMock.mockReturnValue(options) + ensureCorrectShaCheckedOutMock.mockImplementation(() => {}) + createTempDirMock.mockImplementation(() => { return 'stagingOrArchivesDir' }) @@ -302,6 +333,8 @@ describe('run', () => { it('uploads the artifact, returns package metadata from GHCR, and creates an attestation in non-enterprise for public repo', async () => { resolvePublishActionOptionsMock.mockReturnValue(baseOptions()) + ensureCorrectShaCheckedOutMock.mockImplementation(() => {}) + createTempDirMock.mockImplementation(() => { return 'stagingOrArchivesDir' }) @@ -383,6 +416,8 @@ describe('run', () => { resolvePublishActionOptionsMock.mockReturnValue(opts) + ensureCorrectShaCheckedOutMock.mockImplementation(() => {}) + createTempDirMock.mockImplementation(() => { return 'stagingOrArchivesDir' }) diff --git a/badges/coverage.svg b/badges/coverage.svg index 6746ba8..edc5ecc 100644 --- a/badges/coverage.svg +++ b/badges/coverage.svg @@ -1 +1 @@ -Coverage: 96.63%Coverage96.63% \ No newline at end of file +Coverage: 96.78%Coverage96.78% \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index b0cba62..6cbf3a0 100644 --- a/dist/index.js +++ b/dist/index.js @@ -3945,6 +3945,148 @@ function parseParams (str) { module.exports = parseParams +/***/ }), + +/***/ 54751: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +Object.defineProperty(exports, "__esModule", ({ value: true })); +__export(__nccwpck_require__(42825)); +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 42825: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + +"use strict"; + +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +const fs_1 = __nccwpck_require__(57147); +const debug_1 = __importDefault(__nccwpck_require__(38237)); +const log = debug_1.default('@kwsites/file-exists'); +function check(path, isFile, isDirectory) { + log(`checking %s`, path); + try { + const stat = fs_1.statSync(path); + if (stat.isFile() && isFile) { + log(`[OK] path represents a file`); + return true; + } + if (stat.isDirectory() && isDirectory) { + log(`[OK] path represents a directory`); + return true; + } + log(`[FAIL] path represents something other than a file or directory`); + return false; + } + catch (e) { + if (e.code === 'ENOENT') { + log(`[FAIL] path is not accessible: %o`, e); + return false; + } + log(`[FATAL] %o`, e); + throw e; + } +} +/** + * Synchronous validation of a path existing either as a file or as a directory. + * + * @param {string} path The path to check + * @param {number} type One or both of the exported numeric constants + */ +function exists(path, type = exports.READABLE) { + return check(path, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0); +} +exports.exists = exists; +/** + * Constant representing a file + */ +exports.FILE = 1; +/** + * Constant representing a folder + */ +exports.FOLDER = 2; +/** + * Constant representing either a file or a folder + */ +exports.READABLE = exports.FILE + exports.FOLDER; +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 49819: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.createDeferred = exports.deferred = void 0; +/** + * Creates a new `DeferredPromise` + * + * ```typescript + import {deferred} from '@kwsites/promise-deferred`; + ``` + */ +function deferred() { + let done; + let fail; + let status = 'pending'; + const promise = new Promise((_done, _fail) => { + done = _done; + fail = _fail; + }); + return { + promise, + done(result) { + if (status === 'pending') { + status = 'resolved'; + done(result); + } + }, + fail(error) { + if (status === 'pending') { + status = 'rejected'; + fail(error); + } + }, + get fulfilled() { + return status !== 'pending'; + }, + get status() { + return status; + }, + }; +} +exports.deferred = deferred; +/** + * Alias of the exported `deferred` function, to help consumers wanting to use `deferred` as the + * local variable name rather than the factory import name, without needing to rename on import. + * + * ```typescript + import {createDeferred} from '@kwsites/promise-deferred`; + ``` + */ +exports.createDeferred = deferred; +/** + * Default export allows use as: + * + * ```typescript + import deferred from '@kwsites/promise-deferred`; + ``` + */ +exports["default"] = deferred; +//# sourceMappingURL=index.js.map + /***/ }), /***/ 28520: @@ -65560,6 +65702,4921 @@ const validRange = (range, options) => { module.exports = validRange +/***/ }), + +/***/ 79103: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +"use strict"; + +var __create = Object.create; +var __defProp = Object.defineProperty; +var __defProps = Object.defineProperties; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropDescs = Object.getOwnPropertyDescriptors; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getOwnPropSymbols = Object.getOwnPropertySymbols; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __propIsEnum = Object.prototype.propertyIsEnumerable; +var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp.call(b, prop)) + __defNormalProp(a, prop, b[prop]); + if (__getOwnPropSymbols) + for (var prop of __getOwnPropSymbols(b)) { + if (__propIsEnum.call(b, prop)) + __defNormalProp(a, prop, b[prop]); + } + return a; +}; +var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); +var __esm = (fn, res) => function __init() { + return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; +}; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var __async = (__this, __arguments, generator) => { + return new Promise((resolve, reject) => { + var fulfilled = (value) => { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + }; + var rejected = (value) => { + try { + step(generator.throw(value)); + } catch (e) { + reject(e); + } + }; + var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); + step((generator = generator.apply(__this, __arguments)).next()); + }); +}; + +// src/lib/errors/git-error.ts +var GitError; +var init_git_error = __esm({ + "src/lib/errors/git-error.ts"() { + "use strict"; + GitError = class extends Error { + constructor(task, message) { + super(message); + this.task = task; + Object.setPrototypeOf(this, new.target.prototype); + } + }; + } +}); + +// src/lib/errors/git-response-error.ts +var GitResponseError; +var init_git_response_error = __esm({ + "src/lib/errors/git-response-error.ts"() { + "use strict"; + init_git_error(); + GitResponseError = class extends GitError { + constructor(git, message) { + super(void 0, message || String(git)); + this.git = git; + } + }; + } +}); + +// src/lib/args/pathspec.ts +function pathspec(...paths) { + const key = new String(paths); + cache.set(key, paths); + return key; +} +function isPathSpec(path) { + return path instanceof String && cache.has(path); +} +function toPaths(pathSpec) { + return cache.get(pathSpec) || []; +} +var cache; +var init_pathspec = __esm({ + "src/lib/args/pathspec.ts"() { + "use strict"; + cache = /* @__PURE__ */ new WeakMap(); + } +}); + +// src/lib/errors/git-construct-error.ts +var GitConstructError; +var init_git_construct_error = __esm({ + "src/lib/errors/git-construct-error.ts"() { + "use strict"; + init_git_error(); + GitConstructError = class extends GitError { + constructor(config, message) { + super(void 0, message); + this.config = config; + } + }; + } +}); + +// src/lib/errors/git-plugin-error.ts +var GitPluginError; +var init_git_plugin_error = __esm({ + "src/lib/errors/git-plugin-error.ts"() { + "use strict"; + init_git_error(); + GitPluginError = class extends GitError { + constructor(task, plugin, message) { + super(task, message); + this.task = task; + this.plugin = plugin; + Object.setPrototypeOf(this, new.target.prototype); + } + }; + } +}); + +// src/lib/errors/task-configuration-error.ts +var TaskConfigurationError; +var init_task_configuration_error = __esm({ + "src/lib/errors/task-configuration-error.ts"() { + "use strict"; + init_git_error(); + TaskConfigurationError = class extends GitError { + constructor(message) { + super(void 0, message); + } + }; + } +}); + +// src/lib/utils/util.ts +function asFunction(source) { + return typeof source === "function" ? source : NOOP; +} +function isUserFunction(source) { + return typeof source === "function" && source !== NOOP; +} +function splitOn(input, char) { + const index = input.indexOf(char); + if (index <= 0) { + return [input, ""]; + } + return [input.substr(0, index), input.substr(index + 1)]; +} +function first(input, offset = 0) { + return isArrayLike(input) && input.length > offset ? input[offset] : void 0; +} +function last(input, offset = 0) { + if (isArrayLike(input) && input.length > offset) { + return input[input.length - 1 - offset]; + } +} +function isArrayLike(input) { + return !!(input && typeof input.length === "number"); +} +function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") { + return input.split(separator).reduce((output, line) => { + const lineContent = trimmed2 ? line.trim() : line; + if (lineContent) { + output.push(lineContent); + } + return output; + }, []); +} +function forEachLineWithContent(input, callback) { + return toLinesWithContent(input, true).map((line) => callback(line)); +} +function folderExists(path) { + return (0, import_file_exists.exists)(path, import_file_exists.FOLDER); +} +function append(target, item) { + if (Array.isArray(target)) { + if (!target.includes(item)) { + target.push(item); + } + } else { + target.add(item); + } + return item; +} +function including(target, item) { + if (Array.isArray(target) && !target.includes(item)) { + target.push(item); + } + return target; +} +function remove(target, item) { + if (Array.isArray(target)) { + const index = target.indexOf(item); + if (index >= 0) { + target.splice(index, 1); + } + } else { + target.delete(item); + } + return item; +} +function asArray(source) { + return Array.isArray(source) ? source : [source]; +} +function asStringArray(source) { + return asArray(source).map(String); +} +function asNumber(source, onNaN = 0) { + if (source == null) { + return onNaN; + } + const num = parseInt(source, 10); + return isNaN(num) ? onNaN : num; +} +function prefixedArray(input, prefix) { + const output = []; + for (let i = 0, max = input.length; i < max; i++) { + output.push(prefix, input[i]); + } + return output; +} +function bufferToString(input) { + return (Array.isArray(input) ? Buffer.concat(input) : input).toString("utf-8"); +} +function pick(source, properties) { + return Object.assign( + {}, + ...properties.map((property) => property in source ? { [property]: source[property] } : {}) + ); +} +function delay(duration = 0) { + return new Promise((done) => setTimeout(done, duration)); +} +function orVoid(input) { + if (input === false) { + return void 0; + } + return input; +} +var import_file_exists, NULL, NOOP, objectToString; +var init_util = __esm({ + "src/lib/utils/util.ts"() { + "use strict"; + import_file_exists = __nccwpck_require__(54751); + NULL = "\0"; + NOOP = () => { + }; + objectToString = Object.prototype.toString.call.bind(Object.prototype.toString); + } +}); + +// src/lib/utils/argument-filters.ts +function filterType(input, filter, def) { + if (filter(input)) { + return input; + } + return arguments.length > 2 ? def : void 0; +} +function filterPrimitives(input, omit) { + const type = isPathSpec(input) ? "string" : typeof input; + return /number|string|boolean/.test(type) && (!omit || !omit.includes(type)); +} +function filterPlainObject(input) { + return !!input && objectToString(input) === "[object Object]"; +} +function filterFunction(input) { + return typeof input === "function"; +} +var filterArray, filterString, filterStringArray, filterStringOrStringArray, filterHasLength; +var init_argument_filters = __esm({ + "src/lib/utils/argument-filters.ts"() { + "use strict"; + init_util(); + init_pathspec(); + filterArray = (input) => { + return Array.isArray(input); + }; + filterString = (input) => { + return typeof input === "string"; + }; + filterStringArray = (input) => { + return Array.isArray(input) && input.every(filterString); + }; + filterStringOrStringArray = (input) => { + return filterString(input) || Array.isArray(input) && input.every(filterString); + }; + filterHasLength = (input) => { + if (input == null || "number|boolean|function".includes(typeof input)) { + return false; + } + return Array.isArray(input) || typeof input === "string" || typeof input.length === "number"; + }; + } +}); + +// src/lib/utils/exit-codes.ts +var ExitCodes; +var init_exit_codes = __esm({ + "src/lib/utils/exit-codes.ts"() { + "use strict"; + ExitCodes = /* @__PURE__ */ ((ExitCodes2) => { + ExitCodes2[ExitCodes2["SUCCESS"] = 0] = "SUCCESS"; + ExitCodes2[ExitCodes2["ERROR"] = 1] = "ERROR"; + ExitCodes2[ExitCodes2["NOT_FOUND"] = -2] = "NOT_FOUND"; + ExitCodes2[ExitCodes2["UNCLEAN"] = 128] = "UNCLEAN"; + return ExitCodes2; + })(ExitCodes || {}); + } +}); + +// src/lib/utils/git-output-streams.ts +var GitOutputStreams; +var init_git_output_streams = __esm({ + "src/lib/utils/git-output-streams.ts"() { + "use strict"; + GitOutputStreams = class { + constructor(stdOut, stdErr) { + this.stdOut = stdOut; + this.stdErr = stdErr; + } + asStrings() { + return new GitOutputStreams(this.stdOut.toString("utf8"), this.stdErr.toString("utf8")); + } + }; + } +}); + +// src/lib/utils/line-parser.ts +var LineParser, RemoteLineParser; +var init_line_parser = __esm({ + "src/lib/utils/line-parser.ts"() { + "use strict"; + LineParser = class { + constructor(regExp, useMatches) { + this.matches = []; + this.parse = (line, target) => { + this.resetMatches(); + if (!this._regExp.every((reg, index) => this.addMatch(reg, index, line(index)))) { + return false; + } + return this.useMatches(target, this.prepareMatches()) !== false; + }; + this._regExp = Array.isArray(regExp) ? regExp : [regExp]; + if (useMatches) { + this.useMatches = useMatches; + } + } + useMatches(target, match) { + throw new Error(`LineParser:useMatches not implemented`); + } + resetMatches() { + this.matches.length = 0; + } + prepareMatches() { + return this.matches; + } + addMatch(reg, index, line) { + const matched = line && reg.exec(line); + if (matched) { + this.pushMatch(index, matched); + } + return !!matched; + } + pushMatch(_index, matched) { + this.matches.push(...matched.slice(1)); + } + }; + RemoteLineParser = class extends LineParser { + addMatch(reg, index, line) { + return /^remote:\s/.test(String(line)) && super.addMatch(reg, index, line); + } + pushMatch(index, matched) { + if (index > 0 || matched.length > 1) { + super.pushMatch(index, matched); + } + } + }; + } +}); + +// src/lib/utils/simple-git-options.ts +function createInstanceConfig(...options) { + const baseDir = process.cwd(); + const config = Object.assign( + __spreadValues({ baseDir }, defaultOptions), + ...options.filter((o) => typeof o === "object" && o) + ); + config.baseDir = config.baseDir || baseDir; + config.trimmed = config.trimmed === true; + return config; +} +var defaultOptions; +var init_simple_git_options = __esm({ + "src/lib/utils/simple-git-options.ts"() { + "use strict"; + defaultOptions = { + binary: "git", + maxConcurrentProcesses: 5, + config: [], + trimmed: false + }; + } +}); + +// src/lib/utils/task-options.ts +function appendTaskOptions(options, commands = []) { + if (!filterPlainObject(options)) { + return commands; + } + return Object.keys(options).reduce((commands2, key) => { + const value = options[key]; + if (isPathSpec(value)) { + commands2.push(value); + } else if (filterPrimitives(value, ["boolean"])) { + commands2.push(key + "=" + value); + } else { + commands2.push(key); + } + return commands2; + }, commands); +} +function getTrailingOptions(args, initialPrimitive = 0, objectOnly = false) { + const command = []; + for (let i = 0, max = initialPrimitive < 0 ? args.length : initialPrimitive; i < max; i++) { + if ("string|number".includes(typeof args[i])) { + command.push(String(args[i])); + } + } + appendTaskOptions(trailingOptionsArgument(args), command); + if (!objectOnly) { + command.push(...trailingArrayArgument(args)); + } + return command; +} +function trailingArrayArgument(args) { + const hasTrailingCallback = typeof last(args) === "function"; + return filterType(last(args, hasTrailingCallback ? 1 : 0), filterArray, []); +} +function trailingOptionsArgument(args) { + const hasTrailingCallback = filterFunction(last(args)); + return filterType(last(args, hasTrailingCallback ? 1 : 0), filterPlainObject); +} +function trailingFunctionArgument(args, includeNoop = true) { + const callback = asFunction(last(args)); + return includeNoop || isUserFunction(callback) ? callback : void 0; +} +var init_task_options = __esm({ + "src/lib/utils/task-options.ts"() { + "use strict"; + init_argument_filters(); + init_util(); + init_pathspec(); + } +}); + +// src/lib/utils/task-parser.ts +function callTaskParser(parser3, streams) { + return parser3(streams.stdOut, streams.stdErr); +} +function parseStringResponse(result, parsers12, texts, trim = true) { + asArray(texts).forEach((text) => { + for (let lines = toLinesWithContent(text, trim), i = 0, max = lines.length; i < max; i++) { + const line = (offset = 0) => { + if (i + offset >= max) { + return; + } + return lines[i + offset]; + }; + parsers12.some(({ parse }) => parse(line, result)); + } + }); + return result; +} +var init_task_parser = __esm({ + "src/lib/utils/task-parser.ts"() { + "use strict"; + init_util(); + } +}); + +// src/lib/utils/index.ts +var utils_exports = {}; +__export(utils_exports, { + ExitCodes: () => ExitCodes, + GitOutputStreams: () => GitOutputStreams, + LineParser: () => LineParser, + NOOP: () => NOOP, + NULL: () => NULL, + RemoteLineParser: () => RemoteLineParser, + append: () => append, + appendTaskOptions: () => appendTaskOptions, + asArray: () => asArray, + asFunction: () => asFunction, + asNumber: () => asNumber, + asStringArray: () => asStringArray, + bufferToString: () => bufferToString, + callTaskParser: () => callTaskParser, + createInstanceConfig: () => createInstanceConfig, + delay: () => delay, + filterArray: () => filterArray, + filterFunction: () => filterFunction, + filterHasLength: () => filterHasLength, + filterPlainObject: () => filterPlainObject, + filterPrimitives: () => filterPrimitives, + filterString: () => filterString, + filterStringArray: () => filterStringArray, + filterStringOrStringArray: () => filterStringOrStringArray, + filterType: () => filterType, + first: () => first, + folderExists: () => folderExists, + forEachLineWithContent: () => forEachLineWithContent, + getTrailingOptions: () => getTrailingOptions, + including: () => including, + isUserFunction: () => isUserFunction, + last: () => last, + objectToString: () => objectToString, + orVoid: () => orVoid, + parseStringResponse: () => parseStringResponse, + pick: () => pick, + prefixedArray: () => prefixedArray, + remove: () => remove, + splitOn: () => splitOn, + toLinesWithContent: () => toLinesWithContent, + trailingFunctionArgument: () => trailingFunctionArgument, + trailingOptionsArgument: () => trailingOptionsArgument +}); +var init_utils = __esm({ + "src/lib/utils/index.ts"() { + "use strict"; + init_argument_filters(); + init_exit_codes(); + init_git_output_streams(); + init_line_parser(); + init_simple_git_options(); + init_task_options(); + init_task_parser(); + init_util(); + } +}); + +// src/lib/tasks/check-is-repo.ts +var check_is_repo_exports = {}; +__export(check_is_repo_exports, { + CheckRepoActions: () => CheckRepoActions, + checkIsBareRepoTask: () => checkIsBareRepoTask, + checkIsRepoRootTask: () => checkIsRepoRootTask, + checkIsRepoTask: () => checkIsRepoTask +}); +function checkIsRepoTask(action) { + switch (action) { + case "bare" /* BARE */: + return checkIsBareRepoTask(); + case "root" /* IS_REPO_ROOT */: + return checkIsRepoRootTask(); + } + const commands = ["rev-parse", "--is-inside-work-tree"]; + return { + commands, + format: "utf-8", + onError, + parser + }; +} +function checkIsRepoRootTask() { + const commands = ["rev-parse", "--git-dir"]; + return { + commands, + format: "utf-8", + onError, + parser(path) { + return /^\.(git)?$/.test(path.trim()); + } + }; +} +function checkIsBareRepoTask() { + const commands = ["rev-parse", "--is-bare-repository"]; + return { + commands, + format: "utf-8", + onError, + parser + }; +} +function isNotRepoMessage(error) { + return /(Not a git repository|Kein Git-Repository)/i.test(String(error)); +} +var CheckRepoActions, onError, parser; +var init_check_is_repo = __esm({ + "src/lib/tasks/check-is-repo.ts"() { + "use strict"; + init_utils(); + CheckRepoActions = /* @__PURE__ */ ((CheckRepoActions2) => { + CheckRepoActions2["BARE"] = "bare"; + CheckRepoActions2["IN_TREE"] = "tree"; + CheckRepoActions2["IS_REPO_ROOT"] = "root"; + return CheckRepoActions2; + })(CheckRepoActions || {}); + onError = ({ exitCode }, error, done, fail) => { + if (exitCode === 128 /* UNCLEAN */ && isNotRepoMessage(error)) { + return done(Buffer.from("false")); + } + fail(error); + }; + parser = (text) => { + return text.trim() === "true"; + }; + } +}); + +// src/lib/responses/CleanSummary.ts +function cleanSummaryParser(dryRun, text) { + const summary = new CleanResponse(dryRun); + const regexp = dryRun ? dryRunRemovalRegexp : removalRegexp; + toLinesWithContent(text).forEach((line) => { + const removed = line.replace(regexp, ""); + summary.paths.push(removed); + (isFolderRegexp.test(removed) ? summary.folders : summary.files).push(removed); + }); + return summary; +} +var CleanResponse, removalRegexp, dryRunRemovalRegexp, isFolderRegexp; +var init_CleanSummary = __esm({ + "src/lib/responses/CleanSummary.ts"() { + "use strict"; + init_utils(); + CleanResponse = class { + constructor(dryRun) { + this.dryRun = dryRun; + this.paths = []; + this.files = []; + this.folders = []; + } + }; + removalRegexp = /^[a-z]+\s*/i; + dryRunRemovalRegexp = /^[a-z]+\s+[a-z]+\s*/i; + isFolderRegexp = /\/$/; + } +}); + +// src/lib/tasks/task.ts +var task_exports = {}; +__export(task_exports, { + EMPTY_COMMANDS: () => EMPTY_COMMANDS, + adhocExecTask: () => adhocExecTask, + configurationErrorTask: () => configurationErrorTask, + isBufferTask: () => isBufferTask, + isEmptyTask: () => isEmptyTask, + straightThroughBufferTask: () => straightThroughBufferTask, + straightThroughStringTask: () => straightThroughStringTask +}); +function adhocExecTask(parser3) { + return { + commands: EMPTY_COMMANDS, + format: "empty", + parser: parser3 + }; +} +function configurationErrorTask(error) { + return { + commands: EMPTY_COMMANDS, + format: "empty", + parser() { + throw typeof error === "string" ? new TaskConfigurationError(error) : error; + } + }; +} +function straightThroughStringTask(commands, trimmed2 = false) { + return { + commands, + format: "utf-8", + parser(text) { + return trimmed2 ? String(text).trim() : text; + } + }; +} +function straightThroughBufferTask(commands) { + return { + commands, + format: "buffer", + parser(buffer) { + return buffer; + } + }; +} +function isBufferTask(task) { + return task.format === "buffer"; +} +function isEmptyTask(task) { + return task.format === "empty" || !task.commands.length; +} +var EMPTY_COMMANDS; +var init_task = __esm({ + "src/lib/tasks/task.ts"() { + "use strict"; + init_task_configuration_error(); + EMPTY_COMMANDS = []; + } +}); + +// src/lib/tasks/clean.ts +var clean_exports = {}; +__export(clean_exports, { + CONFIG_ERROR_INTERACTIVE_MODE: () => CONFIG_ERROR_INTERACTIVE_MODE, + CONFIG_ERROR_MODE_REQUIRED: () => CONFIG_ERROR_MODE_REQUIRED, + CONFIG_ERROR_UNKNOWN_OPTION: () => CONFIG_ERROR_UNKNOWN_OPTION, + CleanOptions: () => CleanOptions, + cleanTask: () => cleanTask, + cleanWithOptionsTask: () => cleanWithOptionsTask, + isCleanOptionsArray: () => isCleanOptionsArray +}); +function cleanWithOptionsTask(mode, customArgs) { + const { cleanMode, options, valid } = getCleanOptions(mode); + if (!cleanMode) { + return configurationErrorTask(CONFIG_ERROR_MODE_REQUIRED); + } + if (!valid.options) { + return configurationErrorTask(CONFIG_ERROR_UNKNOWN_OPTION + JSON.stringify(mode)); + } + options.push(...customArgs); + if (options.some(isInteractiveMode)) { + return configurationErrorTask(CONFIG_ERROR_INTERACTIVE_MODE); + } + return cleanTask(cleanMode, options); +} +function cleanTask(mode, customArgs) { + const commands = ["clean", `-${mode}`, ...customArgs]; + return { + commands, + format: "utf-8", + parser(text) { + return cleanSummaryParser(mode === "n" /* DRY_RUN */, text); + } + }; +} +function isCleanOptionsArray(input) { + return Array.isArray(input) && input.every((test) => CleanOptionValues.has(test)); +} +function getCleanOptions(input) { + let cleanMode; + let options = []; + let valid = { cleanMode: false, options: true }; + input.replace(/[^a-z]i/g, "").split("").forEach((char) => { + if (isCleanMode(char)) { + cleanMode = char; + valid.cleanMode = true; + } else { + valid.options = valid.options && isKnownOption(options[options.length] = `-${char}`); + } + }); + return { + cleanMode, + options, + valid + }; +} +function isCleanMode(cleanMode) { + return cleanMode === "f" /* FORCE */ || cleanMode === "n" /* DRY_RUN */; +} +function isKnownOption(option) { + return /^-[a-z]$/i.test(option) && CleanOptionValues.has(option.charAt(1)); +} +function isInteractiveMode(option) { + if (/^-[^\-]/.test(option)) { + return option.indexOf("i") > 0; + } + return option === "--interactive"; +} +var CONFIG_ERROR_INTERACTIVE_MODE, CONFIG_ERROR_MODE_REQUIRED, CONFIG_ERROR_UNKNOWN_OPTION, CleanOptions, CleanOptionValues; +var init_clean = __esm({ + "src/lib/tasks/clean.ts"() { + "use strict"; + init_CleanSummary(); + init_utils(); + init_task(); + CONFIG_ERROR_INTERACTIVE_MODE = "Git clean interactive mode is not supported"; + CONFIG_ERROR_MODE_REQUIRED = 'Git clean mode parameter ("n" or "f") is required'; + CONFIG_ERROR_UNKNOWN_OPTION = "Git clean unknown option found in: "; + CleanOptions = /* @__PURE__ */ ((CleanOptions2) => { + CleanOptions2["DRY_RUN"] = "n"; + CleanOptions2["FORCE"] = "f"; + CleanOptions2["IGNORED_INCLUDED"] = "x"; + CleanOptions2["IGNORED_ONLY"] = "X"; + CleanOptions2["EXCLUDING"] = "e"; + CleanOptions2["QUIET"] = "q"; + CleanOptions2["RECURSIVE"] = "d"; + return CleanOptions2; + })(CleanOptions || {}); + CleanOptionValues = /* @__PURE__ */ new Set([ + "i", + ...asStringArray(Object.values(CleanOptions)) + ]); + } +}); + +// src/lib/responses/ConfigList.ts +function configListParser(text) { + const config = new ConfigList(); + for (const item of configParser(text)) { + config.addValue(item.file, String(item.key), item.value); + } + return config; +} +function configGetParser(text, key) { + let value = null; + const values = []; + const scopes = /* @__PURE__ */ new Map(); + for (const item of configParser(text, key)) { + if (item.key !== key) { + continue; + } + values.push(value = item.value); + if (!scopes.has(item.file)) { + scopes.set(item.file, []); + } + scopes.get(item.file).push(value); + } + return { + key, + paths: Array.from(scopes.keys()), + scopes, + value, + values + }; +} +function configFilePath(filePath) { + return filePath.replace(/^(file):/, ""); +} +function* configParser(text, requestedKey = null) { + const lines = text.split("\0"); + for (let i = 0, max = lines.length - 1; i < max; ) { + const file = configFilePath(lines[i++]); + let value = lines[i++]; + let key = requestedKey; + if (value.includes("\n")) { + const line = splitOn(value, "\n"); + key = line[0]; + value = line[1]; + } + yield { file, key, value }; + } +} +var ConfigList; +var init_ConfigList = __esm({ + "src/lib/responses/ConfigList.ts"() { + "use strict"; + init_utils(); + ConfigList = class { + constructor() { + this.files = []; + this.values = /* @__PURE__ */ Object.create(null); + } + get all() { + if (!this._all) { + this._all = this.files.reduce((all, file) => { + return Object.assign(all, this.values[file]); + }, {}); + } + return this._all; + } + addFile(file) { + if (!(file in this.values)) { + const latest = last(this.files); + this.values[file] = latest ? Object.create(this.values[latest]) : {}; + this.files.push(file); + } + return this.values[file]; + } + addValue(file, key, value) { + const values = this.addFile(file); + if (!values.hasOwnProperty(key)) { + values[key] = value; + } else if (Array.isArray(values[key])) { + values[key].push(value); + } else { + values[key] = [values[key], value]; + } + this._all = void 0; + } + }; + } +}); + +// src/lib/tasks/config.ts +function asConfigScope(scope, fallback) { + if (typeof scope === "string" && GitConfigScope.hasOwnProperty(scope)) { + return scope; + } + return fallback; +} +function addConfigTask(key, value, append2, scope) { + const commands = ["config", `--${scope}`]; + if (append2) { + commands.push("--add"); + } + commands.push(key, value); + return { + commands, + format: "utf-8", + parser(text) { + return text; + } + }; +} +function getConfigTask(key, scope) { + const commands = ["config", "--null", "--show-origin", "--get-all", key]; + if (scope) { + commands.splice(1, 0, `--${scope}`); + } + return { + commands, + format: "utf-8", + parser(text) { + return configGetParser(text, key); + } + }; +} +function listConfigTask(scope) { + const commands = ["config", "--list", "--show-origin", "--null"]; + if (scope) { + commands.push(`--${scope}`); + } + return { + commands, + format: "utf-8", + parser(text) { + return configListParser(text); + } + }; +} +function config_default() { + return { + addConfig(key, value, ...rest) { + return this._runTask( + addConfigTask( + key, + value, + rest[0] === true, + asConfigScope(rest[1], "local" /* local */) + ), + trailingFunctionArgument(arguments) + ); + }, + getConfig(key, scope) { + return this._runTask( + getConfigTask(key, asConfigScope(scope, void 0)), + trailingFunctionArgument(arguments) + ); + }, + listConfig(...rest) { + return this._runTask( + listConfigTask(asConfigScope(rest[0], void 0)), + trailingFunctionArgument(arguments) + ); + } + }; +} +var GitConfigScope; +var init_config = __esm({ + "src/lib/tasks/config.ts"() { + "use strict"; + init_ConfigList(); + init_utils(); + GitConfigScope = /* @__PURE__ */ ((GitConfigScope2) => { + GitConfigScope2["system"] = "system"; + GitConfigScope2["global"] = "global"; + GitConfigScope2["local"] = "local"; + GitConfigScope2["worktree"] = "worktree"; + return GitConfigScope2; + })(GitConfigScope || {}); + } +}); + +// src/lib/tasks/diff-name-status.ts +function isDiffNameStatus(input) { + return diffNameStatus.has(input); +} +var DiffNameStatus, diffNameStatus; +var init_diff_name_status = __esm({ + "src/lib/tasks/diff-name-status.ts"() { + "use strict"; + DiffNameStatus = /* @__PURE__ */ ((DiffNameStatus2) => { + DiffNameStatus2["ADDED"] = "A"; + DiffNameStatus2["COPIED"] = "C"; + DiffNameStatus2["DELETED"] = "D"; + DiffNameStatus2["MODIFIED"] = "M"; + DiffNameStatus2["RENAMED"] = "R"; + DiffNameStatus2["CHANGED"] = "T"; + DiffNameStatus2["UNMERGED"] = "U"; + DiffNameStatus2["UNKNOWN"] = "X"; + DiffNameStatus2["BROKEN"] = "B"; + return DiffNameStatus2; + })(DiffNameStatus || {}); + diffNameStatus = new Set(Object.values(DiffNameStatus)); + } +}); + +// src/lib/tasks/grep.ts +function grepQueryBuilder(...params) { + return new GrepQuery().param(...params); +} +function parseGrep(grep) { + const paths = /* @__PURE__ */ new Set(); + const results = {}; + forEachLineWithContent(grep, (input) => { + const [path, line, preview] = input.split(NULL); + paths.add(path); + (results[path] = results[path] || []).push({ + line: asNumber(line), + path, + preview + }); + }); + return { + paths, + results + }; +} +function grep_default() { + return { + grep(searchTerm) { + const then = trailingFunctionArgument(arguments); + const options = getTrailingOptions(arguments); + for (const option of disallowedOptions) { + if (options.includes(option)) { + return this._runTask( + configurationErrorTask(`git.grep: use of "${option}" is not supported.`), + then + ); + } + } + if (typeof searchTerm === "string") { + searchTerm = grepQueryBuilder().param(searchTerm); + } + const commands = ["grep", "--null", "-n", "--full-name", ...options, ...searchTerm]; + return this._runTask( + { + commands, + format: "utf-8", + parser(stdOut) { + return parseGrep(stdOut); + } + }, + then + ); + } + }; +} +var disallowedOptions, Query, _a, GrepQuery; +var init_grep = __esm({ + "src/lib/tasks/grep.ts"() { + "use strict"; + init_utils(); + init_task(); + disallowedOptions = ["-h"]; + Query = Symbol("grepQuery"); + GrepQuery = class { + constructor() { + this[_a] = []; + } + *[(_a = Query, Symbol.iterator)]() { + for (const query of this[Query]) { + yield query; + } + } + and(...and) { + and.length && this[Query].push("--and", "(", ...prefixedArray(and, "-e"), ")"); + return this; + } + param(...param) { + this[Query].push(...prefixedArray(param, "-e")); + return this; + } + }; + } +}); + +// src/lib/tasks/reset.ts +var reset_exports = {}; +__export(reset_exports, { + ResetMode: () => ResetMode, + getResetMode: () => getResetMode, + resetTask: () => resetTask +}); +function resetTask(mode, customArgs) { + const commands = ["reset"]; + if (isValidResetMode(mode)) { + commands.push(`--${mode}`); + } + commands.push(...customArgs); + return straightThroughStringTask(commands); +} +function getResetMode(mode) { + if (isValidResetMode(mode)) { + return mode; + } + switch (typeof mode) { + case "string": + case "undefined": + return "soft" /* SOFT */; + } + return; +} +function isValidResetMode(mode) { + return ResetModes.includes(mode); +} +var ResetMode, ResetModes; +var init_reset = __esm({ + "src/lib/tasks/reset.ts"() { + "use strict"; + init_task(); + ResetMode = /* @__PURE__ */ ((ResetMode2) => { + ResetMode2["MIXED"] = "mixed"; + ResetMode2["SOFT"] = "soft"; + ResetMode2["HARD"] = "hard"; + ResetMode2["MERGE"] = "merge"; + ResetMode2["KEEP"] = "keep"; + return ResetMode2; + })(ResetMode || {}); + ResetModes = Array.from(Object.values(ResetMode)); + } +}); + +// src/lib/api.ts +var api_exports = {}; +__export(api_exports, { + CheckRepoActions: () => CheckRepoActions, + CleanOptions: () => CleanOptions, + DiffNameStatus: () => DiffNameStatus, + GitConfigScope: () => GitConfigScope, + GitConstructError: () => GitConstructError, + GitError: () => GitError, + GitPluginError: () => GitPluginError, + GitResponseError: () => GitResponseError, + ResetMode: () => ResetMode, + TaskConfigurationError: () => TaskConfigurationError, + grepQueryBuilder: () => grepQueryBuilder, + pathspec: () => pathspec +}); +var init_api = __esm({ + "src/lib/api.ts"() { + "use strict"; + init_pathspec(); + init_git_construct_error(); + init_git_error(); + init_git_plugin_error(); + init_git_response_error(); + init_task_configuration_error(); + init_check_is_repo(); + init_clean(); + init_config(); + init_diff_name_status(); + init_grep(); + init_reset(); + } +}); + +// src/lib/plugins/abort-plugin.ts +function abortPlugin(signal) { + if (!signal) { + return; + } + const onSpawnAfter = { + type: "spawn.after", + action(_data, context) { + function kill() { + context.kill(new GitPluginError(void 0, "abort", "Abort signal received")); + } + signal.addEventListener("abort", kill); + context.spawned.on("close", () => signal.removeEventListener("abort", kill)); + } + }; + const onSpawnBefore = { + type: "spawn.before", + action(_data, context) { + if (signal.aborted) { + context.kill(new GitPluginError(void 0, "abort", "Abort already signaled")); + } + } + }; + return [onSpawnBefore, onSpawnAfter]; +} +var init_abort_plugin = __esm({ + "src/lib/plugins/abort-plugin.ts"() { + "use strict"; + init_git_plugin_error(); + } +}); + +// src/lib/plugins/block-unsafe-operations-plugin.ts +function isConfigSwitch(arg) { + return typeof arg === "string" && arg.trim().toLowerCase() === "-c"; +} +function preventProtocolOverride(arg, next) { + if (!isConfigSwitch(arg)) { + return; + } + if (!/^\s*protocol(.[a-z]+)?.allow/.test(next)) { + return; + } + throw new GitPluginError( + void 0, + "unsafe", + "Configuring protocol.allow is not permitted without enabling allowUnsafeExtProtocol" + ); +} +function preventUploadPack(arg, method) { + if (/^\s*--(upload|receive)-pack/.test(arg)) { + throw new GitPluginError( + void 0, + "unsafe", + `Use of --upload-pack or --receive-pack is not permitted without enabling allowUnsafePack` + ); + } + if (method === "clone" && /^\s*-u\b/.test(arg)) { + throw new GitPluginError( + void 0, + "unsafe", + `Use of clone with option -u is not permitted without enabling allowUnsafePack` + ); + } + if (method === "push" && /^\s*--exec\b/.test(arg)) { + throw new GitPluginError( + void 0, + "unsafe", + `Use of push with option --exec is not permitted without enabling allowUnsafePack` + ); + } +} +function blockUnsafeOperationsPlugin({ + allowUnsafeProtocolOverride = false, + allowUnsafePack = false +} = {}) { + return { + type: "spawn.args", + action(args, context) { + args.forEach((current, index) => { + const next = index < args.length ? args[index + 1] : ""; + allowUnsafeProtocolOverride || preventProtocolOverride(current, next); + allowUnsafePack || preventUploadPack(current, context.method); + }); + return args; + } + }; +} +var init_block_unsafe_operations_plugin = __esm({ + "src/lib/plugins/block-unsafe-operations-plugin.ts"() { + "use strict"; + init_git_plugin_error(); + } +}); + +// src/lib/plugins/command-config-prefixing-plugin.ts +function commandConfigPrefixingPlugin(configuration) { + const prefix = prefixedArray(configuration, "-c"); + return { + type: "spawn.args", + action(data) { + return [...prefix, ...data]; + } + }; +} +var init_command_config_prefixing_plugin = __esm({ + "src/lib/plugins/command-config-prefixing-plugin.ts"() { + "use strict"; + init_utils(); + } +}); + +// src/lib/plugins/completion-detection.plugin.ts +function completionDetectionPlugin({ + onClose = true, + onExit = 50 +} = {}) { + function createEvents() { + let exitCode = -1; + const events = { + close: (0, import_promise_deferred.deferred)(), + closeTimeout: (0, import_promise_deferred.deferred)(), + exit: (0, import_promise_deferred.deferred)(), + exitTimeout: (0, import_promise_deferred.deferred)() + }; + const result = Promise.race([ + onClose === false ? never : events.closeTimeout.promise, + onExit === false ? never : events.exitTimeout.promise + ]); + configureTimeout(onClose, events.close, events.closeTimeout); + configureTimeout(onExit, events.exit, events.exitTimeout); + return { + close(code) { + exitCode = code; + events.close.done(); + }, + exit(code) { + exitCode = code; + events.exit.done(); + }, + get exitCode() { + return exitCode; + }, + result + }; + } + function configureTimeout(flag, event, timeout) { + if (flag === false) { + return; + } + (flag === true ? event.promise : event.promise.then(() => delay(flag))).then(timeout.done); + } + return { + type: "spawn.after", + action(_0, _1) { + return __async(this, arguments, function* (_data, { spawned, close }) { + var _a3, _b; + const events = createEvents(); + let deferClose = true; + let quickClose = () => void (deferClose = false); + (_a3 = spawned.stdout) == null ? void 0 : _a3.on("data", quickClose); + (_b = spawned.stderr) == null ? void 0 : _b.on("data", quickClose); + spawned.on("error", quickClose); + spawned.on("close", (code) => events.close(code)); + spawned.on("exit", (code) => events.exit(code)); + try { + yield events.result; + if (deferClose) { + yield delay(50); + } + close(events.exitCode); + } catch (err) { + close(events.exitCode, err); + } + }); + } + }; +} +var import_promise_deferred, never; +var init_completion_detection_plugin = __esm({ + "src/lib/plugins/completion-detection.plugin.ts"() { + "use strict"; + import_promise_deferred = __nccwpck_require__(49819); + init_utils(); + never = (0, import_promise_deferred.deferred)().promise; + } +}); + +// src/lib/plugins/custom-binary.plugin.ts +function isBadArgument(arg) { + return !arg || !/^([a-z]:)?([a-z0-9/.\\_-]+)$/i.test(arg); +} +function toBinaryConfig(input, allowUnsafe) { + if (input.length < 1 || input.length > 2) { + throw new GitPluginError(void 0, "binary", WRONG_NUMBER_ERR); + } + const isBad = input.some(isBadArgument); + if (isBad) { + if (allowUnsafe) { + console.warn(WRONG_CHARS_ERR); + } else { + throw new GitPluginError(void 0, "binary", WRONG_CHARS_ERR); + } + } + const [binary, prefix] = input; + return { + binary, + prefix + }; +} +function customBinaryPlugin(plugins, input = ["git"], allowUnsafe = false) { + let config = toBinaryConfig(asArray(input), allowUnsafe); + plugins.on("binary", (input2) => { + config = toBinaryConfig(asArray(input2), allowUnsafe); + }); + plugins.append("spawn.binary", () => { + return config.binary; + }); + plugins.append("spawn.args", (data) => { + return config.prefix ? [config.prefix, ...data] : data; + }); +} +var WRONG_NUMBER_ERR, WRONG_CHARS_ERR; +var init_custom_binary_plugin = __esm({ + "src/lib/plugins/custom-binary.plugin.ts"() { + "use strict"; + init_git_plugin_error(); + init_utils(); + WRONG_NUMBER_ERR = `Invalid value supplied for custom binary, requires a single string or an array containing either one or two strings`; + WRONG_CHARS_ERR = `Invalid value supplied for custom binary, restricted characters must be removed or supply the unsafe.allowUnsafeCustomBinary option`; + } +}); + +// src/lib/plugins/error-detection.plugin.ts +function isTaskError(result) { + return !!(result.exitCode && result.stdErr.length); +} +function getErrorMessage(result) { + return Buffer.concat([...result.stdOut, ...result.stdErr]); +} +function errorDetectionHandler(overwrite = false, isError = isTaskError, errorMessage = getErrorMessage) { + return (error, result) => { + if (!overwrite && error || !isError(result)) { + return error; + } + return errorMessage(result); + }; +} +function errorDetectionPlugin(config) { + return { + type: "task.error", + action(data, context) { + const error = config(data.error, { + stdErr: context.stdErr, + stdOut: context.stdOut, + exitCode: context.exitCode + }); + if (Buffer.isBuffer(error)) { + return { error: new GitError(void 0, error.toString("utf-8")) }; + } + return { + error + }; + } + }; +} +var init_error_detection_plugin = __esm({ + "src/lib/plugins/error-detection.plugin.ts"() { + "use strict"; + init_git_error(); + } +}); + +// src/lib/plugins/plugin-store.ts +var import_node_events, PluginStore; +var init_plugin_store = __esm({ + "src/lib/plugins/plugin-store.ts"() { + "use strict"; + import_node_events = __nccwpck_require__(15673); + init_utils(); + PluginStore = class { + constructor() { + this.plugins = /* @__PURE__ */ new Set(); + this.events = new import_node_events.EventEmitter(); + } + on(type, listener) { + this.events.on(type, listener); + } + reconfigure(type, data) { + this.events.emit(type, data); + } + append(type, action) { + const plugin = append(this.plugins, { type, action }); + return () => this.plugins.delete(plugin); + } + add(plugin) { + const plugins = []; + asArray(plugin).forEach((plugin2) => plugin2 && this.plugins.add(append(plugins, plugin2))); + return () => { + plugins.forEach((plugin2) => this.plugins.delete(plugin2)); + }; + } + exec(type, data, context) { + let output = data; + const contextual = Object.freeze(Object.create(context)); + for (const plugin of this.plugins) { + if (plugin.type === type) { + output = plugin.action(output, contextual); + } + } + return output; + } + }; + } +}); + +// src/lib/plugins/progress-monitor-plugin.ts +function progressMonitorPlugin(progress) { + const progressCommand = "--progress"; + const progressMethods = ["checkout", "clone", "fetch", "pull", "push"]; + const onProgress = { + type: "spawn.after", + action(_data, context) { + var _a2; + if (!context.commands.includes(progressCommand)) { + return; + } + (_a2 = context.spawned.stderr) == null ? void 0 : _a2.on("data", (chunk) => { + const message = /^([\s\S]+?):\s*(\d+)% \((\d+)\/(\d+)\)/.exec(chunk.toString("utf8")); + if (!message) { + return; + } + progress({ + method: context.method, + stage: progressEventStage(message[1]), + progress: asNumber(message[2]), + processed: asNumber(message[3]), + total: asNumber(message[4]) + }); + }); + } + }; + const onArgs = { + type: "spawn.args", + action(args, context) { + if (!progressMethods.includes(context.method)) { + return args; + } + return including(args, progressCommand); + } + }; + return [onArgs, onProgress]; +} +function progressEventStage(input) { + return String(input.toLowerCase().split(" ", 1)) || "unknown"; +} +var init_progress_monitor_plugin = __esm({ + "src/lib/plugins/progress-monitor-plugin.ts"() { + "use strict"; + init_utils(); + } +}); + +// src/lib/plugins/simple-git-plugin.ts +var init_simple_git_plugin = __esm({ + "src/lib/plugins/simple-git-plugin.ts"() { + "use strict"; + } +}); + +// src/lib/plugins/spawn-options-plugin.ts +function spawnOptionsPlugin(spawnOptions) { + const options = pick(spawnOptions, ["uid", "gid"]); + return { + type: "spawn.options", + action(data) { + return __spreadValues(__spreadValues({}, options), data); + } + }; +} +var init_spawn_options_plugin = __esm({ + "src/lib/plugins/spawn-options-plugin.ts"() { + "use strict"; + init_utils(); + } +}); + +// src/lib/plugins/timout-plugin.ts +function timeoutPlugin({ + block, + stdErr = true, + stdOut = true +}) { + if (block > 0) { + return { + type: "spawn.after", + action(_data, context) { + var _a2, _b; + let timeout; + function wait() { + timeout && clearTimeout(timeout); + timeout = setTimeout(kill, block); + } + function stop() { + var _a3, _b2; + (_a3 = context.spawned.stdout) == null ? void 0 : _a3.off("data", wait); + (_b2 = context.spawned.stderr) == null ? void 0 : _b2.off("data", wait); + context.spawned.off("exit", stop); + context.spawned.off("close", stop); + timeout && clearTimeout(timeout); + } + function kill() { + stop(); + context.kill(new GitPluginError(void 0, "timeout", `block timeout reached`)); + } + stdOut && ((_a2 = context.spawned.stdout) == null ? void 0 : _a2.on("data", wait)); + stdErr && ((_b = context.spawned.stderr) == null ? void 0 : _b.on("data", wait)); + context.spawned.on("exit", stop); + context.spawned.on("close", stop); + wait(); + } + }; + } +} +var init_timout_plugin = __esm({ + "src/lib/plugins/timout-plugin.ts"() { + "use strict"; + init_git_plugin_error(); + } +}); + +// src/lib/plugins/index.ts +var init_plugins = __esm({ + "src/lib/plugins/index.ts"() { + "use strict"; + init_abort_plugin(); + init_block_unsafe_operations_plugin(); + init_command_config_prefixing_plugin(); + init_completion_detection_plugin(); + init_custom_binary_plugin(); + init_error_detection_plugin(); + init_plugin_store(); + init_progress_monitor_plugin(); + init_simple_git_plugin(); + init_spawn_options_plugin(); + init_timout_plugin(); + } +}); + +// src/lib/plugins/suffix-paths.plugin.ts +function suffixPathsPlugin() { + return { + type: "spawn.args", + action(data) { + const prefix = []; + let suffix; + function append2(args) { + (suffix = suffix || []).push(...args); + } + for (let i = 0; i < data.length; i++) { + const param = data[i]; + if (isPathSpec(param)) { + append2(toPaths(param)); + continue; + } + if (param === "--") { + append2( + data.slice(i + 1).flatMap((item) => isPathSpec(item) && toPaths(item) || item) + ); + break; + } + prefix.push(param); + } + return !suffix ? prefix : [...prefix, "--", ...suffix.map(String)]; + } + }; +} +var init_suffix_paths_plugin = __esm({ + "src/lib/plugins/suffix-paths.plugin.ts"() { + "use strict"; + init_pathspec(); + } +}); + +// src/lib/git-logger.ts +function createLog() { + return (0, import_debug.default)("simple-git"); +} +function prefixedLogger(to, prefix, forward) { + if (!prefix || !String(prefix).replace(/\s*/, "")) { + return !forward ? to : (message, ...args) => { + to(message, ...args); + forward(message, ...args); + }; + } + return (message, ...args) => { + to(`%s ${message}`, prefix, ...args); + if (forward) { + forward(message, ...args); + } + }; +} +function childLoggerName(name, childDebugger, { namespace: parentNamespace }) { + if (typeof name === "string") { + return name; + } + const childNamespace = childDebugger && childDebugger.namespace || ""; + if (childNamespace.startsWith(parentNamespace)) { + return childNamespace.substr(parentNamespace.length + 1); + } + return childNamespace || parentNamespace; +} +function createLogger(label, verbose, initialStep, infoDebugger = createLog()) { + const labelPrefix = label && `[${label}]` || ""; + const spawned = []; + const debugDebugger = typeof verbose === "string" ? infoDebugger.extend(verbose) : verbose; + const key = childLoggerName(filterType(verbose, filterString), debugDebugger, infoDebugger); + return step(initialStep); + function sibling(name, initial) { + return append( + spawned, + createLogger(label, key.replace(/^[^:]+/, name), initial, infoDebugger) + ); + } + function step(phase) { + const stepPrefix = phase && `[${phase}]` || ""; + const debug2 = debugDebugger && prefixedLogger(debugDebugger, stepPrefix) || NOOP; + const info = prefixedLogger(infoDebugger, `${labelPrefix} ${stepPrefix}`, debug2); + return Object.assign(debugDebugger ? debug2 : info, { + label, + sibling, + info, + step + }); + } +} +var import_debug; +var init_git_logger = __esm({ + "src/lib/git-logger.ts"() { + "use strict"; + import_debug = __toESM(__nccwpck_require__(38237)); + init_utils(); + import_debug.default.formatters.L = (value) => String(filterHasLength(value) ? value.length : "-"); + import_debug.default.formatters.B = (value) => { + if (Buffer.isBuffer(value)) { + return value.toString("utf8"); + } + return objectToString(value); + }; + } +}); + +// src/lib/runners/tasks-pending-queue.ts +var _TasksPendingQueue, TasksPendingQueue; +var init_tasks_pending_queue = __esm({ + "src/lib/runners/tasks-pending-queue.ts"() { + "use strict"; + init_git_error(); + init_git_logger(); + _TasksPendingQueue = class { + constructor(logLabel = "GitExecutor") { + this.logLabel = logLabel; + this._queue = /* @__PURE__ */ new Map(); + } + withProgress(task) { + return this._queue.get(task); + } + createProgress(task) { + const name = _TasksPendingQueue.getName(task.commands[0]); + const logger = createLogger(this.logLabel, name); + return { + task, + logger, + name + }; + } + push(task) { + const progress = this.createProgress(task); + progress.logger("Adding task to the queue, commands = %o", task.commands); + this._queue.set(task, progress); + return progress; + } + fatal(err) { + for (const [task, { logger }] of Array.from(this._queue.entries())) { + if (task === err.task) { + logger.info(`Failed %o`, err); + logger( + `Fatal exception, any as-yet un-started tasks run through this executor will not be attempted` + ); + } else { + logger.info( + `A fatal exception occurred in a previous task, the queue has been purged: %o`, + err.message + ); + } + this.complete(task); + } + if (this._queue.size !== 0) { + throw new Error(`Queue size should be zero after fatal: ${this._queue.size}`); + } + } + complete(task) { + const progress = this.withProgress(task); + if (progress) { + this._queue.delete(task); + } + } + attempt(task) { + const progress = this.withProgress(task); + if (!progress) { + throw new GitError(void 0, "TasksPendingQueue: attempt called for an unknown task"); + } + progress.logger("Starting task"); + return progress; + } + static getName(name = "empty") { + return `task:${name}:${++_TasksPendingQueue.counter}`; + } + }; + TasksPendingQueue = _TasksPendingQueue; + TasksPendingQueue.counter = 0; + } +}); + +// src/lib/runners/git-executor-chain.ts +function pluginContext(task, commands) { + return { + method: first(task.commands) || "", + commands + }; +} +function onErrorReceived(target, logger) { + return (err) => { + logger(`[ERROR] child process exception %o`, err); + target.push(Buffer.from(String(err.stack), "ascii")); + }; +} +function onDataReceived(target, name, logger, output) { + return (buffer) => { + logger(`%s received %L bytes`, name, buffer); + output(`%B`, buffer); + target.push(buffer); + }; +} +var import_child_process, GitExecutorChain; +var init_git_executor_chain = __esm({ + "src/lib/runners/git-executor-chain.ts"() { + "use strict"; + import_child_process = __nccwpck_require__(32081); + init_git_error(); + init_task(); + init_utils(); + init_tasks_pending_queue(); + GitExecutorChain = class { + constructor(_executor, _scheduler, _plugins) { + this._executor = _executor; + this._scheduler = _scheduler; + this._plugins = _plugins; + this._chain = Promise.resolve(); + this._queue = new TasksPendingQueue(); + } + get cwd() { + return this._cwd || this._executor.cwd; + } + set cwd(cwd) { + this._cwd = cwd; + } + get env() { + return this._executor.env; + } + get outputHandler() { + return this._executor.outputHandler; + } + chain() { + return this; + } + push(task) { + this._queue.push(task); + return this._chain = this._chain.then(() => this.attemptTask(task)); + } + attemptTask(task) { + return __async(this, null, function* () { + const onScheduleComplete = yield this._scheduler.next(); + const onQueueComplete = () => this._queue.complete(task); + try { + const { logger } = this._queue.attempt(task); + return yield isEmptyTask(task) ? this.attemptEmptyTask(task, logger) : this.attemptRemoteTask(task, logger); + } catch (e) { + throw this.onFatalException(task, e); + } finally { + onQueueComplete(); + onScheduleComplete(); + } + }); + } + onFatalException(task, e) { + const gitError = e instanceof GitError ? Object.assign(e, { task }) : new GitError(task, e && String(e)); + this._chain = Promise.resolve(); + this._queue.fatal(gitError); + return gitError; + } + attemptRemoteTask(task, logger) { + return __async(this, null, function* () { + const binary = this._plugins.exec("spawn.binary", "", pluginContext(task, task.commands)); + const args = this._plugins.exec( + "spawn.args", + [...task.commands], + pluginContext(task, task.commands) + ); + const raw = yield this.gitResponse( + task, + binary, + args, + this.outputHandler, + logger.step("SPAWN") + ); + const outputStreams = yield this.handleTaskData(task, args, raw, logger.step("HANDLE")); + logger(`passing response to task's parser as a %s`, task.format); + if (isBufferTask(task)) { + return callTaskParser(task.parser, outputStreams); + } + return callTaskParser(task.parser, outputStreams.asStrings()); + }); + } + attemptEmptyTask(task, logger) { + return __async(this, null, function* () { + logger(`empty task bypassing child process to call to task's parser`); + return task.parser(this); + }); + } + handleTaskData(task, args, result, logger) { + const { exitCode, rejection, stdOut, stdErr } = result; + return new Promise((done, fail) => { + logger(`Preparing to handle process response exitCode=%d stdOut=`, exitCode); + const { error } = this._plugins.exec( + "task.error", + { error: rejection }, + __spreadValues(__spreadValues({}, pluginContext(task, args)), result) + ); + if (error && task.onError) { + logger.info(`exitCode=%s handling with custom error handler`); + return task.onError( + result, + error, + (newStdOut) => { + logger.info(`custom error handler treated as success`); + logger(`custom error returned a %s`, objectToString(newStdOut)); + done( + new GitOutputStreams( + Array.isArray(newStdOut) ? Buffer.concat(newStdOut) : newStdOut, + Buffer.concat(stdErr) + ) + ); + }, + fail + ); + } + if (error) { + logger.info( + `handling as error: exitCode=%s stdErr=%s rejection=%o`, + exitCode, + stdErr.length, + rejection + ); + return fail(error); + } + logger.info(`retrieving task output complete`); + done(new GitOutputStreams(Buffer.concat(stdOut), Buffer.concat(stdErr))); + }); + } + gitResponse(task, command, args, outputHandler, logger) { + return __async(this, null, function* () { + const outputLogger = logger.sibling("output"); + const spawnOptions = this._plugins.exec( + "spawn.options", + { + cwd: this.cwd, + env: this.env, + windowsHide: true + }, + pluginContext(task, task.commands) + ); + return new Promise((done) => { + const stdOut = []; + const stdErr = []; + logger.info(`%s %o`, command, args); + logger("%O", spawnOptions); + let rejection = this._beforeSpawn(task, args); + if (rejection) { + return done({ + stdOut, + stdErr, + exitCode: 9901, + rejection + }); + } + this._plugins.exec("spawn.before", void 0, __spreadProps(__spreadValues({}, pluginContext(task, args)), { + kill(reason) { + rejection = reason || rejection; + } + })); + const spawned = (0, import_child_process.spawn)(command, args, spawnOptions); + spawned.stdout.on( + "data", + onDataReceived(stdOut, "stdOut", logger, outputLogger.step("stdOut")) + ); + spawned.stderr.on( + "data", + onDataReceived(stdErr, "stdErr", logger, outputLogger.step("stdErr")) + ); + spawned.on("error", onErrorReceived(stdErr, logger)); + if (outputHandler) { + logger(`Passing child process stdOut/stdErr to custom outputHandler`); + outputHandler(command, spawned.stdout, spawned.stderr, [...args]); + } + this._plugins.exec("spawn.after", void 0, __spreadProps(__spreadValues({}, pluginContext(task, args)), { + spawned, + close(exitCode, reason) { + done({ + stdOut, + stdErr, + exitCode, + rejection: rejection || reason + }); + }, + kill(reason) { + if (spawned.killed) { + return; + } + rejection = reason; + spawned.kill("SIGINT"); + } + })); + }); + }); + } + _beforeSpawn(task, args) { + let rejection; + this._plugins.exec("spawn.before", void 0, __spreadProps(__spreadValues({}, pluginContext(task, args)), { + kill(reason) { + rejection = reason || rejection; + } + })); + return rejection; + } + }; + } +}); + +// src/lib/runners/git-executor.ts +var git_executor_exports = {}; +__export(git_executor_exports, { + GitExecutor: () => GitExecutor +}); +var GitExecutor; +var init_git_executor = __esm({ + "src/lib/runners/git-executor.ts"() { + "use strict"; + init_git_executor_chain(); + GitExecutor = class { + constructor(cwd, _scheduler, _plugins) { + this.cwd = cwd; + this._scheduler = _scheduler; + this._plugins = _plugins; + this._chain = new GitExecutorChain(this, this._scheduler, this._plugins); + } + chain() { + return new GitExecutorChain(this, this._scheduler, this._plugins); + } + push(task) { + return this._chain.push(task); + } + }; + } +}); + +// src/lib/task-callback.ts +function taskCallback(task, response, callback = NOOP) { + const onSuccess = (data) => { + callback(null, data); + }; + const onError2 = (err) => { + if ((err == null ? void 0 : err.task) === task) { + callback( + err instanceof GitResponseError ? addDeprecationNoticeToError(err) : err, + void 0 + ); + } + }; + response.then(onSuccess, onError2); +} +function addDeprecationNoticeToError(err) { + let log = (name) => { + console.warn( + `simple-git deprecation notice: accessing GitResponseError.${name} should be GitResponseError.git.${name}, this will no longer be available in version 3` + ); + log = NOOP; + }; + return Object.create(err, Object.getOwnPropertyNames(err.git).reduce(descriptorReducer, {})); + function descriptorReducer(all, name) { + if (name in err) { + return all; + } + all[name] = { + enumerable: false, + configurable: false, + get() { + log(name); + return err.git[name]; + } + }; + return all; + } +} +var init_task_callback = __esm({ + "src/lib/task-callback.ts"() { + "use strict"; + init_git_response_error(); + init_utils(); + } +}); + +// src/lib/tasks/change-working-directory.ts +function changeWorkingDirectoryTask(directory, root) { + return adhocExecTask((instance) => { + if (!folderExists(directory)) { + throw new Error(`Git.cwd: cannot change to non-directory "${directory}"`); + } + return (root || instance).cwd = directory; + }); +} +var init_change_working_directory = __esm({ + "src/lib/tasks/change-working-directory.ts"() { + "use strict"; + init_utils(); + init_task(); + } +}); + +// src/lib/tasks/checkout.ts +function checkoutTask(args) { + const commands = ["checkout", ...args]; + if (commands[1] === "-b" && commands.includes("-B")) { + commands[1] = remove(commands, "-B"); + } + return straightThroughStringTask(commands); +} +function checkout_default() { + return { + checkout() { + return this._runTask( + checkoutTask(getTrailingOptions(arguments, 1)), + trailingFunctionArgument(arguments) + ); + }, + checkoutBranch(branchName, startPoint) { + return this._runTask( + checkoutTask(["-b", branchName, startPoint, ...getTrailingOptions(arguments)]), + trailingFunctionArgument(arguments) + ); + }, + checkoutLocalBranch(branchName) { + return this._runTask( + checkoutTask(["-b", branchName, ...getTrailingOptions(arguments)]), + trailingFunctionArgument(arguments) + ); + } + }; +} +var init_checkout = __esm({ + "src/lib/tasks/checkout.ts"() { + "use strict"; + init_utils(); + init_task(); + } +}); + +// src/lib/parsers/parse-commit.ts +function parseCommitResult(stdOut) { + const result = { + author: null, + branch: "", + commit: "", + root: false, + summary: { + changes: 0, + insertions: 0, + deletions: 0 + } + }; + return parseStringResponse(result, parsers, stdOut); +} +var parsers; +var init_parse_commit = __esm({ + "src/lib/parsers/parse-commit.ts"() { + "use strict"; + init_utils(); + parsers = [ + new LineParser(/^\[([^\s]+)( \([^)]+\))? ([^\]]+)/, (result, [branch, root, commit]) => { + result.branch = branch; + result.commit = commit; + result.root = !!root; + }), + new LineParser(/\s*Author:\s(.+)/i, (result, [author]) => { + const parts = author.split("<"); + const email = parts.pop(); + if (!email || !email.includes("@")) { + return; + } + result.author = { + email: email.substr(0, email.length - 1), + name: parts.join("<").trim() + }; + }), + new LineParser( + /(\d+)[^,]*(?:,\s*(\d+)[^,]*)(?:,\s*(\d+))/g, + (result, [changes, insertions, deletions]) => { + result.summary.changes = parseInt(changes, 10) || 0; + result.summary.insertions = parseInt(insertions, 10) || 0; + result.summary.deletions = parseInt(deletions, 10) || 0; + } + ), + new LineParser( + /^(\d+)[^,]*(?:,\s*(\d+)[^(]+\(([+-]))?/, + (result, [changes, lines, direction]) => { + result.summary.changes = parseInt(changes, 10) || 0; + const count = parseInt(lines, 10) || 0; + if (direction === "-") { + result.summary.deletions = count; + } else if (direction === "+") { + result.summary.insertions = count; + } + } + ) + ]; + } +}); + +// src/lib/tasks/commit.ts +function commitTask(message, files, customArgs) { + const commands = [ + "-c", + "core.abbrev=40", + "commit", + ...prefixedArray(message, "-m"), + ...files, + ...customArgs + ]; + return { + commands, + format: "utf-8", + parser: parseCommitResult + }; +} +function commit_default() { + return { + commit(message, ...rest) { + const next = trailingFunctionArgument(arguments); + const task = rejectDeprecatedSignatures(message) || commitTask( + asArray(message), + asArray(filterType(rest[0], filterStringOrStringArray, [])), + [...filterType(rest[1], filterArray, []), ...getTrailingOptions(arguments, 0, true)] + ); + return this._runTask(task, next); + } + }; + function rejectDeprecatedSignatures(message) { + return !filterStringOrStringArray(message) && configurationErrorTask( + `git.commit: requires the commit message to be supplied as a string/string[]` + ); + } +} +var init_commit = __esm({ + "src/lib/tasks/commit.ts"() { + "use strict"; + init_parse_commit(); + init_utils(); + init_task(); + } +}); + +// src/lib/tasks/first-commit.ts +function first_commit_default() { + return { + firstCommit() { + return this._runTask( + straightThroughStringTask(["rev-list", "--max-parents=0", "HEAD"], true), + trailingFunctionArgument(arguments) + ); + } + }; +} +var init_first_commit = __esm({ + "src/lib/tasks/first-commit.ts"() { + "use strict"; + init_utils(); + init_task(); + } +}); + +// src/lib/tasks/hash-object.ts +function hashObjectTask(filePath, write) { + const commands = ["hash-object", filePath]; + if (write) { + commands.push("-w"); + } + return straightThroughStringTask(commands, true); +} +var init_hash_object = __esm({ + "src/lib/tasks/hash-object.ts"() { + "use strict"; + init_task(); + } +}); + +// src/lib/responses/InitSummary.ts +function parseInit(bare, path, text) { + const response = String(text).trim(); + let result; + if (result = initResponseRegex.exec(response)) { + return new InitSummary(bare, path, false, result[1]); + } + if (result = reInitResponseRegex.exec(response)) { + return new InitSummary(bare, path, true, result[1]); + } + let gitDir = ""; + const tokens = response.split(" "); + while (tokens.length) { + const token = tokens.shift(); + if (token === "in") { + gitDir = tokens.join(" "); + break; + } + } + return new InitSummary(bare, path, /^re/i.test(response), gitDir); +} +var InitSummary, initResponseRegex, reInitResponseRegex; +var init_InitSummary = __esm({ + "src/lib/responses/InitSummary.ts"() { + "use strict"; + InitSummary = class { + constructor(bare, path, existing, gitDir) { + this.bare = bare; + this.path = path; + this.existing = existing; + this.gitDir = gitDir; + } + }; + initResponseRegex = /^Init.+ repository in (.+)$/; + reInitResponseRegex = /^Rein.+ in (.+)$/; + } +}); + +// src/lib/tasks/init.ts +function hasBareCommand(command) { + return command.includes(bareCommand); +} +function initTask(bare = false, path, customArgs) { + const commands = ["init", ...customArgs]; + if (bare && !hasBareCommand(commands)) { + commands.splice(1, 0, bareCommand); + } + return { + commands, + format: "utf-8", + parser(text) { + return parseInit(commands.includes("--bare"), path, text); + } + }; +} +var bareCommand; +var init_init = __esm({ + "src/lib/tasks/init.ts"() { + "use strict"; + init_InitSummary(); + bareCommand = "--bare"; + } +}); + +// src/lib/args/log-format.ts +function logFormatFromCommand(customArgs) { + for (let i = 0; i < customArgs.length; i++) { + const format = logFormatRegex.exec(customArgs[i]); + if (format) { + return `--${format[1]}`; + } + } + return "" /* NONE */; +} +function isLogFormat(customArg) { + return logFormatRegex.test(customArg); +} +var logFormatRegex; +var init_log_format = __esm({ + "src/lib/args/log-format.ts"() { + "use strict"; + logFormatRegex = /^--(stat|numstat|name-only|name-status)(=|$)/; + } +}); + +// src/lib/responses/DiffSummary.ts +var DiffSummary; +var init_DiffSummary = __esm({ + "src/lib/responses/DiffSummary.ts"() { + "use strict"; + DiffSummary = class { + constructor() { + this.changed = 0; + this.deletions = 0; + this.insertions = 0; + this.files = []; + } + }; + } +}); + +// src/lib/parsers/parse-diff-summary.ts +function getDiffParser(format = "" /* NONE */) { + const parser3 = diffSummaryParsers[format]; + return (stdOut) => parseStringResponse(new DiffSummary(), parser3, stdOut, false); +} +var statParser, numStatParser, nameOnlyParser, nameStatusParser, diffSummaryParsers; +var init_parse_diff_summary = __esm({ + "src/lib/parsers/parse-diff-summary.ts"() { + "use strict"; + init_log_format(); + init_DiffSummary(); + init_diff_name_status(); + init_utils(); + statParser = [ + new LineParser( + /^(.+)\s+\|\s+(\d+)(\s+[+\-]+)?$/, + (result, [file, changes, alterations = ""]) => { + result.files.push({ + file: file.trim(), + changes: asNumber(changes), + insertions: alterations.replace(/[^+]/g, "").length, + deletions: alterations.replace(/[^-]/g, "").length, + binary: false + }); + } + ), + new LineParser( + /^(.+) \|\s+Bin ([0-9.]+) -> ([0-9.]+) ([a-z]+)/, + (result, [file, before, after]) => { + result.files.push({ + file: file.trim(), + before: asNumber(before), + after: asNumber(after), + binary: true + }); + } + ), + new LineParser( + /(\d+) files? changed\s*((?:, \d+ [^,]+){0,2})/, + (result, [changed, summary]) => { + const inserted = /(\d+) i/.exec(summary); + const deleted = /(\d+) d/.exec(summary); + result.changed = asNumber(changed); + result.insertions = asNumber(inserted == null ? void 0 : inserted[1]); + result.deletions = asNumber(deleted == null ? void 0 : deleted[1]); + } + ) + ]; + numStatParser = [ + new LineParser( + /(\d+)\t(\d+)\t(.+)$/, + (result, [changesInsert, changesDelete, file]) => { + const insertions = asNumber(changesInsert); + const deletions = asNumber(changesDelete); + result.changed++; + result.insertions += insertions; + result.deletions += deletions; + result.files.push({ + file, + changes: insertions + deletions, + insertions, + deletions, + binary: false + }); + } + ), + new LineParser(/-\t-\t(.+)$/, (result, [file]) => { + result.changed++; + result.files.push({ + file, + after: 0, + before: 0, + binary: true + }); + }) + ]; + nameOnlyParser = [ + new LineParser(/(.+)$/, (result, [file]) => { + result.changed++; + result.files.push({ + file, + changes: 0, + insertions: 0, + deletions: 0, + binary: false + }); + }) + ]; + nameStatusParser = [ + new LineParser( + /([ACDMRTUXB])([0-9]{0,3})\t(.[^\t]*)(\t(.[^\t]*))?$/, + (result, [status, _similarity, from, _to, to]) => { + result.changed++; + result.files.push({ + file: to != null ? to : from, + changes: 0, + status: orVoid(isDiffNameStatus(status) && status), + insertions: 0, + deletions: 0, + binary: false + }); + } + ) + ]; + diffSummaryParsers = { + ["" /* NONE */]: statParser, + ["--stat" /* STAT */]: statParser, + ["--numstat" /* NUM_STAT */]: numStatParser, + ["--name-status" /* NAME_STATUS */]: nameStatusParser, + ["--name-only" /* NAME_ONLY */]: nameOnlyParser + }; + } +}); + +// src/lib/parsers/parse-list-log-summary.ts +function lineBuilder(tokens, fields) { + return fields.reduce( + (line, field, index) => { + line[field] = tokens[index] || ""; + return line; + }, + /* @__PURE__ */ Object.create({ diff: null }) + ); +} +function createListLogSummaryParser(splitter = SPLITTER, fields = defaultFieldNames, logFormat = "" /* NONE */) { + const parseDiffResult = getDiffParser(logFormat); + return function(stdOut) { + const all = toLinesWithContent( + stdOut, + true, + START_BOUNDARY + ).map(function(item) { + const lineDetail = item.trim().split(COMMIT_BOUNDARY); + const listLogLine = lineBuilder( + lineDetail[0].trim().split(splitter), + fields + ); + if (lineDetail.length > 1 && !!lineDetail[1].trim()) { + listLogLine.diff = parseDiffResult(lineDetail[1]); + } + return listLogLine; + }); + return { + all, + latest: all.length && all[0] || null, + total: all.length + }; + }; +} +var START_BOUNDARY, COMMIT_BOUNDARY, SPLITTER, defaultFieldNames; +var init_parse_list_log_summary = __esm({ + "src/lib/parsers/parse-list-log-summary.ts"() { + "use strict"; + init_utils(); + init_parse_diff_summary(); + init_log_format(); + START_BOUNDARY = "\xF2\xF2\xF2\xF2\xF2\xF2 "; + COMMIT_BOUNDARY = " \xF2\xF2"; + SPLITTER = " \xF2 "; + defaultFieldNames = ["hash", "date", "message", "refs", "author_name", "author_email"]; + } +}); + +// src/lib/tasks/diff.ts +var diff_exports = {}; +__export(diff_exports, { + diffSummaryTask: () => diffSummaryTask, + validateLogFormatConfig: () => validateLogFormatConfig +}); +function diffSummaryTask(customArgs) { + let logFormat = logFormatFromCommand(customArgs); + const commands = ["diff"]; + if (logFormat === "" /* NONE */) { + logFormat = "--stat" /* STAT */; + commands.push("--stat=4096"); + } + commands.push(...customArgs); + return validateLogFormatConfig(commands) || { + commands, + format: "utf-8", + parser: getDiffParser(logFormat) + }; +} +function validateLogFormatConfig(customArgs) { + const flags = customArgs.filter(isLogFormat); + if (flags.length > 1) { + return configurationErrorTask( + `Summary flags are mutually exclusive - pick one of ${flags.join(",")}` + ); + } + if (flags.length && customArgs.includes("-z")) { + return configurationErrorTask( + `Summary flag ${flags} parsing is not compatible with null termination option '-z'` + ); + } +} +var init_diff = __esm({ + "src/lib/tasks/diff.ts"() { + "use strict"; + init_log_format(); + init_parse_diff_summary(); + init_task(); + } +}); + +// src/lib/tasks/log.ts +function prettyFormat(format, splitter) { + const fields = []; + const formatStr = []; + Object.keys(format).forEach((field) => { + fields.push(field); + formatStr.push(String(format[field])); + }); + return [fields, formatStr.join(splitter)]; +} +function userOptions(input) { + return Object.keys(input).reduce((out, key) => { + if (!(key in excludeOptions)) { + out[key] = input[key]; + } + return out; + }, {}); +} +function parseLogOptions(opt = {}, customArgs = []) { + const splitter = filterType(opt.splitter, filterString, SPLITTER); + const format = !filterPrimitives(opt.format) && opt.format ? opt.format : { + hash: "%H", + date: opt.strictDate === false ? "%ai" : "%aI", + message: "%s", + refs: "%D", + body: opt.multiLine ? "%B" : "%b", + author_name: opt.mailMap !== false ? "%aN" : "%an", + author_email: opt.mailMap !== false ? "%aE" : "%ae" + }; + const [fields, formatStr] = prettyFormat(format, splitter); + const suffix = []; + const command = [ + `--pretty=format:${START_BOUNDARY}${formatStr}${COMMIT_BOUNDARY}`, + ...customArgs + ]; + const maxCount = opt.n || opt["max-count"] || opt.maxCount; + if (maxCount) { + command.push(`--max-count=${maxCount}`); + } + if (opt.from || opt.to) { + const rangeOperator = opt.symmetric !== false ? "..." : ".."; + suffix.push(`${opt.from || ""}${rangeOperator}${opt.to || ""}`); + } + if (filterString(opt.file)) { + command.push("--follow", pathspec(opt.file)); + } + appendTaskOptions(userOptions(opt), command); + return { + fields, + splitter, + commands: [...command, ...suffix] + }; +} +function logTask(splitter, fields, customArgs) { + const parser3 = createListLogSummaryParser(splitter, fields, logFormatFromCommand(customArgs)); + return { + commands: ["log", ...customArgs], + format: "utf-8", + parser: parser3 + }; +} +function log_default() { + return { + log(...rest) { + const next = trailingFunctionArgument(arguments); + const options = parseLogOptions( + trailingOptionsArgument(arguments), + filterType(arguments[0], filterArray) + ); + const task = rejectDeprecatedSignatures(...rest) || validateLogFormatConfig(options.commands) || createLogTask(options); + return this._runTask(task, next); + } + }; + function createLogTask(options) { + return logTask(options.splitter, options.fields, options.commands); + } + function rejectDeprecatedSignatures(from, to) { + return filterString(from) && filterString(to) && configurationErrorTask( + `git.log(string, string) should be replaced with git.log({ from: string, to: string })` + ); + } +} +var excludeOptions; +var init_log = __esm({ + "src/lib/tasks/log.ts"() { + "use strict"; + init_log_format(); + init_pathspec(); + init_parse_list_log_summary(); + init_utils(); + init_task(); + init_diff(); + excludeOptions = /* @__PURE__ */ ((excludeOptions2) => { + excludeOptions2[excludeOptions2["--pretty"] = 0] = "--pretty"; + excludeOptions2[excludeOptions2["max-count"] = 1] = "max-count"; + excludeOptions2[excludeOptions2["maxCount"] = 2] = "maxCount"; + excludeOptions2[excludeOptions2["n"] = 3] = "n"; + excludeOptions2[excludeOptions2["file"] = 4] = "file"; + excludeOptions2[excludeOptions2["format"] = 5] = "format"; + excludeOptions2[excludeOptions2["from"] = 6] = "from"; + excludeOptions2[excludeOptions2["to"] = 7] = "to"; + excludeOptions2[excludeOptions2["splitter"] = 8] = "splitter"; + excludeOptions2[excludeOptions2["symmetric"] = 9] = "symmetric"; + excludeOptions2[excludeOptions2["mailMap"] = 10] = "mailMap"; + excludeOptions2[excludeOptions2["multiLine"] = 11] = "multiLine"; + excludeOptions2[excludeOptions2["strictDate"] = 12] = "strictDate"; + return excludeOptions2; + })(excludeOptions || {}); + } +}); + +// src/lib/responses/MergeSummary.ts +var MergeSummaryConflict, MergeSummaryDetail; +var init_MergeSummary = __esm({ + "src/lib/responses/MergeSummary.ts"() { + "use strict"; + MergeSummaryConflict = class { + constructor(reason, file = null, meta) { + this.reason = reason; + this.file = file; + this.meta = meta; + } + toString() { + return `${this.file}:${this.reason}`; + } + }; + MergeSummaryDetail = class { + constructor() { + this.conflicts = []; + this.merges = []; + this.result = "success"; + } + get failed() { + return this.conflicts.length > 0; + } + get reason() { + return this.result; + } + toString() { + if (this.conflicts.length) { + return `CONFLICTS: ${this.conflicts.join(", ")}`; + } + return "OK"; + } + }; + } +}); + +// src/lib/responses/PullSummary.ts +var PullSummary, PullFailedSummary; +var init_PullSummary = __esm({ + "src/lib/responses/PullSummary.ts"() { + "use strict"; + PullSummary = class { + constructor() { + this.remoteMessages = { + all: [] + }; + this.created = []; + this.deleted = []; + this.files = []; + this.deletions = {}; + this.insertions = {}; + this.summary = { + changes: 0, + deletions: 0, + insertions: 0 + }; + } + }; + PullFailedSummary = class { + constructor() { + this.remote = ""; + this.hash = { + local: "", + remote: "" + }; + this.branch = { + local: "", + remote: "" + }; + this.message = ""; + } + toString() { + return this.message; + } + }; + } +}); + +// src/lib/parsers/parse-remote-objects.ts +function objectEnumerationResult(remoteMessages) { + return remoteMessages.objects = remoteMessages.objects || { + compressing: 0, + counting: 0, + enumerating: 0, + packReused: 0, + reused: { count: 0, delta: 0 }, + total: { count: 0, delta: 0 } + }; +} +function asObjectCount(source) { + const count = /^\s*(\d+)/.exec(source); + const delta = /delta (\d+)/i.exec(source); + return { + count: asNumber(count && count[1] || "0"), + delta: asNumber(delta && delta[1] || "0") + }; +} +var remoteMessagesObjectParsers; +var init_parse_remote_objects = __esm({ + "src/lib/parsers/parse-remote-objects.ts"() { + "use strict"; + init_utils(); + remoteMessagesObjectParsers = [ + new RemoteLineParser( + /^remote:\s*(enumerating|counting|compressing) objects: (\d+),/i, + (result, [action, count]) => { + const key = action.toLowerCase(); + const enumeration = objectEnumerationResult(result.remoteMessages); + Object.assign(enumeration, { [key]: asNumber(count) }); + } + ), + new RemoteLineParser( + /^remote:\s*(enumerating|counting|compressing) objects: \d+% \(\d+\/(\d+)\),/i, + (result, [action, count]) => { + const key = action.toLowerCase(); + const enumeration = objectEnumerationResult(result.remoteMessages); + Object.assign(enumeration, { [key]: asNumber(count) }); + } + ), + new RemoteLineParser( + /total ([^,]+), reused ([^,]+), pack-reused (\d+)/i, + (result, [total, reused, packReused]) => { + const objects = objectEnumerationResult(result.remoteMessages); + objects.total = asObjectCount(total); + objects.reused = asObjectCount(reused); + objects.packReused = asNumber(packReused); + } + ) + ]; + } +}); + +// src/lib/parsers/parse-remote-messages.ts +function parseRemoteMessages(_stdOut, stdErr) { + return parseStringResponse({ remoteMessages: new RemoteMessageSummary() }, parsers2, stdErr); +} +var parsers2, RemoteMessageSummary; +var init_parse_remote_messages = __esm({ + "src/lib/parsers/parse-remote-messages.ts"() { + "use strict"; + init_utils(); + init_parse_remote_objects(); + parsers2 = [ + new RemoteLineParser(/^remote:\s*(.+)$/, (result, [text]) => { + result.remoteMessages.all.push(text.trim()); + return false; + }), + ...remoteMessagesObjectParsers, + new RemoteLineParser( + [/create a (?:pull|merge) request/i, /\s(https?:\/\/\S+)$/], + (result, [pullRequestUrl]) => { + result.remoteMessages.pullRequestUrl = pullRequestUrl; + } + ), + new RemoteLineParser( + [/found (\d+) vulnerabilities.+\(([^)]+)\)/i, /\s(https?:\/\/\S+)$/], + (result, [count, summary, url]) => { + result.remoteMessages.vulnerabilities = { + count: asNumber(count), + summary, + url + }; + } + ) + ]; + RemoteMessageSummary = class { + constructor() { + this.all = []; + } + }; + } +}); + +// src/lib/parsers/parse-pull.ts +function parsePullErrorResult(stdOut, stdErr) { + const pullError = parseStringResponse(new PullFailedSummary(), errorParsers, [stdOut, stdErr]); + return pullError.message && pullError; +} +var FILE_UPDATE_REGEX, SUMMARY_REGEX, ACTION_REGEX, parsers3, errorParsers, parsePullDetail, parsePullResult; +var init_parse_pull = __esm({ + "src/lib/parsers/parse-pull.ts"() { + "use strict"; + init_PullSummary(); + init_utils(); + init_parse_remote_messages(); + FILE_UPDATE_REGEX = /^\s*(.+?)\s+\|\s+\d+\s*(\+*)(-*)/; + SUMMARY_REGEX = /(\d+)\D+((\d+)\D+\(\+\))?(\D+(\d+)\D+\(-\))?/; + ACTION_REGEX = /^(create|delete) mode \d+ (.+)/; + parsers3 = [ + new LineParser(FILE_UPDATE_REGEX, (result, [file, insertions, deletions]) => { + result.files.push(file); + if (insertions) { + result.insertions[file] = insertions.length; + } + if (deletions) { + result.deletions[file] = deletions.length; + } + }), + new LineParser(SUMMARY_REGEX, (result, [changes, , insertions, , deletions]) => { + if (insertions !== void 0 || deletions !== void 0) { + result.summary.changes = +changes || 0; + result.summary.insertions = +insertions || 0; + result.summary.deletions = +deletions || 0; + return true; + } + return false; + }), + new LineParser(ACTION_REGEX, (result, [action, file]) => { + append(result.files, file); + append(action === "create" ? result.created : result.deleted, file); + }) + ]; + errorParsers = [ + new LineParser(/^from\s(.+)$/i, (result, [remote]) => void (result.remote = remote)), + new LineParser(/^fatal:\s(.+)$/, (result, [message]) => void (result.message = message)), + new LineParser( + /([a-z0-9]+)\.\.([a-z0-9]+)\s+(\S+)\s+->\s+(\S+)$/, + (result, [hashLocal, hashRemote, branchLocal, branchRemote]) => { + result.branch.local = branchLocal; + result.hash.local = hashLocal; + result.branch.remote = branchRemote; + result.hash.remote = hashRemote; + } + ) + ]; + parsePullDetail = (stdOut, stdErr) => { + return parseStringResponse(new PullSummary(), parsers3, [stdOut, stdErr]); + }; + parsePullResult = (stdOut, stdErr) => { + return Object.assign( + new PullSummary(), + parsePullDetail(stdOut, stdErr), + parseRemoteMessages(stdOut, stdErr) + ); + }; + } +}); + +// src/lib/parsers/parse-merge.ts +var parsers4, parseMergeResult, parseMergeDetail; +var init_parse_merge = __esm({ + "src/lib/parsers/parse-merge.ts"() { + "use strict"; + init_MergeSummary(); + init_utils(); + init_parse_pull(); + parsers4 = [ + new LineParser(/^Auto-merging\s+(.+)$/, (summary, [autoMerge]) => { + summary.merges.push(autoMerge); + }), + new LineParser(/^CONFLICT\s+\((.+)\): Merge conflict in (.+)$/, (summary, [reason, file]) => { + summary.conflicts.push(new MergeSummaryConflict(reason, file)); + }), + new LineParser( + /^CONFLICT\s+\((.+\/delete)\): (.+) deleted in (.+) and/, + (summary, [reason, file, deleteRef]) => { + summary.conflicts.push(new MergeSummaryConflict(reason, file, { deleteRef })); + } + ), + new LineParser(/^CONFLICT\s+\((.+)\):/, (summary, [reason]) => { + summary.conflicts.push(new MergeSummaryConflict(reason, null)); + }), + new LineParser(/^Automatic merge failed;\s+(.+)$/, (summary, [result]) => { + summary.result = result; + }) + ]; + parseMergeResult = (stdOut, stdErr) => { + return Object.assign(parseMergeDetail(stdOut, stdErr), parsePullResult(stdOut, stdErr)); + }; + parseMergeDetail = (stdOut) => { + return parseStringResponse(new MergeSummaryDetail(), parsers4, stdOut); + }; + } +}); + +// src/lib/tasks/merge.ts +function mergeTask(customArgs) { + if (!customArgs.length) { + return configurationErrorTask("Git.merge requires at least one option"); + } + return { + commands: ["merge", ...customArgs], + format: "utf-8", + parser(stdOut, stdErr) { + const merge = parseMergeResult(stdOut, stdErr); + if (merge.failed) { + throw new GitResponseError(merge); + } + return merge; + } + }; +} +var init_merge = __esm({ + "src/lib/tasks/merge.ts"() { + "use strict"; + init_git_response_error(); + init_parse_merge(); + init_task(); + } +}); + +// src/lib/parsers/parse-push.ts +function pushResultPushedItem(local, remote, status) { + const deleted = status.includes("deleted"); + const tag = status.includes("tag") || /^refs\/tags/.test(local); + const alreadyUpdated = !status.includes("new"); + return { + deleted, + tag, + branch: !tag, + new: !alreadyUpdated, + alreadyUpdated, + local, + remote + }; +} +var parsers5, parsePushResult, parsePushDetail; +var init_parse_push = __esm({ + "src/lib/parsers/parse-push.ts"() { + "use strict"; + init_utils(); + init_parse_remote_messages(); + parsers5 = [ + new LineParser(/^Pushing to (.+)$/, (result, [repo]) => { + result.repo = repo; + }), + new LineParser(/^updating local tracking ref '(.+)'/, (result, [local]) => { + result.ref = __spreadProps(__spreadValues({}, result.ref || {}), { + local + }); + }), + new LineParser(/^[=*-]\s+([^:]+):(\S+)\s+\[(.+)]$/, (result, [local, remote, type]) => { + result.pushed.push(pushResultPushedItem(local, remote, type)); + }), + new LineParser( + /^Branch '([^']+)' set up to track remote branch '([^']+)' from '([^']+)'/, + (result, [local, remote, remoteName]) => { + result.branch = __spreadProps(__spreadValues({}, result.branch || {}), { + local, + remote, + remoteName + }); + } + ), + new LineParser( + /^([^:]+):(\S+)\s+([a-z0-9]+)\.\.([a-z0-9]+)$/, + (result, [local, remote, from, to]) => { + result.update = { + head: { + local, + remote + }, + hash: { + from, + to + } + }; + } + ) + ]; + parsePushResult = (stdOut, stdErr) => { + const pushDetail = parsePushDetail(stdOut, stdErr); + const responseDetail = parseRemoteMessages(stdOut, stdErr); + return __spreadValues(__spreadValues({}, pushDetail), responseDetail); + }; + parsePushDetail = (stdOut, stdErr) => { + return parseStringResponse({ pushed: [] }, parsers5, [stdOut, stdErr]); + }; + } +}); + +// src/lib/tasks/push.ts +var push_exports = {}; +__export(push_exports, { + pushTagsTask: () => pushTagsTask, + pushTask: () => pushTask +}); +function pushTagsTask(ref = {}, customArgs) { + append(customArgs, "--tags"); + return pushTask(ref, customArgs); +} +function pushTask(ref = {}, customArgs) { + const commands = ["push", ...customArgs]; + if (ref.branch) { + commands.splice(1, 0, ref.branch); + } + if (ref.remote) { + commands.splice(1, 0, ref.remote); + } + remove(commands, "-v"); + append(commands, "--verbose"); + append(commands, "--porcelain"); + return { + commands, + format: "utf-8", + parser: parsePushResult + }; +} +var init_push = __esm({ + "src/lib/tasks/push.ts"() { + "use strict"; + init_parse_push(); + init_utils(); + } +}); + +// src/lib/tasks/show.ts +function show_default() { + return { + showBuffer() { + const commands = ["show", ...getTrailingOptions(arguments, 1)]; + if (!commands.includes("--binary")) { + commands.splice(1, 0, "--binary"); + } + return this._runTask( + straightThroughBufferTask(commands), + trailingFunctionArgument(arguments) + ); + }, + show() { + const commands = ["show", ...getTrailingOptions(arguments, 1)]; + return this._runTask( + straightThroughStringTask(commands), + trailingFunctionArgument(arguments) + ); + } + }; +} +var init_show = __esm({ + "src/lib/tasks/show.ts"() { + "use strict"; + init_utils(); + init_task(); + } +}); + +// src/lib/responses/FileStatusSummary.ts +var fromPathRegex, FileStatusSummary; +var init_FileStatusSummary = __esm({ + "src/lib/responses/FileStatusSummary.ts"() { + "use strict"; + fromPathRegex = /^(.+) -> (.+)$/; + FileStatusSummary = class { + constructor(path, index, working_dir) { + this.path = path; + this.index = index; + this.working_dir = working_dir; + if ("R" === index + working_dir) { + const detail = fromPathRegex.exec(path) || [null, path, path]; + this.from = detail[1] || ""; + this.path = detail[2] || ""; + } + } + }; + } +}); + +// src/lib/responses/StatusSummary.ts +function renamedFile(line) { + const [to, from] = line.split(NULL); + return { + from: from || to, + to + }; +} +function parser2(indexX, indexY, handler) { + return [`${indexX}${indexY}`, handler]; +} +function conflicts(indexX, ...indexY) { + return indexY.map((y) => parser2(indexX, y, (result, file) => append(result.conflicted, file))); +} +function splitLine(result, lineStr) { + const trimmed2 = lineStr.trim(); + switch (" ") { + case trimmed2.charAt(2): + return data(trimmed2.charAt(0), trimmed2.charAt(1), trimmed2.substr(3)); + case trimmed2.charAt(1): + return data(" " /* NONE */, trimmed2.charAt(0), trimmed2.substr(2)); + default: + return; + } + function data(index, workingDir, path) { + const raw = `${index}${workingDir}`; + const handler = parsers6.get(raw); + if (handler) { + handler(result, path); + } + if (raw !== "##" && raw !== "!!") { + result.files.push(new FileStatusSummary(path.replace(/\0.+$/, ""), index, workingDir)); + } + } +} +var StatusSummary, parsers6, parseStatusSummary; +var init_StatusSummary = __esm({ + "src/lib/responses/StatusSummary.ts"() { + "use strict"; + init_utils(); + init_FileStatusSummary(); + StatusSummary = class { + constructor() { + this.not_added = []; + this.conflicted = []; + this.created = []; + this.deleted = []; + this.ignored = void 0; + this.modified = []; + this.renamed = []; + this.files = []; + this.staged = []; + this.ahead = 0; + this.behind = 0; + this.current = null; + this.tracking = null; + this.detached = false; + this.isClean = () => { + return !this.files.length; + }; + } + }; + parsers6 = new Map([ + parser2( + " " /* NONE */, + "A" /* ADDED */, + (result, file) => append(result.created, file) + ), + parser2( + " " /* NONE */, + "D" /* DELETED */, + (result, file) => append(result.deleted, file) + ), + parser2( + " " /* NONE */, + "M" /* MODIFIED */, + (result, file) => append(result.modified, file) + ), + parser2( + "A" /* ADDED */, + " " /* NONE */, + (result, file) => append(result.created, file) && append(result.staged, file) + ), + parser2( + "A" /* ADDED */, + "M" /* MODIFIED */, + (result, file) => append(result.created, file) && append(result.staged, file) && append(result.modified, file) + ), + parser2( + "D" /* DELETED */, + " " /* NONE */, + (result, file) => append(result.deleted, file) && append(result.staged, file) + ), + parser2( + "M" /* MODIFIED */, + " " /* NONE */, + (result, file) => append(result.modified, file) && append(result.staged, file) + ), + parser2( + "M" /* MODIFIED */, + "M" /* MODIFIED */, + (result, file) => append(result.modified, file) && append(result.staged, file) + ), + parser2("R" /* RENAMED */, " " /* NONE */, (result, file) => { + append(result.renamed, renamedFile(file)); + }), + parser2("R" /* RENAMED */, "M" /* MODIFIED */, (result, file) => { + const renamed = renamedFile(file); + append(result.renamed, renamed); + append(result.modified, renamed.to); + }), + parser2("!" /* IGNORED */, "!" /* IGNORED */, (_result, _file) => { + append(_result.ignored = _result.ignored || [], _file); + }), + parser2( + "?" /* UNTRACKED */, + "?" /* UNTRACKED */, + (result, file) => append(result.not_added, file) + ), + ...conflicts("A" /* ADDED */, "A" /* ADDED */, "U" /* UNMERGED */), + ...conflicts( + "D" /* DELETED */, + "D" /* DELETED */, + "U" /* UNMERGED */ + ), + ...conflicts( + "U" /* UNMERGED */, + "A" /* ADDED */, + "D" /* DELETED */, + "U" /* UNMERGED */ + ), + [ + "##", + (result, line) => { + const aheadReg = /ahead (\d+)/; + const behindReg = /behind (\d+)/; + const currentReg = /^(.+?(?=(?:\.{3}|\s|$)))/; + const trackingReg = /\.{3}(\S*)/; + const onEmptyBranchReg = /\son\s([\S]+)$/; + let regexResult; + regexResult = aheadReg.exec(line); + result.ahead = regexResult && +regexResult[1] || 0; + regexResult = behindReg.exec(line); + result.behind = regexResult && +regexResult[1] || 0; + regexResult = currentReg.exec(line); + result.current = regexResult && regexResult[1]; + regexResult = trackingReg.exec(line); + result.tracking = regexResult && regexResult[1]; + regexResult = onEmptyBranchReg.exec(line); + result.current = regexResult && regexResult[1] || result.current; + result.detached = /\(no branch\)/.test(line); + } + ] + ]); + parseStatusSummary = function(text) { + const lines = text.split(NULL); + const status = new StatusSummary(); + for (let i = 0, l = lines.length; i < l; ) { + let line = lines[i++].trim(); + if (!line) { + continue; + } + if (line.charAt(0) === "R" /* RENAMED */) { + line += NULL + (lines[i++] || ""); + } + splitLine(status, line); + } + return status; + }; + } +}); + +// src/lib/tasks/status.ts +function statusTask(customArgs) { + const commands = [ + "status", + "--porcelain", + "-b", + "-u", + "--null", + ...customArgs.filter((arg) => !ignoredOptions.includes(arg)) + ]; + return { + format: "utf-8", + commands, + parser(text) { + return parseStatusSummary(text); + } + }; +} +var ignoredOptions; +var init_status = __esm({ + "src/lib/tasks/status.ts"() { + "use strict"; + init_StatusSummary(); + ignoredOptions = ["--null", "-z"]; + } +}); + +// src/lib/tasks/version.ts +function versionResponse(major = 0, minor = 0, patch = 0, agent = "", installed = true) { + return Object.defineProperty( + { + major, + minor, + patch, + agent, + installed + }, + "toString", + { + value() { + return `${this.major}.${this.minor}.${this.patch}`; + }, + configurable: false, + enumerable: false + } + ); +} +function notInstalledResponse() { + return versionResponse(0, 0, 0, "", false); +} +function version_default() { + return { + version() { + return this._runTask({ + commands: ["--version"], + format: "utf-8", + parser: versionParser, + onError(result, error, done, fail) { + if (result.exitCode === -2 /* NOT_FOUND */) { + return done(Buffer.from(NOT_INSTALLED)); + } + fail(error); + } + }); + } + }; +} +function versionParser(stdOut) { + if (stdOut === NOT_INSTALLED) { + return notInstalledResponse(); + } + return parseStringResponse(versionResponse(0, 0, 0, stdOut), parsers7, stdOut); +} +var NOT_INSTALLED, parsers7; +var init_version = __esm({ + "src/lib/tasks/version.ts"() { + "use strict"; + init_utils(); + NOT_INSTALLED = "installed=false"; + parsers7 = [ + new LineParser( + /version (\d+)\.(\d+)\.(\d+)(?:\s*\((.+)\))?/, + (result, [major, minor, patch, agent = ""]) => { + Object.assign( + result, + versionResponse(asNumber(major), asNumber(minor), asNumber(patch), agent) + ); + } + ), + new LineParser( + /version (\d+)\.(\d+)\.(\D+)(.+)?$/, + (result, [major, minor, patch, agent = ""]) => { + Object.assign(result, versionResponse(asNumber(major), asNumber(minor), patch, agent)); + } + ) + ]; + } +}); + +// src/lib/simple-git-api.ts +var simple_git_api_exports = {}; +__export(simple_git_api_exports, { + SimpleGitApi: () => SimpleGitApi +}); +var SimpleGitApi; +var init_simple_git_api = __esm({ + "src/lib/simple-git-api.ts"() { + "use strict"; + init_task_callback(); + init_change_working_directory(); + init_checkout(); + init_commit(); + init_config(); + init_first_commit(); + init_grep(); + init_hash_object(); + init_init(); + init_log(); + init_merge(); + init_push(); + init_show(); + init_status(); + init_task(); + init_version(); + init_utils(); + SimpleGitApi = class { + constructor(_executor) { + this._executor = _executor; + } + _runTask(task, then) { + const chain = this._executor.chain(); + const promise = chain.push(task); + if (then) { + taskCallback(task, promise, then); + } + return Object.create(this, { + then: { value: promise.then.bind(promise) }, + catch: { value: promise.catch.bind(promise) }, + _executor: { value: chain } + }); + } + add(files) { + return this._runTask( + straightThroughStringTask(["add", ...asArray(files)]), + trailingFunctionArgument(arguments) + ); + } + cwd(directory) { + const next = trailingFunctionArgument(arguments); + if (typeof directory === "string") { + return this._runTask(changeWorkingDirectoryTask(directory, this._executor), next); + } + if (typeof (directory == null ? void 0 : directory.path) === "string") { + return this._runTask( + changeWorkingDirectoryTask( + directory.path, + directory.root && this._executor || void 0 + ), + next + ); + } + return this._runTask( + configurationErrorTask("Git.cwd: workingDirectory must be supplied as a string"), + next + ); + } + hashObject(path, write) { + return this._runTask( + hashObjectTask(path, write === true), + trailingFunctionArgument(arguments) + ); + } + init(bare) { + return this._runTask( + initTask(bare === true, this._executor.cwd, getTrailingOptions(arguments)), + trailingFunctionArgument(arguments) + ); + } + merge() { + return this._runTask( + mergeTask(getTrailingOptions(arguments)), + trailingFunctionArgument(arguments) + ); + } + mergeFromTo(remote, branch) { + if (!(filterString(remote) && filterString(branch))) { + return this._runTask( + configurationErrorTask( + `Git.mergeFromTo requires that the 'remote' and 'branch' arguments are supplied as strings` + ) + ); + } + return this._runTask( + mergeTask([remote, branch, ...getTrailingOptions(arguments)]), + trailingFunctionArgument(arguments, false) + ); + } + outputHandler(handler) { + this._executor.outputHandler = handler; + return this; + } + push() { + const task = pushTask( + { + remote: filterType(arguments[0], filterString), + branch: filterType(arguments[1], filterString) + }, + getTrailingOptions(arguments) + ); + return this._runTask(task, trailingFunctionArgument(arguments)); + } + stash() { + return this._runTask( + straightThroughStringTask(["stash", ...getTrailingOptions(arguments)]), + trailingFunctionArgument(arguments) + ); + } + status() { + return this._runTask( + statusTask(getTrailingOptions(arguments)), + trailingFunctionArgument(arguments) + ); + } + }; + Object.assign( + SimpleGitApi.prototype, + checkout_default(), + commit_default(), + config_default(), + first_commit_default(), + grep_default(), + log_default(), + show_default(), + version_default() + ); + } +}); + +// src/lib/runners/scheduler.ts +var scheduler_exports = {}; +__export(scheduler_exports, { + Scheduler: () => Scheduler +}); +var import_promise_deferred2, createScheduledTask, Scheduler; +var init_scheduler = __esm({ + "src/lib/runners/scheduler.ts"() { + "use strict"; + init_utils(); + import_promise_deferred2 = __nccwpck_require__(49819); + init_git_logger(); + createScheduledTask = (() => { + let id = 0; + return () => { + id++; + const { promise, done } = (0, import_promise_deferred2.createDeferred)(); + return { + promise, + done, + id + }; + }; + })(); + Scheduler = class { + constructor(concurrency = 2) { + this.concurrency = concurrency; + this.logger = createLogger("", "scheduler"); + this.pending = []; + this.running = []; + this.logger(`Constructed, concurrency=%s`, concurrency); + } + schedule() { + if (!this.pending.length || this.running.length >= this.concurrency) { + this.logger( + `Schedule attempt ignored, pending=%s running=%s concurrency=%s`, + this.pending.length, + this.running.length, + this.concurrency + ); + return; + } + const task = append(this.running, this.pending.shift()); + this.logger(`Attempting id=%s`, task.id); + task.done(() => { + this.logger(`Completing id=`, task.id); + remove(this.running, task); + this.schedule(); + }); + } + next() { + const { promise, id } = append(this.pending, createScheduledTask()); + this.logger(`Scheduling id=%s`, id); + this.schedule(); + return promise; + } + }; + } +}); + +// src/lib/tasks/apply-patch.ts +var apply_patch_exports = {}; +__export(apply_patch_exports, { + applyPatchTask: () => applyPatchTask +}); +function applyPatchTask(patches, customArgs) { + return straightThroughStringTask(["apply", ...customArgs, ...patches]); +} +var init_apply_patch = __esm({ + "src/lib/tasks/apply-patch.ts"() { + "use strict"; + init_task(); + } +}); + +// src/lib/responses/BranchDeleteSummary.ts +function branchDeletionSuccess(branch, hash) { + return { + branch, + hash, + success: true + }; +} +function branchDeletionFailure(branch) { + return { + branch, + hash: null, + success: false + }; +} +var BranchDeletionBatch; +var init_BranchDeleteSummary = __esm({ + "src/lib/responses/BranchDeleteSummary.ts"() { + "use strict"; + BranchDeletionBatch = class { + constructor() { + this.all = []; + this.branches = {}; + this.errors = []; + } + get success() { + return !this.errors.length; + } + }; + } +}); + +// src/lib/parsers/parse-branch-delete.ts +function hasBranchDeletionError(data, processExitCode) { + return processExitCode === 1 /* ERROR */ && deleteErrorRegex.test(data); +} +var deleteSuccessRegex, deleteErrorRegex, parsers8, parseBranchDeletions; +var init_parse_branch_delete = __esm({ + "src/lib/parsers/parse-branch-delete.ts"() { + "use strict"; + init_BranchDeleteSummary(); + init_utils(); + deleteSuccessRegex = /(\S+)\s+\(\S+\s([^)]+)\)/; + deleteErrorRegex = /^error[^']+'([^']+)'/m; + parsers8 = [ + new LineParser(deleteSuccessRegex, (result, [branch, hash]) => { + const deletion = branchDeletionSuccess(branch, hash); + result.all.push(deletion); + result.branches[branch] = deletion; + }), + new LineParser(deleteErrorRegex, (result, [branch]) => { + const deletion = branchDeletionFailure(branch); + result.errors.push(deletion); + result.all.push(deletion); + result.branches[branch] = deletion; + }) + ]; + parseBranchDeletions = (stdOut, stdErr) => { + return parseStringResponse(new BranchDeletionBatch(), parsers8, [stdOut, stdErr]); + }; + } +}); + +// src/lib/responses/BranchSummary.ts +var BranchSummaryResult; +var init_BranchSummary = __esm({ + "src/lib/responses/BranchSummary.ts"() { + "use strict"; + BranchSummaryResult = class { + constructor() { + this.all = []; + this.branches = {}; + this.current = ""; + this.detached = false; + } + push(status, detached, name, commit, label) { + if (status === "*" /* CURRENT */) { + this.detached = detached; + this.current = name; + } + this.all.push(name); + this.branches[name] = { + current: status === "*" /* CURRENT */, + linkedWorkTree: status === "+" /* LINKED */, + name, + commit, + label + }; + } + }; + } +}); + +// src/lib/parsers/parse-branch.ts +function branchStatus(input) { + return input ? input.charAt(0) : ""; +} +function parseBranchSummary(stdOut) { + return parseStringResponse(new BranchSummaryResult(), parsers9, stdOut); +} +var parsers9; +var init_parse_branch = __esm({ + "src/lib/parsers/parse-branch.ts"() { + "use strict"; + init_BranchSummary(); + init_utils(); + parsers9 = [ + new LineParser( + /^([*+]\s)?\((?:HEAD )?detached (?:from|at) (\S+)\)\s+([a-z0-9]+)\s(.*)$/, + (result, [current, name, commit, label]) => { + result.push(branchStatus(current), true, name, commit, label); + } + ), + new LineParser( + new RegExp("^([*+]\\s)?(\\S+)\\s+([a-z0-9]+)\\s?(.*)$", "s"), + (result, [current, name, commit, label]) => { + result.push(branchStatus(current), false, name, commit, label); + } + ) + ]; + } +}); + +// src/lib/tasks/branch.ts +var branch_exports = {}; +__export(branch_exports, { + branchLocalTask: () => branchLocalTask, + branchTask: () => branchTask, + containsDeleteBranchCommand: () => containsDeleteBranchCommand, + deleteBranchTask: () => deleteBranchTask, + deleteBranchesTask: () => deleteBranchesTask +}); +function containsDeleteBranchCommand(commands) { + const deleteCommands = ["-d", "-D", "--delete"]; + return commands.some((command) => deleteCommands.includes(command)); +} +function branchTask(customArgs) { + const isDelete = containsDeleteBranchCommand(customArgs); + const commands = ["branch", ...customArgs]; + if (commands.length === 1) { + commands.push("-a"); + } + if (!commands.includes("-v")) { + commands.splice(1, 0, "-v"); + } + return { + format: "utf-8", + commands, + parser(stdOut, stdErr) { + if (isDelete) { + return parseBranchDeletions(stdOut, stdErr).all[0]; + } + return parseBranchSummary(stdOut); + } + }; +} +function branchLocalTask() { + const parser3 = parseBranchSummary; + return { + format: "utf-8", + commands: ["branch", "-v"], + parser: parser3 + }; +} +function deleteBranchesTask(branches, forceDelete = false) { + return { + format: "utf-8", + commands: ["branch", "-v", forceDelete ? "-D" : "-d", ...branches], + parser(stdOut, stdErr) { + return parseBranchDeletions(stdOut, stdErr); + }, + onError({ exitCode, stdOut }, error, done, fail) { + if (!hasBranchDeletionError(String(error), exitCode)) { + return fail(error); + } + done(stdOut); + } + }; +} +function deleteBranchTask(branch, forceDelete = false) { + const task = { + format: "utf-8", + commands: ["branch", "-v", forceDelete ? "-D" : "-d", branch], + parser(stdOut, stdErr) { + return parseBranchDeletions(stdOut, stdErr).branches[branch]; + }, + onError({ exitCode, stdErr, stdOut }, error, _, fail) { + if (!hasBranchDeletionError(String(error), exitCode)) { + return fail(error); + } + throw new GitResponseError( + task.parser(bufferToString(stdOut), bufferToString(stdErr)), + String(error) + ); + } + }; + return task; +} +var init_branch = __esm({ + "src/lib/tasks/branch.ts"() { + "use strict"; + init_git_response_error(); + init_parse_branch_delete(); + init_parse_branch(); + init_utils(); + } +}); + +// src/lib/responses/CheckIgnore.ts +var parseCheckIgnore; +var init_CheckIgnore = __esm({ + "src/lib/responses/CheckIgnore.ts"() { + "use strict"; + parseCheckIgnore = (text) => { + return text.split(/\n/g).map((line) => line.trim()).filter((file) => !!file); + }; + } +}); + +// src/lib/tasks/check-ignore.ts +var check_ignore_exports = {}; +__export(check_ignore_exports, { + checkIgnoreTask: () => checkIgnoreTask +}); +function checkIgnoreTask(paths) { + return { + commands: ["check-ignore", ...paths], + format: "utf-8", + parser: parseCheckIgnore + }; +} +var init_check_ignore = __esm({ + "src/lib/tasks/check-ignore.ts"() { + "use strict"; + init_CheckIgnore(); + } +}); + +// src/lib/tasks/clone.ts +var clone_exports = {}; +__export(clone_exports, { + cloneMirrorTask: () => cloneMirrorTask, + cloneTask: () => cloneTask +}); +function disallowedCommand(command) { + return /^--upload-pack(=|$)/.test(command); +} +function cloneTask(repo, directory, customArgs) { + const commands = ["clone", ...customArgs]; + filterString(repo) && commands.push(repo); + filterString(directory) && commands.push(directory); + const banned = commands.find(disallowedCommand); + if (banned) { + return configurationErrorTask(`git.fetch: potential exploit argument blocked.`); + } + return straightThroughStringTask(commands); +} +function cloneMirrorTask(repo, directory, customArgs) { + append(customArgs, "--mirror"); + return cloneTask(repo, directory, customArgs); +} +var init_clone = __esm({ + "src/lib/tasks/clone.ts"() { + "use strict"; + init_task(); + init_utils(); + } +}); + +// src/lib/parsers/parse-fetch.ts +function parseFetchResult(stdOut, stdErr) { + const result = { + raw: stdOut, + remote: null, + branches: [], + tags: [], + updated: [], + deleted: [] + }; + return parseStringResponse(result, parsers10, [stdOut, stdErr]); +} +var parsers10; +var init_parse_fetch = __esm({ + "src/lib/parsers/parse-fetch.ts"() { + "use strict"; + init_utils(); + parsers10 = [ + new LineParser(/From (.+)$/, (result, [remote]) => { + result.remote = remote; + }), + new LineParser(/\* \[new branch]\s+(\S+)\s*-> (.+)$/, (result, [name, tracking]) => { + result.branches.push({ + name, + tracking + }); + }), + new LineParser(/\* \[new tag]\s+(\S+)\s*-> (.+)$/, (result, [name, tracking]) => { + result.tags.push({ + name, + tracking + }); + }), + new LineParser(/- \[deleted]\s+\S+\s*-> (.+)$/, (result, [tracking]) => { + result.deleted.push({ + tracking + }); + }), + new LineParser( + /\s*([^.]+)\.\.(\S+)\s+(\S+)\s*-> (.+)$/, + (result, [from, to, name, tracking]) => { + result.updated.push({ + name, + tracking, + to, + from + }); + } + ) + ]; + } +}); + +// src/lib/tasks/fetch.ts +var fetch_exports = {}; +__export(fetch_exports, { + fetchTask: () => fetchTask +}); +function disallowedCommand2(command) { + return /^--upload-pack(=|$)/.test(command); +} +function fetchTask(remote, branch, customArgs) { + const commands = ["fetch", ...customArgs]; + if (remote && branch) { + commands.push(remote, branch); + } + const banned = commands.find(disallowedCommand2); + if (banned) { + return configurationErrorTask(`git.fetch: potential exploit argument blocked.`); + } + return { + commands, + format: "utf-8", + parser: parseFetchResult + }; +} +var init_fetch = __esm({ + "src/lib/tasks/fetch.ts"() { + "use strict"; + init_parse_fetch(); + init_task(); + } +}); + +// src/lib/parsers/parse-move.ts +function parseMoveResult(stdOut) { + return parseStringResponse({ moves: [] }, parsers11, stdOut); +} +var parsers11; +var init_parse_move = __esm({ + "src/lib/parsers/parse-move.ts"() { + "use strict"; + init_utils(); + parsers11 = [ + new LineParser(/^Renaming (.+) to (.+)$/, (result, [from, to]) => { + result.moves.push({ from, to }); + }) + ]; + } +}); + +// src/lib/tasks/move.ts +var move_exports = {}; +__export(move_exports, { + moveTask: () => moveTask +}); +function moveTask(from, to) { + return { + commands: ["mv", "-v", ...asArray(from), to], + format: "utf-8", + parser: parseMoveResult + }; +} +var init_move = __esm({ + "src/lib/tasks/move.ts"() { + "use strict"; + init_parse_move(); + init_utils(); + } +}); + +// src/lib/tasks/pull.ts +var pull_exports = {}; +__export(pull_exports, { + pullTask: () => pullTask +}); +function pullTask(remote, branch, customArgs) { + const commands = ["pull", ...customArgs]; + if (remote && branch) { + commands.splice(1, 0, remote, branch); + } + return { + commands, + format: "utf-8", + parser(stdOut, stdErr) { + return parsePullResult(stdOut, stdErr); + }, + onError(result, _error, _done, fail) { + const pullError = parsePullErrorResult( + bufferToString(result.stdOut), + bufferToString(result.stdErr) + ); + if (pullError) { + return fail(new GitResponseError(pullError)); + } + fail(_error); + } + }; +} +var init_pull = __esm({ + "src/lib/tasks/pull.ts"() { + "use strict"; + init_git_response_error(); + init_parse_pull(); + init_utils(); + } +}); + +// src/lib/responses/GetRemoteSummary.ts +function parseGetRemotes(text) { + const remotes = {}; + forEach(text, ([name]) => remotes[name] = { name }); + return Object.values(remotes); +} +function parseGetRemotesVerbose(text) { + const remotes = {}; + forEach(text, ([name, url, purpose]) => { + if (!remotes.hasOwnProperty(name)) { + remotes[name] = { + name, + refs: { fetch: "", push: "" } + }; + } + if (purpose && url) { + remotes[name].refs[purpose.replace(/[^a-z]/g, "")] = url; + } + }); + return Object.values(remotes); +} +function forEach(text, handler) { + forEachLineWithContent(text, (line) => handler(line.split(/\s+/))); +} +var init_GetRemoteSummary = __esm({ + "src/lib/responses/GetRemoteSummary.ts"() { + "use strict"; + init_utils(); + } +}); + +// src/lib/tasks/remote.ts +var remote_exports = {}; +__export(remote_exports, { + addRemoteTask: () => addRemoteTask, + getRemotesTask: () => getRemotesTask, + listRemotesTask: () => listRemotesTask, + remoteTask: () => remoteTask, + removeRemoteTask: () => removeRemoteTask +}); +function addRemoteTask(remoteName, remoteRepo, customArgs) { + return straightThroughStringTask(["remote", "add", ...customArgs, remoteName, remoteRepo]); +} +function getRemotesTask(verbose) { + const commands = ["remote"]; + if (verbose) { + commands.push("-v"); + } + return { + commands, + format: "utf-8", + parser: verbose ? parseGetRemotesVerbose : parseGetRemotes + }; +} +function listRemotesTask(customArgs) { + const commands = [...customArgs]; + if (commands[0] !== "ls-remote") { + commands.unshift("ls-remote"); + } + return straightThroughStringTask(commands); +} +function remoteTask(customArgs) { + const commands = [...customArgs]; + if (commands[0] !== "remote") { + commands.unshift("remote"); + } + return straightThroughStringTask(commands); +} +function removeRemoteTask(remoteName) { + return straightThroughStringTask(["remote", "remove", remoteName]); +} +var init_remote = __esm({ + "src/lib/tasks/remote.ts"() { + "use strict"; + init_GetRemoteSummary(); + init_task(); + } +}); + +// src/lib/tasks/stash-list.ts +var stash_list_exports = {}; +__export(stash_list_exports, { + stashListTask: () => stashListTask +}); +function stashListTask(opt = {}, customArgs) { + const options = parseLogOptions(opt); + const commands = ["stash", "list", ...options.commands, ...customArgs]; + const parser3 = createListLogSummaryParser( + options.splitter, + options.fields, + logFormatFromCommand(commands) + ); + return validateLogFormatConfig(commands) || { + commands, + format: "utf-8", + parser: parser3 + }; +} +var init_stash_list = __esm({ + "src/lib/tasks/stash-list.ts"() { + "use strict"; + init_log_format(); + init_parse_list_log_summary(); + init_diff(); + init_log(); + } +}); + +// src/lib/tasks/sub-module.ts +var sub_module_exports = {}; +__export(sub_module_exports, { + addSubModuleTask: () => addSubModuleTask, + initSubModuleTask: () => initSubModuleTask, + subModuleTask: () => subModuleTask, + updateSubModuleTask: () => updateSubModuleTask +}); +function addSubModuleTask(repo, path) { + return subModuleTask(["add", repo, path]); +} +function initSubModuleTask(customArgs) { + return subModuleTask(["init", ...customArgs]); +} +function subModuleTask(customArgs) { + const commands = [...customArgs]; + if (commands[0] !== "submodule") { + commands.unshift("submodule"); + } + return straightThroughStringTask(commands); +} +function updateSubModuleTask(customArgs) { + return subModuleTask(["update", ...customArgs]); +} +var init_sub_module = __esm({ + "src/lib/tasks/sub-module.ts"() { + "use strict"; + init_task(); + } +}); + +// src/lib/responses/TagList.ts +function singleSorted(a, b) { + const aIsNum = isNaN(a); + const bIsNum = isNaN(b); + if (aIsNum !== bIsNum) { + return aIsNum ? 1 : -1; + } + return aIsNum ? sorted(a, b) : 0; +} +function sorted(a, b) { + return a === b ? 0 : a > b ? 1 : -1; +} +function trimmed(input) { + return input.trim(); +} +function toNumber(input) { + if (typeof input === "string") { + return parseInt(input.replace(/^\D+/g, ""), 10) || 0; + } + return 0; +} +var TagList, parseTagList; +var init_TagList = __esm({ + "src/lib/responses/TagList.ts"() { + "use strict"; + TagList = class { + constructor(all, latest) { + this.all = all; + this.latest = latest; + } + }; + parseTagList = function(data, customSort = false) { + const tags = data.split("\n").map(trimmed).filter(Boolean); + if (!customSort) { + tags.sort(function(tagA, tagB) { + const partsA = tagA.split("."); + const partsB = tagB.split("."); + if (partsA.length === 1 || partsB.length === 1) { + return singleSorted(toNumber(partsA[0]), toNumber(partsB[0])); + } + for (let i = 0, l = Math.max(partsA.length, partsB.length); i < l; i++) { + const diff = sorted(toNumber(partsA[i]), toNumber(partsB[i])); + if (diff) { + return diff; + } + } + return 0; + }); + } + const latest = customSort ? tags[0] : [...tags].reverse().find((tag) => tag.indexOf(".") >= 0); + return new TagList(tags, latest); + }; + } +}); + +// src/lib/tasks/tag.ts +var tag_exports = {}; +__export(tag_exports, { + addAnnotatedTagTask: () => addAnnotatedTagTask, + addTagTask: () => addTagTask, + tagListTask: () => tagListTask +}); +function tagListTask(customArgs = []) { + const hasCustomSort = customArgs.some((option) => /^--sort=/.test(option)); + return { + format: "utf-8", + commands: ["tag", "-l", ...customArgs], + parser(text) { + return parseTagList(text, hasCustomSort); + } + }; +} +function addTagTask(name) { + return { + format: "utf-8", + commands: ["tag", name], + parser() { + return { name }; + } + }; +} +function addAnnotatedTagTask(name, tagMessage) { + return { + format: "utf-8", + commands: ["tag", "-a", "-m", tagMessage, name], + parser() { + return { name }; + } + }; +} +var init_tag = __esm({ + "src/lib/tasks/tag.ts"() { + "use strict"; + init_TagList(); + } +}); + +// src/git.js +var require_git = __commonJS({ + "src/git.js"(exports2, module2) { + "use strict"; + var { GitExecutor: GitExecutor2 } = (init_git_executor(), __toCommonJS(git_executor_exports)); + var { SimpleGitApi: SimpleGitApi2 } = (init_simple_git_api(), __toCommonJS(simple_git_api_exports)); + var { Scheduler: Scheduler2 } = (init_scheduler(), __toCommonJS(scheduler_exports)); + var { configurationErrorTask: configurationErrorTask2 } = (init_task(), __toCommonJS(task_exports)); + var { + asArray: asArray2, + filterArray: filterArray2, + filterPrimitives: filterPrimitives2, + filterString: filterString2, + filterStringOrStringArray: filterStringOrStringArray2, + filterType: filterType2, + getTrailingOptions: getTrailingOptions2, + trailingFunctionArgument: trailingFunctionArgument2, + trailingOptionsArgument: trailingOptionsArgument2 + } = (init_utils(), __toCommonJS(utils_exports)); + var { applyPatchTask: applyPatchTask2 } = (init_apply_patch(), __toCommonJS(apply_patch_exports)); + var { + branchTask: branchTask2, + branchLocalTask: branchLocalTask2, + deleteBranchesTask: deleteBranchesTask2, + deleteBranchTask: deleteBranchTask2 + } = (init_branch(), __toCommonJS(branch_exports)); + var { checkIgnoreTask: checkIgnoreTask2 } = (init_check_ignore(), __toCommonJS(check_ignore_exports)); + var { checkIsRepoTask: checkIsRepoTask2 } = (init_check_is_repo(), __toCommonJS(check_is_repo_exports)); + var { cloneTask: cloneTask2, cloneMirrorTask: cloneMirrorTask2 } = (init_clone(), __toCommonJS(clone_exports)); + var { cleanWithOptionsTask: cleanWithOptionsTask2, isCleanOptionsArray: isCleanOptionsArray2 } = (init_clean(), __toCommonJS(clean_exports)); + var { diffSummaryTask: diffSummaryTask2 } = (init_diff(), __toCommonJS(diff_exports)); + var { fetchTask: fetchTask2 } = (init_fetch(), __toCommonJS(fetch_exports)); + var { moveTask: moveTask2 } = (init_move(), __toCommonJS(move_exports)); + var { pullTask: pullTask2 } = (init_pull(), __toCommonJS(pull_exports)); + var { pushTagsTask: pushTagsTask2 } = (init_push(), __toCommonJS(push_exports)); + var { + addRemoteTask: addRemoteTask2, + getRemotesTask: getRemotesTask2, + listRemotesTask: listRemotesTask2, + remoteTask: remoteTask2, + removeRemoteTask: removeRemoteTask2 + } = (init_remote(), __toCommonJS(remote_exports)); + var { getResetMode: getResetMode2, resetTask: resetTask2 } = (init_reset(), __toCommonJS(reset_exports)); + var { stashListTask: stashListTask2 } = (init_stash_list(), __toCommonJS(stash_list_exports)); + var { + addSubModuleTask: addSubModuleTask2, + initSubModuleTask: initSubModuleTask2, + subModuleTask: subModuleTask2, + updateSubModuleTask: updateSubModuleTask2 + } = (init_sub_module(), __toCommonJS(sub_module_exports)); + var { addAnnotatedTagTask: addAnnotatedTagTask2, addTagTask: addTagTask2, tagListTask: tagListTask2 } = (init_tag(), __toCommonJS(tag_exports)); + var { straightThroughBufferTask: straightThroughBufferTask2, straightThroughStringTask: straightThroughStringTask2 } = (init_task(), __toCommonJS(task_exports)); + function Git2(options, plugins) { + this._plugins = plugins; + this._executor = new GitExecutor2( + options.baseDir, + new Scheduler2(options.maxConcurrentProcesses), + plugins + ); + this._trimmed = options.trimmed; + } + (Git2.prototype = Object.create(SimpleGitApi2.prototype)).constructor = Git2; + Git2.prototype.customBinary = function(command) { + this._plugins.reconfigure("binary", command); + return this; + }; + Git2.prototype.env = function(name, value) { + if (arguments.length === 1 && typeof name === "object") { + this._executor.env = name; + } else { + (this._executor.env = this._executor.env || {})[name] = value; + } + return this; + }; + Git2.prototype.stashList = function(options) { + return this._runTask( + stashListTask2( + trailingOptionsArgument2(arguments) || {}, + filterArray2(options) && options || [] + ), + trailingFunctionArgument2(arguments) + ); + }; + function createCloneTask(api, task, repoPath, localPath) { + if (typeof repoPath !== "string") { + return configurationErrorTask2(`git.${api}() requires a string 'repoPath'`); + } + return task(repoPath, filterType2(localPath, filterString2), getTrailingOptions2(arguments)); + } + Git2.prototype.clone = function() { + return this._runTask( + createCloneTask("clone", cloneTask2, ...arguments), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.mirror = function() { + return this._runTask( + createCloneTask("mirror", cloneMirrorTask2, ...arguments), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.mv = function(from, to) { + return this._runTask(moveTask2(from, to), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.checkoutLatestTag = function(then) { + var git = this; + return this.pull(function() { + git.tags(function(err, tags) { + git.checkout(tags.latest, then); + }); + }); + }; + Git2.prototype.pull = function(remote, branch, options, then) { + return this._runTask( + pullTask2( + filterType2(remote, filterString2), + filterType2(branch, filterString2), + getTrailingOptions2(arguments) + ), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.fetch = function(remote, branch) { + return this._runTask( + fetchTask2( + filterType2(remote, filterString2), + filterType2(branch, filterString2), + getTrailingOptions2(arguments) + ), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.silent = function(silence) { + console.warn( + "simple-git deprecation notice: git.silent: logging should be configured using the `debug` library / `DEBUG` environment variable, this will be an error in version 3" + ); + return this; + }; + Git2.prototype.tags = function(options, then) { + return this._runTask( + tagListTask2(getTrailingOptions2(arguments)), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.rebase = function() { + return this._runTask( + straightThroughStringTask2(["rebase", ...getTrailingOptions2(arguments)]), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.reset = function(mode) { + return this._runTask( + resetTask2(getResetMode2(mode), getTrailingOptions2(arguments)), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.revert = function(commit) { + const next = trailingFunctionArgument2(arguments); + if (typeof commit !== "string") { + return this._runTask(configurationErrorTask2("Commit must be a string"), next); + } + return this._runTask( + straightThroughStringTask2(["revert", ...getTrailingOptions2(arguments, 0, true), commit]), + next + ); + }; + Git2.prototype.addTag = function(name) { + const task = typeof name === "string" ? addTagTask2(name) : configurationErrorTask2("Git.addTag requires a tag name"); + return this._runTask(task, trailingFunctionArgument2(arguments)); + }; + Git2.prototype.addAnnotatedTag = function(tagName, tagMessage) { + return this._runTask( + addAnnotatedTagTask2(tagName, tagMessage), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.deleteLocalBranch = function(branchName, forceDelete, then) { + return this._runTask( + deleteBranchTask2(branchName, typeof forceDelete === "boolean" ? forceDelete : false), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.deleteLocalBranches = function(branchNames, forceDelete, then) { + return this._runTask( + deleteBranchesTask2(branchNames, typeof forceDelete === "boolean" ? forceDelete : false), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.branch = function(options, then) { + return this._runTask( + branchTask2(getTrailingOptions2(arguments)), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.branchLocal = function(then) { + return this._runTask(branchLocalTask2(), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.raw = function(commands) { + const createRestCommands = !Array.isArray(commands); + const command = [].slice.call(createRestCommands ? arguments : commands, 0); + for (let i = 0; i < command.length && createRestCommands; i++) { + if (!filterPrimitives2(command[i])) { + command.splice(i, command.length - i); + break; + } + } + command.push(...getTrailingOptions2(arguments, 0, true)); + var next = trailingFunctionArgument2(arguments); + if (!command.length) { + return this._runTask( + configurationErrorTask2("Raw: must supply one or more command to execute"), + next + ); + } + return this._runTask(straightThroughStringTask2(command, this._trimmed), next); + }; + Git2.prototype.submoduleAdd = function(repo, path, then) { + return this._runTask(addSubModuleTask2(repo, path), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.submoduleUpdate = function(args, then) { + return this._runTask( + updateSubModuleTask2(getTrailingOptions2(arguments, true)), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.submoduleInit = function(args, then) { + return this._runTask( + initSubModuleTask2(getTrailingOptions2(arguments, true)), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.subModule = function(options, then) { + return this._runTask( + subModuleTask2(getTrailingOptions2(arguments)), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.listRemote = function() { + return this._runTask( + listRemotesTask2(getTrailingOptions2(arguments)), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.addRemote = function(remoteName, remoteRepo, then) { + return this._runTask( + addRemoteTask2(remoteName, remoteRepo, getTrailingOptions2(arguments)), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.removeRemote = function(remoteName, then) { + return this._runTask(removeRemoteTask2(remoteName), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.getRemotes = function(verbose, then) { + return this._runTask(getRemotesTask2(verbose === true), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.remote = function(options, then) { + return this._runTask( + remoteTask2(getTrailingOptions2(arguments)), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.tag = function(options, then) { + const command = getTrailingOptions2(arguments); + if (command[0] !== "tag") { + command.unshift("tag"); + } + return this._runTask(straightThroughStringTask2(command), trailingFunctionArgument2(arguments)); + }; + Git2.prototype.updateServerInfo = function(then) { + return this._runTask( + straightThroughStringTask2(["update-server-info"]), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.pushTags = function(remote, then) { + const task = pushTagsTask2( + { remote: filterType2(remote, filterString2) }, + getTrailingOptions2(arguments) + ); + return this._runTask(task, trailingFunctionArgument2(arguments)); + }; + Git2.prototype.rm = function(files) { + return this._runTask( + straightThroughStringTask2(["rm", "-f", ...asArray2(files)]), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.rmKeepLocal = function(files) { + return this._runTask( + straightThroughStringTask2(["rm", "--cached", ...asArray2(files)]), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.catFile = function(options, then) { + return this._catFile("utf-8", arguments); + }; + Git2.prototype.binaryCatFile = function() { + return this._catFile("buffer", arguments); + }; + Git2.prototype._catFile = function(format, args) { + var handler = trailingFunctionArgument2(args); + var command = ["cat-file"]; + var options = args[0]; + if (typeof options === "string") { + return this._runTask( + configurationErrorTask2("Git.catFile: options must be supplied as an array of strings"), + handler + ); + } + if (Array.isArray(options)) { + command.push.apply(command, options); + } + const task = format === "buffer" ? straightThroughBufferTask2(command) : straightThroughStringTask2(command); + return this._runTask(task, handler); + }; + Git2.prototype.diff = function(options, then) { + const task = filterString2(options) ? configurationErrorTask2( + "git.diff: supplying options as a single string is no longer supported, switch to an array of strings" + ) : straightThroughStringTask2(["diff", ...getTrailingOptions2(arguments)]); + return this._runTask(task, trailingFunctionArgument2(arguments)); + }; + Git2.prototype.diffSummary = function() { + return this._runTask( + diffSummaryTask2(getTrailingOptions2(arguments, 1)), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.applyPatch = function(patches) { + const task = !filterStringOrStringArray2(patches) ? configurationErrorTask2( + `git.applyPatch requires one or more string patches as the first argument` + ) : applyPatchTask2(asArray2(patches), getTrailingOptions2([].slice.call(arguments, 1))); + return this._runTask(task, trailingFunctionArgument2(arguments)); + }; + Git2.prototype.revparse = function() { + const commands = ["rev-parse", ...getTrailingOptions2(arguments, true)]; + return this._runTask( + straightThroughStringTask2(commands, true), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.clean = function(mode, options, then) { + const usingCleanOptionsArray = isCleanOptionsArray2(mode); + const cleanMode = usingCleanOptionsArray && mode.join("") || filterType2(mode, filterString2) || ""; + const customArgs = getTrailingOptions2([].slice.call(arguments, usingCleanOptionsArray ? 1 : 0)); + return this._runTask( + cleanWithOptionsTask2(cleanMode, customArgs), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.exec = function(then) { + const task = { + commands: [], + format: "utf-8", + parser() { + if (typeof then === "function") { + then(); + } + } + }; + return this._runTask(task); + }; + Git2.prototype.clearQueue = function() { + return this; + }; + Git2.prototype.checkIgnore = function(pathnames, then) { + return this._runTask( + checkIgnoreTask2(asArray2(filterType2(pathnames, filterStringOrStringArray2, []))), + trailingFunctionArgument2(arguments) + ); + }; + Git2.prototype.checkIsRepo = function(checkType, then) { + return this._runTask( + checkIsRepoTask2(filterType2(checkType, filterString2)), + trailingFunctionArgument2(arguments) + ); + }; + module2.exports = Git2; + } +}); + +// src/lib/git-factory.ts +var git_factory_exports = {}; +__export(git_factory_exports, { + esModuleFactory: () => esModuleFactory, + gitExportFactory: () => gitExportFactory, + gitInstanceFactory: () => gitInstanceFactory +}); +function esModuleFactory(defaultExport) { + return Object.defineProperties(defaultExport, { + __esModule: { value: true }, + default: { value: defaultExport } + }); +} +function gitExportFactory(factory) { + return Object.assign(factory.bind(null), api_exports); +} +function gitInstanceFactory(baseDir, options) { + var _a2; + const plugins = new PluginStore(); + const config = createInstanceConfig( + baseDir && (typeof baseDir === "string" ? { baseDir } : baseDir) || {}, + options + ); + if (!folderExists(config.baseDir)) { + throw new GitConstructError( + config, + `Cannot use simple-git on a directory that does not exist` + ); + } + if (Array.isArray(config.config)) { + plugins.add(commandConfigPrefixingPlugin(config.config)); + } + plugins.add(blockUnsafeOperationsPlugin(config.unsafe)); + plugins.add(suffixPathsPlugin()); + plugins.add(completionDetectionPlugin(config.completion)); + config.abort && plugins.add(abortPlugin(config.abort)); + config.progress && plugins.add(progressMonitorPlugin(config.progress)); + config.timeout && plugins.add(timeoutPlugin(config.timeout)); + config.spawnOptions && plugins.add(spawnOptionsPlugin(config.spawnOptions)); + plugins.add(errorDetectionPlugin(errorDetectionHandler(true))); + config.errors && plugins.add(errorDetectionPlugin(config.errors)); + customBinaryPlugin(plugins, config.binary, (_a2 = config.unsafe) == null ? void 0 : _a2.allowUnsafeCustomBinary); + return new Git(config, plugins); +} +var Git; +var init_git_factory = __esm({ + "src/lib/git-factory.ts"() { + "use strict"; + init_api(); + init_plugins(); + init_suffix_paths_plugin(); + init_utils(); + Git = require_git(); + } +}); + +// src/lib/runners/promise-wrapped.ts +var promise_wrapped_exports = {}; +__export(promise_wrapped_exports, { + gitP: () => gitP +}); +function gitP(...args) { + let git; + let chain = Promise.resolve(); + try { + git = gitInstanceFactory(...args); + } catch (e) { + chain = Promise.reject(e); + } + function builderReturn() { + return promiseApi; + } + function chainReturn() { + return chain; + } + const promiseApi = [...functionNamesBuilderApi, ...functionNamesPromiseApi].reduce( + (api, name) => { + const isAsync = functionNamesPromiseApi.includes(name); + const valid = isAsync ? asyncWrapper(name, git) : syncWrapper(name, git, api); + const alternative = isAsync ? chainReturn : builderReturn; + Object.defineProperty(api, name, { + enumerable: false, + configurable: false, + value: git ? valid : alternative + }); + return api; + }, + {} + ); + return promiseApi; + function asyncWrapper(fn, git2) { + return function(...args2) { + if (typeof args2[args2.length] === "function") { + throw new TypeError( + "Promise interface requires that handlers are not supplied inline, trailing function not allowed in call to " + fn + ); + } + return chain.then(function() { + return new Promise(function(resolve, reject) { + const callback = (err, result) => { + if (err) { + return reject(toError(err)); + } + resolve(result); + }; + args2.push(callback); + git2[fn].apply(git2, args2); + }); + }); + }; + } + function syncWrapper(fn, git2, api) { + return (...args2) => { + git2[fn](...args2); + return api; + }; + } +} +function toError(error) { + if (error instanceof Error) { + return error; + } + if (typeof error === "string") { + return new Error(error); + } + return new GitResponseError(error); +} +var functionNamesBuilderApi, functionNamesPromiseApi; +var init_promise_wrapped = __esm({ + "src/lib/runners/promise-wrapped.ts"() { + "use strict"; + init_git_response_error(); + init_git_factory(); + functionNamesBuilderApi = ["customBinary", "env", "outputHandler", "silent"]; + functionNamesPromiseApi = [ + "add", + "addAnnotatedTag", + "addConfig", + "addRemote", + "addTag", + "applyPatch", + "binaryCatFile", + "branch", + "branchLocal", + "catFile", + "checkIgnore", + "checkIsRepo", + "checkout", + "checkoutBranch", + "checkoutLatestTag", + "checkoutLocalBranch", + "clean", + "clone", + "commit", + "cwd", + "deleteLocalBranch", + "deleteLocalBranches", + "diff", + "diffSummary", + "exec", + "fetch", + "getRemotes", + "init", + "listConfig", + "listRemote", + "log", + "merge", + "mergeFromTo", + "mirror", + "mv", + "pull", + "push", + "pushTags", + "raw", + "rebase", + "remote", + "removeRemote", + "reset", + "revert", + "revparse", + "rm", + "rmKeepLocal", + "show", + "stash", + "stashList", + "status", + "subModule", + "submoduleAdd", + "submoduleInit", + "submoduleUpdate", + "tag", + "tags", + "updateServerInfo" + ]; + } +}); + +// src/index.js +var { gitP: gitP2 } = (init_promise_wrapped(), __toCommonJS(promise_wrapped_exports)); +var { esModuleFactory: esModuleFactory2, gitInstanceFactory: gitInstanceFactory2, gitExportFactory: gitExportFactory2 } = (init_git_factory(), __toCommonJS(git_factory_exports)); +var simpleGit = esModuleFactory2(gitExportFactory2(gitInstanceFactory2)); +module.exports = Object.assign(simpleGit, { gitP: gitP2, simpleGit }); +//# sourceMappingURL=index.js.map + + /***/ }), /***/ 71062: @@ -99486,13 +104543,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.stageActionFiles = exports.readFileContents = exports.isDirectory = exports.createArchives = exports.createTempDir = void 0; +exports.ensureCorrectShaCheckedOut = exports.stageActionFiles = exports.readFileContents = exports.isDirectory = exports.createArchives = exports.createTempDir = void 0; const fs = __importStar(__nccwpck_require__(57147)); const fs_extra_1 = __importDefault(__nccwpck_require__(5630)); const path = __importStar(__nccwpck_require__(71017)); const tar = __importStar(__nccwpck_require__(74674)); const archiver = __importStar(__nccwpck_require__(43084)); const crypto = __importStar(__nccwpck_require__(6113)); +const simpleGit = __importStar(__nccwpck_require__(79103)); // Simple convenience around creating subdirectories in the same base temporary directory function createTempDir(tmpDirPath, subDirName) { const tempDir = path.join(tmpDirPath, subDirName); @@ -99574,6 +104632,21 @@ function stageActionFiles(actionDir, targetDir) { } } exports.stageActionFiles = stageActionFiles; +// Ensure the correct SHA is checked out for the tag by inspecting the git metadata in the workspace +// and comparing it to the information actions provided us. +// Provided ref should be in format refs/tags/. +async function ensureCorrectShaCheckedOut(tagRef, expectedSha, gitDir) { + const git = simpleGit.simpleGit(gitDir); + const tagCommitSha = await git.raw(['rev-parse', '--verify', tagRef]); + if (tagCommitSha.trim() !== expectedSha) { + throw new Error(`The commit associated with the tag ${tagRef} does not match the SHA of the commit provided by the actions context.`); + } + const currentlyCheckedOutSha = await git.revparse(['HEAD']); + if (currentlyCheckedOutSha.trim() !== expectedSha) { + throw new Error(`The expected commit associated with the tag ${tagRef} is not checked out.`); + } +} +exports.ensureCorrectShaCheckedOut = ensureCorrectShaCheckedOut; // Converts a file path to a filemetadata object by querying the fs for relevant metadata. async function fileMetadata(filePath) { const stats = fs.statSync(filePath); @@ -99800,7 +104873,7 @@ async function run() { const options = await cfg.resolvePublishActionOptions(); core.info(`Publishing action package version with options:`); core.info(cfg.serializeOptions(options)); - const semverTag = parseSemverTagFromRef(options.ref); + const semverTag = await parseSemverTagFromRef(options); const stagedActionFilesDir = fsHelper.createTempDir(options.runnerTempDir, 'staging'); fsHelper.stageActionFiles(options.workspaceDir, stagedActionFilesDir); const archiveDir = fsHelper.createTempDir(options.runnerTempDir, 'archives'); @@ -99828,7 +104901,8 @@ exports.run = run; // This action can be triggered by any workflow that specifies a tag as its GITHUB_REF. // This includes releases, creating or pushing tags, or workflow_dispatch. // See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#about-events-that-trigger-workflows. -function parseSemverTagFromRef(ref) { +async function parseSemverTagFromRef(opts) { + const ref = opts.ref; if (!ref.startsWith('refs/tags/')) { throw new Error(`The ref ${ref} is not a valid tag reference.`); } @@ -99837,6 +104911,8 @@ function parseSemverTagFromRef(ref) { if (!semverTag) { throw new Error(`${rawTag} is not a valid semantic version tag, and so cannot be uploaded to the action package.`); } + // Ensure the correct SHA is checked out for the tag we're parsing, otherwise the bundled content will be incorrect. + await fsHelper.ensureCorrectShaCheckedOut(ref, opts.sha, opts.workspaceDir); return semverTag; } // Generate an attestation using the actions toolkit @@ -99962,6 +105038,14 @@ module.exports = require("buffer"); /***/ }), +/***/ 32081: +/***/ ((module) => { + +"use strict"; +module.exports = require("child_process"); + +/***/ }), + /***/ 96206: /***/ ((module) => { diff --git a/dist/licenses.txt b/dist/licenses.txt index 040900c..449dcd4 100644 --- a/dist/licenses.txt +++ b/dist/licenses.txt @@ -82,6 +82,55 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +@kwsites/file-exists +MIT +The MIT License (MIT) + +Copyright (c) 2015 Steve King + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +@kwsites/promise-deferred +MIT +MIT License + +Copyright (c) 2018 kwsites + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + @npmcli/agent ISC @@ -3213,6 +3262,9 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +simple-git +MIT + smart-buffer MIT The MIT License (MIT) diff --git a/package-lock.json b/package-lock.json index db6030a..8cf4621 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@types/fs-extra": "^11.0.4", "archiver": "^6.0.1", "fs-extra": "^11.2.0", + "simple-git": "^3.22.0", "tar": "^6.2.0" }, "devDependencies": { @@ -1408,6 +1409,19 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "dependencies": { + "debug": "^4.1.1" + } + }, + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -7496,6 +7510,20 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, + "node_modules/simple-git": { + "version": "3.24.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.24.0.tgz", + "integrity": "sha512-QqAKee9Twv+3k8IFOFfPB2hnk6as6Y6ACUpwCtQvRYBAes23Wv3SZlHVobAzqcE8gfsisCvPw3HGW3HYM+VYYw==", + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.3.4" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", diff --git a/package.json b/package.json index a3c41c4..0a3c412 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,8 @@ "@types/fs-extra": "^11.0.4", "archiver": "^6.0.1", "fs-extra": "^11.2.0", - "tar": "^6.2.0" + "tar": "^6.2.0", + "simple-git": "^3.22.0" }, "devDependencies": { "@types/archiver": "^6.0.2", diff --git a/src/config.ts b/src/config.ts index 7d356cb..f3f7e53 100644 --- a/src/config.ts +++ b/src/config.ts @@ -8,8 +8,6 @@ export interface PublishActionOptions { nameWithOwner: string // The GitHub token to use for API requests token: string - // The commit SHA to reset back to after the action completes - sha: string // The base URL for the GitHub API apiBaseUrl: string // The base URL for the GitHub Container Registry @@ -30,6 +28,8 @@ export interface PublishActionOptions { event: string // The ref that triggered the action, associated with the event ref: string + // The commit SHA associated with the ref that triggered the action + sha: string } export async function resolvePublishActionOptions(): Promise { diff --git a/src/fs-helper.ts b/src/fs-helper.ts index 6ce0f35..78c6832 100644 --- a/src/fs-helper.ts +++ b/src/fs-helper.ts @@ -4,6 +4,7 @@ import * as path from 'path' import * as tar from 'tar' import * as archiver from 'archiver' import * as crypto from 'crypto' +import * as simpleGit from 'simple-git' export interface FileMetadata { path: string @@ -114,6 +115,31 @@ export function stageActionFiles(actionDir: string, targetDir: string): void { } } +// Ensure the correct SHA is checked out for the tag by inspecting the git metadata in the workspace +// and comparing it to the information actions provided us. +// Provided ref should be in format refs/tags/. +export async function ensureCorrectShaCheckedOut( + tagRef: string, + expectedSha: string, + gitDir: string +): Promise { + const git: simpleGit.SimpleGit = simpleGit.simpleGit(gitDir) + + const tagCommitSha = await git.raw(['rev-parse', '--verify', tagRef]) + if (tagCommitSha.trim() !== expectedSha) { + throw new Error( + `The commit associated with the tag ${tagRef} does not match the SHA of the commit provided by the actions context.` + ) + } + + const currentlyCheckedOutSha = await git.revparse(['HEAD']) + if (currentlyCheckedOutSha.trim() !== expectedSha) { + throw new Error( + `The expected commit associated with the tag ${tagRef} is not checked out.` + ) + } +} + // Converts a file path to a filemetadata object by querying the fs for relevant metadata. async function fileMetadata(filePath: string): Promise { const stats = fs.statSync(filePath) diff --git a/src/main.ts b/src/main.ts index af339f1..05462ec 100644 --- a/src/main.ts +++ b/src/main.ts @@ -18,7 +18,7 @@ export async function run(): Promise { core.info(`Publishing action package version with options:`) core.info(cfg.serializeOptions(options)) - const semverTag: semver.SemVer = parseSemverTagFromRef(options.ref) + const semverTag: semver.SemVer = await parseSemverTagFromRef(options) const stagedActionFilesDir = fsHelper.createTempDir( options.runnerTempDir, @@ -77,7 +77,11 @@ export async function run(): Promise { // This action can be triggered by any workflow that specifies a tag as its GITHUB_REF. // This includes releases, creating or pushing tags, or workflow_dispatch. // See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#about-events-that-trigger-workflows. -function parseSemverTagFromRef(ref: string): semver.SemVer { +async function parseSemverTagFromRef( + opts: cfg.PublishActionOptions +): Promise { + const ref = opts.ref + if (!ref.startsWith('refs/tags/')) { throw new Error(`The ref ${ref} is not a valid tag reference.`) } @@ -89,6 +93,10 @@ function parseSemverTagFromRef(ref: string): semver.SemVer { `${rawTag} is not a valid semantic version tag, and so cannot be uploaded to the action package.` ) } + + // Ensure the correct SHA is checked out for the tag we're parsing, otherwise the bundled content will be incorrect. + await fsHelper.ensureCorrectShaCheckedOut(ref, opts.sha, opts.workspaceDir) + return semverTag }