simple-git
Version:
Simple GIT interface for node.js
1,737 lines (1,705 loc) • 140 kB
JavaScript
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 __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 __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/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-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/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
import { exists, FOLDER } from "@kwsites/file-exists";
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 exists(path, 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 asCamelCase(str) {
return str.replace(/[\s-]+(.)/g, (_all, chr) => {
return chr.toUpperCase();
});
}
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 NULL, NOOP, objectToString;
var init_util = __esm({
"src/lib/utils/util.ts"() {
"use strict";
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(parser4, streams) {
return parser4(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,
asCamelCase: () => asCamelCase,
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(parser4) {
return {
commands: EMPTY_COMMANDS,
format: "empty",
parser: parser4
};
}
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/git-logger.ts
import debug from "debug";
function createLog() {
return debug("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 init_git_logger = __esm({
"src/lib/git-logger.ts"() {
"use strict";
init_utils();
debug.formatters.L = (value) => String(filterHasLength(value) ? value.length : "-");
debug.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
import { spawn } from "child_process";
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 GitExecutorChain;
var init_git_executor_chain = __esm({
"src/lib/runners/git-executor-chain.ts"() {
"use strict";
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 = 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/tasks/count-objects.ts
function countObjectsResponse() {
return {
count: 0,
garbage: 0,
inPack: 0,
packs: 0,
prunePackable: 0,
size: 0,
sizeGarbage: 0,
sizePack: 0
};
}
function count_objects_default() {
return {
countObjects() {
return this._runTask({
commands: ["count-objects", "--verbose"],
format: "utf-8",
parser(stdOut) {
return parseStringResponse(countObjectsResponse(), [parser2], stdOut);
}
});
}
};
}
var parser2;
var init_count_objects = __esm({
"src/lib/tasks/count-objects.ts"() {
"use strict";
init_utils();
parser2 = new LineParser(
/([a-z-]+): (\d+)$/,
(result, [key, value]) => {
const property = asCamelCase(key);
if (result.hasOwnProperty(property)) {
result[property] = asNumber(value);
}
}
);
}
});
// 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(
asArr