diff --git a/package-lock.json b/package-lock.json
index c9e56720ab..3a854864e4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12130,6 +12130,7 @@
"dependencies": {
"@pkgjs/parseargs": "^0.11.0",
"buffer": "^6.0.3",
+ "chalk": "^5.3.0",
"diff": "^5.2.0",
"isomorphic-git": "^1.25.10"
},
@@ -12165,6 +12166,18 @@
"ieee754": "^1.2.1"
}
},
+ "packages/git/node_modules/chalk": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+ "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
"packages/git/node_modules/diff": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
diff --git a/packages/git/package.json b/packages/git/package.json
index 9b52a8b782..e446dbf884 100644
--- a/packages/git/package.json
+++ b/packages/git/package.json
@@ -20,6 +20,7 @@
"dependencies": {
"@pkgjs/parseargs": "^0.11.0",
"buffer": "^6.0.3",
+ "chalk": "^5.3.0",
"diff": "^5.2.0",
"isomorphic-git": "^1.25.10"
}
diff --git a/packages/git/src/color.js b/packages/git/src/color.js
new file mode 100644
index 0000000000..24188b17b4
--- /dev/null
+++ b/packages/git/src/color.js
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2024 Puter Technologies Inc.
+ *
+ * This file is part of Puter's Git client.
+ *
+ * Puter's Git client is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+import chalk from 'chalk';
+
+export const color_options = {
+ 'color': {
+ // TODO: '--color[=]' syntax, once we have an args parser that supports optional string option-arguments.
+ description: 'Force colored output.',
+ type: 'boolean',
+ },
+ 'no-color': {
+ description: 'Disable colored output.',
+ type: 'boolean',
+ },
+}
+
+/**
+ * Process command-line options related to color, and modify them in place.
+ * Sets the chalk color level based on whether color is enabled or disabled.
+ * @param options Parsed command-line options, which will be modified in place.
+ */
+export const process_color_options = (options) => {
+
+ if (!options['color'] && !options['no-color']) {
+ // TODO: Default to whether we're running in a TTY, once we have that concept.
+ options['color'] = true;
+ }
+
+ if (options['no-color']) {
+ options['color'] = false;
+ delete options['no-color'];
+ }
+
+ chalk.level = options.color ? 3 : 0;
+}
diff --git a/packages/git/src/format.js b/packages/git/src/format.js
index da3d320af8..db9f2868c0 100644
--- a/packages/git/src/format.js
+++ b/packages/git/src/format.js
@@ -17,6 +17,7 @@
* along with this program. If not, see .
*/
import { shorten_hash } from './git-helpers.js';
+import chalk from 'chalk';
export const commit_formatting_options = {
'abbrev-commit': {
@@ -428,15 +429,15 @@ export const format_diffs = (diffs, options) => {
s += `+++ ${b_path}\n`;
for (const hunk of diff.hunks) {
- s += `\x1b[36;1m@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@\x1b[0m\n`;
+ s += chalk.blueBright(`@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@\n`);
for (const line of hunk.lines) {
switch (line[0]) {
case '+':
- s += `\x1b[32;1m${line}\x1b[0m\n`;
+ s += chalk.greenBright(`${line}\n`);
break;
case '-':
- s += `\x1b[31;1m${line}\x1b[0m\n`;
+ s += chalk.redBright(`${line}\n`);
break;
default:
s += `${line}\n`;
diff --git a/packages/git/src/subcommands/branch.js b/packages/git/src/subcommands/branch.js
index 3174d6b996..257db29985 100644
--- a/packages/git/src/subcommands/branch.js
+++ b/packages/git/src/subcommands/branch.js
@@ -19,6 +19,8 @@
import git from 'isomorphic-git';
import { find_repo_root, shorten_hash } from '../git-helpers.js';
import { SHOW_USAGE } from '../help.js';
+import { color_options, process_color_options } from '../color.js';
+import chalk from 'chalk';
const BRANCH = {
name: 'branch',
@@ -64,7 +66,8 @@ const BRANCH = {
description: 'Perform the action forcefully. For --delete, ignores whether the branches are fully merged. For --move, --copy, and creating new branches, ignores whether a branch already exists with that name.',
type: 'boolean',
short: 'f',
- }
+ },
+ ...color_options,
},
},
execute: async (ctx) => {
@@ -108,6 +111,8 @@ const BRANCH = {
}
}
+ process_color_options(options);
+
const { dir, gitdir } = await find_repo_root(fs, env.PWD);
const get_current_branch = async () => git.currentBranch({
@@ -266,7 +271,7 @@ const BRANCH = {
for (const branch of branches) {
if (branch === current_branch) {
- stdout(`\x1b[32;1m* ${branch}\x1b[0m`);
+ stdout(chalk.greenBright(`* ${branch}`));
} else {
stdout(` ${branch}`);
}
diff --git a/packages/git/src/subcommands/diff.js b/packages/git/src/subcommands/diff.js
index 88862c411c..0775de2021 100644
--- a/packages/git/src/subcommands/diff.js
+++ b/packages/git/src/subcommands/diff.js
@@ -23,6 +23,7 @@ import * as Diff from 'diff';
import path from 'path-browserify';
import { diff_formatting_options, format_diffs, process_diff_formatting_options } from '../format.js';
import { diff_git_trees } from '../diff.js';
+import { color_options, process_color_options } from '../color.js';
export default {
name: 'diff',
@@ -55,6 +56,7 @@ export default {
description: 'Compare files, ignoring git.',
type: 'boolean',
},
+ ...color_options,
},
},
execute: async (ctx) => {
@@ -63,6 +65,8 @@ export default {
const { options, positionals, tokens } = args;
const cache = {};
+ process_color_options(options);
+
const diff_options = process_diff_formatting_options(options);
if (diff_options.no_patch && !options['exit-code'])
return;
diff --git a/packages/git/src/subcommands/log.js b/packages/git/src/subcommands/log.js
index 470f8d8dcb..6ad523b1bd 100644
--- a/packages/git/src/subcommands/log.js
+++ b/packages/git/src/subcommands/log.js
@@ -28,6 +28,7 @@ import {
import path from 'path-browserify';
import { SHOW_USAGE } from '../help.js';
import { diff_git_trees } from '../diff.js';
+import { color_options, process_color_options } from '../color.js';
export default {
name: 'log',
@@ -39,6 +40,7 @@ export default {
options: {
...commit_formatting_options,
...diff_formatting_options,
+ ...color_options,
'max-count': {
description: 'Maximum number of commits to output.',
type: 'string',
@@ -54,6 +56,7 @@ export default {
process_commit_formatting_options(options);
const diff_options = process_diff_formatting_options(options, { show_patch_by_default: false });
+ process_color_options(options);
const depth = Number(options['max-count']) || undefined;
diff --git a/packages/git/src/subcommands/push.js b/packages/git/src/subcommands/push.js
index 30b862f9a7..fe0f30b12c 100644
--- a/packages/git/src/subcommands/push.js
+++ b/packages/git/src/subcommands/push.js
@@ -21,6 +21,8 @@ import http from 'isomorphic-git/http/web';
import { determine_fetch_remote, find_repo_root, shorten_hash } from '../git-helpers.js';
import { SHOW_USAGE } from '../help.js';
import { authentication_options, Authenticator } from '../auth.js';
+import { color_options, process_color_options } from '../color.js';
+import chalk from 'chalk';
export default {
name: 'push',
@@ -37,6 +39,7 @@ export default {
short: 'f',
},
...authentication_options,
+ ...color_options,
},
},
execute: async (ctx) => {
@@ -45,6 +48,8 @@ export default {
const { options, positionals } = args;
const cache = {};
+ process_color_options(options);
+
const { dir, gitdir } = await find_repo_root(fs, env.PWD);
const remotes = await git.listRemotes({
@@ -265,12 +270,13 @@ export default {
stdout(`To ${remote_url}`);
let any_failed = false;
for (const { flag, summary, source, dest, reason } of results) {
- stdout(`${flag === '!' ? '\x1b[31;1m' : ''} ${flag} ${summary.padEnd(19, ' ')}\x1b[0m ${source} -> ${dest}${reason ? ` (${reason})` : ''}`);
+ const flag_and_summary = `${flag} ${summary.padEnd(19, ' ')}`;
+ stdout(` ${ (flag === '!') ? chalk.redBright(flag_and_summary) : flag_and_summary } ${source} -> ${dest}${reason ? ` (${reason})` : ''}`);
if (reason)
any_failed = true;
}
if (any_failed) {
- stderr(`\x1b[31;1merror: Failed to push some refs to '${remote_url}'\x1b[0m`);
+ stderr(chalk.redBright(`error: Failed to push some refs to '${remote_url}'`));
}
},
};
diff --git a/packages/git/src/subcommands/show.js b/packages/git/src/subcommands/show.js
index b14c538894..a6bbdf13d9 100644
--- a/packages/git/src/subcommands/show.js
+++ b/packages/git/src/subcommands/show.js
@@ -28,6 +28,7 @@ import {
process_diff_formatting_options,
} from '../format.js';
import { diff_git_trees } from '../diff.js';
+import { color_options, process_color_options } from '../color.js';
export default {
name: 'show',
@@ -38,6 +39,7 @@ export default {
options: {
...commit_formatting_options,
...diff_formatting_options,
+ ...color_options,
},
},
execute: async (ctx) => {
@@ -47,6 +49,7 @@ export default {
process_commit_formatting_options(options);
const diff_options = process_diff_formatting_options(options);
+ process_color_options(options);
const { dir, gitdir } = await find_repo_root(fs, env.PWD);