diff --git a/packages/git/src/main.js b/packages/git/src/main.js index adb1f744b..dabbca422 100644 --- a/packages/git/src/main.js +++ b/packages/git/src/main.js @@ -141,6 +141,7 @@ window.main = async () => { args: { options: parsed_args.values, positionals: parsed_args.positionals, + tokens: parsed_args.tokens, }, env, }; diff --git a/packages/git/src/subcommands/__exports__.js b/packages/git/src/subcommands/__exports__.js index e9caea944..2950292f0 100644 --- a/packages/git/src/subcommands/__exports__.js +++ b/packages/git/src/subcommands/__exports__.js @@ -24,6 +24,7 @@ import module_config from './config.js' import module_help from './help.js' import module_init from './init.js' import module_log from './log.js' +import module_remote from './remote.js' import module_show from './show.js' import module_status from './status.js' import module_version from './version.js' @@ -36,6 +37,7 @@ export default { "help": module_help, "init": module_init, "log": module_log, + "remote": module_remote, "show": module_show, "status": module_status, "version": module_version, diff --git a/packages/git/src/subcommands/remote.js b/packages/git/src/subcommands/remote.js new file mode 100644 index 000000000..4cc05125f --- /dev/null +++ b/packages/git/src/subcommands/remote.js @@ -0,0 +1,126 @@ +/* + * 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 git from 'isomorphic-git'; +import { find_repo_root } from '../git-helpers.js'; + +export default { + name: 'remote', + usage: 'git remote', + description: `Manage remote repositories.`, + args: { + allowPositionals: true, + tokens: true, + options: { + verbose: { + description: 'Verbose if the commit verbose was used', + type: 'boolean', + short: 'v', + default: false, + } + }, + }, + execute: async (ctx) => { + const { io, fs, env, args } = ctx; + const { stdout, stderr } = io; + const { options, positionals, tokens } = args; + + const { repository_dir, git_dir } = await find_repo_root(fs, env.PWD); + + // TODO: Other subcommands: + // - set-head + // - set-branches + // - get-url + // - set-url + // - show + // - prune + // - update + const subcommand = positionals.shift(); + switch (subcommand) { + case undefined: { + // No subcommand, so list remotes + const remotes = await git.listRemotes({ + fs, + dir: repository_dir, + gitdir: git_dir, + }); + for (const remote of remotes) { + if (options.verbose) { + // TODO: fetch and push urls can be overridden per remote. That's what this is supposed to show. + stdout(`${remote.remote}\t${remote.url} (fetch)`); + stdout(`${remote.remote}\t${remote.url} (push)`); + } else { + stdout(remote.remote); + } + } + return; + } + + case 'add': { + if (positionals.length !== 2) { + stderr(`error: Wrong number of arguments to 'git remote add'. Expected 2 but got ${positionals.length}`); + return 1; + } + const [ name, url ] = positionals; + await git.addRemote({ + fs, + dir: repository_dir, + gitdir: git_dir, + remote: name, + url: url, + }); + return; + } + + case 'remove': + case 'rm': { + if (positionals.length !== 1) { + stderr(`error: Wrong number of arguments to 'git remote remove'. Expected 1 but got ${positionals.length}`); + return 1; + } + const [ name ] = positionals; + + // First, check if the remote exists so we can show an error if it doesn't. + const remotes = await git.listRemotes({ + fs, + dir: repository_dir, + gitdir: git_dir, + }); + if (!remotes.find(it => it.remote === name)) { + stderr(`error: No such remote: '${name}'`); + return 1; + } + + await git.deleteRemote({ + fs, + dir: repository_dir, + gitdir: git_dir, + remote: name, + }); + return; + } + + default: { + stderr(`fatal: Unrecognized command 'git remote ${subcommand}'`); + return 1; + } + } + + + } +}