Skip to content

Commit

Permalink
feat(git): Add --color and --no-color options
Browse files Browse the repository at this point in the history
These allow the user to force color on or off. The chalk library is used
for the output, because it's already used elsewhere in Puter and seems
like a good choice.

Ideally, the default will be based on whether stdout is a tty, but Puter
doesn't yet have that concept, so we just default to color.
  • Loading branch information
AtkinsSJ authored and KernelDeimos committed Jun 28, 2024
1 parent 364d580 commit d6dd1a5
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 7 deletions.
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/git/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
Expand Down
51 changes: 51 additions & 0 deletions packages/git/src/color.js
Original file line number Diff line number Diff line change
@@ -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 <https://www.gnu.org/licenses/>.
*/
import chalk from 'chalk';

export const color_options = {
'color': {
// TODO: '--color[=<when>]' 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;
}
7 changes: 4 additions & 3 deletions packages/git/src/format.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { shorten_hash } from './git-helpers.js';
import chalk from 'chalk';

export const commit_formatting_options = {
'abbrev-commit': {
Expand Down Expand Up @@ -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`;
Expand Down
9 changes: 7 additions & 2 deletions packages/git/src/subcommands/branch.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -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({
Expand Down Expand Up @@ -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}`);
}
Expand Down
4 changes: 4 additions & 0 deletions packages/git/src/subcommands/diff.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -55,6 +56,7 @@ export default {
description: 'Compare files, ignoring git.',
type: 'boolean',
},
...color_options,
},
},
execute: async (ctx) => {
Expand All @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions packages/git/src/subcommands/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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',
Expand All @@ -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;

Expand Down
10 changes: 8 additions & 2 deletions packages/git/src/subcommands/push.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -37,6 +39,7 @@ export default {
short: 'f',
},
...authentication_options,
...color_options,
},
},
execute: async (ctx) => {
Expand All @@ -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({
Expand Down Expand Up @@ -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}'`));
}
},
};
3 changes: 3 additions & 0 deletions packages/git/src/subcommands/show.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -38,6 +39,7 @@ export default {
options: {
...commit_formatting_options,
...diff_formatting_options,
...color_options,
},
},
execute: async (ctx) => {
Expand All @@ -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);

Expand Down

0 comments on commit d6dd1a5

Please sign in to comment.