UNPKG

@savaryna/git-add-account

Version:

🔐 A small CLI app that allows you to easily add multiple Git accounts on one machine. It switches between accounts automatically based on the workspace you are in.

43 lines (42 loc) 5.63 kB
#!/usr/bin/env node "use strict";var T=Object.create;var u=Object.defineProperty;var N=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var I=Object.getPrototypeOf,Y=Object.prototype.hasOwnProperty;var j=(e,i,n,s)=>{if(i&&typeof i=="object"||typeof i=="function")for(let t of O(i))!Y.call(e,t)&&t!==n&&u(e,t,{get:()=>i[t],enumerable:!(s=N(i,t))||s.enumerable});return e};var d=(e,i,n)=>(n=e!=null?T(I(e)):{},j(i||!e||!e.__esModule?u(n,"default",{value:e,enumerable:!0}):n,e));var $=d(require("yargs")),S=require("yargs/helpers");var x=require("os"),A=require("path"),D=d(require("prompts"));var b=require("child_process"),w=require("fs"),a=require("fs/promises"),l=require("os"),r=require("path"),k=require("util"),m=d(require("mustache"));var h=` [includeIf "gitdir:{{{paths.workspace}}}/"] path = {{{paths.gitConfig}}} `;var y=`# Config for GIT account {{{configDetails.email}}} [user] name = {{{configDetails.name}}} email = {{{configDetails.email}}} [core] sshCommand = ssh -F {{{paths.sshConfig}}} {{#configDetails.signYourWork}} [gpg] format = ssh [commit] gpgsign = true [push] gpgsign = if-asked [tag] gpgsign = true [user] signingkey = {{{paths.privateKey}}} {{/configDetails.signYourWork}} `;var C=`# Config for GIT account {{{configDetails.email}}} Host {{{configDetails.host}}} IgnoreUnknown AddKeysToAgent HostName {{{configDetails.host}}} User git AddKeysToAgent yes IdentitiesOnly yes IdentityFile {{{paths.privateKey}}} `;var c=require("zod"),E=(e,i)=>{let{success:n,error:s}=e.safeParse(i);return!n&&s.errors.map(({message:t})=>t).join(` `)},g=E;var L=(0,k.promisify)(b.exec);async function R(e){let i=`id_ed25519_git_${e.host}`,n=i,s=`${i}.pub`,t=(0,r.resolve)((0,l.tmpdir)(),n),o=(0,r.resolve)((0,l.tmpdir)(),s);await(0,a.rm)(t,{force:!0}),await(0,a.rm)(o,{force:!0}),await L(`ssh-keygen -t ed25519 -C "${e.email}" -f ${t} -N ""`);let f=await(0,a.readFile)(t,"utf8"),F=await(0,a.readFile)(o,"utf8");return await(0,a.rm)(t,{force:!0}),await(0,a.rm)(o,{force:!0}),{privateKeyName:n,publicKeyName:s,privateKey:f,publicKey:F}}var p=c.z.object({name:c.z.string().min(1),email:c.z.string().email(),host:c.z.string().refine(e=>e.includes(".")&&URL.canParse(`https://${e}`),{message:"Invalid host, must be a valid domain (e.g., github.com)"}),workspace:c.z.string().min(1).refine(e=>!(0,w.existsSync)(e),"Path already exists"),signYourWork:c.z.boolean()});async function v(e){let i=g(p,e);if(i)throw new Error(i);let n=await R(e),s=(0,r.resolve)(e.workspace),t=(0,r.resolve)(s,".config"),o={workspace:s,config:t,gitConfigGlobal:(0,r.resolve)((0,l.homedir)(),".gitconfig"),gitConfig:(0,r.resolve)(t,"gitconfig"),sshConfig:(0,r.resolve)(t,"sshconfig"),privateKey:(0,r.resolve)(t,n.privateKeyName),publicKey:(0,r.resolve)(t,n.publicKeyName)};return{gitConfigGlobal:{path:o.gitConfigGlobal,content:m.default.render(h,{configDetails:e,paths:o})},gitConfig:{path:o.gitConfig,content:m.default.render(y,{configDetails:e,paths:o})},sshConfig:{path:o.sshConfig,content:m.default.render(C,{configDetails:e,paths:o})},privateKey:{path:o.privateKey,content:n.privateKey,secret:!0},publicKey:{path:o.publicKey,content:n.publicKey}}}async function K(e,i){let n=(0,r.resolve)(e.workspace,".config");await(0,a.mkdir)(n,{recursive:!0});let s=Object.values(i).map(({path:t,content:o,secret:f})=>(0,a.appendFile)(t,o,{encoding:"utf8",mode:f?384:420}));await Promise.all(s)}var G={command:["$0","add"],describe:"Add a new Git account",builder:e=>e.option("dry-run",{type:"boolean",describe:"Preview the generated config files without writing them to disk"}),handler:async e=>{console.log("Let's add a new Git account.");let s=await(0,D.default)([{type:"text",name:"name",message:"Full name for Git commits (e.g., John Doe):",validate:o=>g(p.shape.name,o)||!0},{type:"text",name:"email",message:"Email for this Git account:",validate:o=>g(p.shape.email,o)||!0},{type:"text",name:"host",message:"Git provider host (e.g., github.com, gitlab.com):",initial:o=>o.split("@")[1],validate:o=>g(p.shape.host,o)||!0},{type:"text",name:"workspace",message:"Absolute path to the workspace for this account:",initial:o=>(0,A.resolve)((0,x.homedir)(),"code",o),validate:o=>g(p.shape.workspace,o)||!0},{type:"toggle",name:"signYourWork",message:"Sign commits and tags with your SSH key?",initial:!0,active:"yes",inactive:"no"}],{onCancel:()=>{throw new Error("Operation cancelled by the user.")}}),t=await v(s);if(e!=null&&e.dryRun){console.log(` Config files that would be generated/updated:`);for(let o of Object.values(t))console.log(` Path:`,o.path),console.log(o.secret?"[Content hidden for security]":o.content)}else await K(s,t),console.log(` Your public SSH key is: ${t.publicKey.content}`),console.log(`You can also find it here: ${t.publicKey.path}`),console.log(` Next, add the key to ${s.host}:`),console.log("1. Copy the public SSH key above."),console.log(`2. Go to the SSH keys settings page on ${s.host}.`),console.log("3. Add the key as an 'Authentication Key'."),s.signYourWork&&console.log("4. Add the same key again as a 'Signing Key'."),console.log(` Done! Any git command you run from '${s.workspace}',`),console.log("(and its subdirectories), will now use this new account.")}};var P=[G];(0,$.default)((0,S.hideBin)(process.argv)).scriptName("git-add-account").usage("$0 [cmd] <options>").command(P).demandCommand(0,1).help("h").alias("h","help").strict().fail((e,i,n)=>{e&&console.log(n.help()),console.log(` ${e||(i==null?void 0:i.message)} `),console.log(`\u{1F635} Exited! Thanks for using @savaryna/git-add-account! `),process.exit(1)}).parse();