├── .prettierignore ├── bin └── index.js ├── .gitignore ├── .prettierrc ├── package.json ├── README.md └── src ├── utils.js └── index.js /.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.svg 2 | **/*.ejs 3 | **/*.html 4 | package.json 5 | -------------------------------------------------------------------------------- /bin/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('../src/index'); 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | /npm-debug.log* 4 | /yarn-error.log 5 | /yarn.lock 6 | /package-lock.json 7 | 8 | # production 9 | /dist 10 | /docs-dist 11 | 12 | # misc 13 | .DS_Store 14 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "printWidth": 120, 5 | "overrides": [ 6 | { 7 | "files": ".prettierrc", 8 | "options": { "parser": "json" } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@gauseen/gum", 3 | "version": "1.0.5", 4 | "description": "git multiple user config manager", 5 | "bin": "./bin/index.js", 6 | "scripts": {}, 7 | "keywords": [ 8 | "git", 9 | "multiple", 10 | "config", 11 | "user", 12 | "manager" 13 | ], 14 | "author": "gauseen", 15 | "license": "ISC", 16 | "devDependencies": { 17 | "@types/node": "^15.12.4" 18 | }, 19 | "dependencies": { 20 | "commander": "^7.2.0", 21 | "console-table-printer": "^2.9.0", 22 | "git-config-path": "^2.0.0", 23 | "ini": "^2.0.0", 24 | "is-git-repository": "^2.0.0", 25 | "lodash": "^4.17.21", 26 | "parse-git-config": "^3.0.0", 27 | "shelljs": "^0.8.4" 28 | }, 29 | "bugs": { 30 | "url": "https://github.com/gauseen/gum/issues" 31 | }, 32 | "homepage": "https://github.com/gauseen/gum#readme" 33 | } 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Git multiple user config manager 2 | 3 | ## Install 4 | 5 | ```sh 6 | $ npm i -g @gauseen/gum 7 | ``` 8 | 9 | ## Example 10 | 11 | ```sh 12 | $ gum list 13 | 14 | Currently used name=gauseen email=gauseen@gmail.com 15 | ┌────────────┬─────────┬─────────────────────────┐ 16 | │ group-name │ name │ email │ 17 | ├────────────┼─────────┼─────────────────────────┤ 18 | │ global │ gauseen │ gauseen@gmail.com │ 19 | │ user1 │ li si │ lisi@gmail.com │ 20 | │ user2 │ wang er │ wanger@gmail.com │ 21 | └────────────┴─────────┴─────────────────────────┘ 22 | ``` 23 | 24 | ```sh 25 | $ gum use user1 26 | 27 | Currently used name=li si email=lisi@gmail.com 28 | ``` 29 | 30 | ## Usage 31 | 32 | ```sh 33 | Usage: gum [options] [command] 34 | 35 | Options: 36 | -V, --version output the version number 37 | -h, --help display help for command 38 | 39 | Commands: 40 | list List all the user config group 41 | set [options] Set one group for user config 42 | --name User name 43 | --email User email 44 | use [options] Use one group name for user config 45 | --global Git global config 46 | delete Delete one group 47 | help [command] display help for command 48 | ``` 49 | 50 | ## Change Log 51 | 52 | ### v1.0.5 53 | 54 | - feat: Support `gum use --global` commands that are not Git repositories 55 | 56 | ### v1.0.4 57 | 58 | - fix: support user.name contain space 59 | 60 | ### v1.0.3 61 | 62 | - fix: Group name can't be 'global' 63 | 64 | ### v1.0.2 65 | 66 | - feat: `gum --version` cmd 67 | - fix: support node v9.0.0 68 | -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs'); 3 | const ini = require('ini'); 4 | const merge = require('lodash/merge'); 5 | const gitConfigPath = require('git-config-path'); 6 | const parse = require('parse-git-config'); 7 | 8 | const GUMRC = path.join(process.env[process.platform == 'win32' ? 'USERPROFILE' : 'HOME'], '.gumrc'); 9 | 10 | function getGumrcInfo() { 11 | return fs.existsSync(GUMRC) ? ini.decode(fs.readFileSync(GUMRC, 'utf-8')) : {}; 12 | } 13 | 14 | function setGumrcInfo(finalGumrcInfo, callback) { 15 | fs.writeFile(GUMRC, ini.encode(finalGumrcInfo), callback); 16 | } 17 | 18 | function getAllConfigInfo() { 19 | const globalInfo = getGlobalGitUserConfig(); 20 | const currentGumrcInfo = getGumrcInfo(); 21 | const allInfo = merge({ global: globalInfo }, currentGumrcInfo); 22 | return allInfo; 23 | } 24 | 25 | function getUsingGitUserConfig() { 26 | const project = getProjectGitUserConfig() || {}; 27 | const global = getGlobalGitUserConfig() || {}; 28 | 29 | const name = project.name || global.name; 30 | const email = project.email || global.email; 31 | return { 32 | email, 33 | name, 34 | }; 35 | } 36 | 37 | function getProjectGitUserConfig() { 38 | return parse.sync().user; 39 | } 40 | 41 | function getGlobalGitUserConfig() { 42 | const global = gitConfigPath('global'); 43 | return parse.sync({ path: global }).user; 44 | } 45 | 46 | function getPrintTableData(data) { 47 | const tableData = Object.keys(data).map((groupName, index) => { 48 | const { name, email } = data[groupName] || {}; 49 | return { 50 | ['group-name']: groupName, 51 | name, 52 | email, 53 | }; 54 | }); 55 | 56 | return tableData; 57 | } 58 | 59 | // https://stackoverflow.com/questions/9781218/how-to-change-node-jss-console-font-color 60 | function printer(val, color) { 61 | const colorMap = { 62 | red: '\x1b[31m', 63 | yellow: '\x1b[33m', 64 | green: '\x1b[32m', 65 | cyan: '\x1b[36m', 66 | white: '\x1b[37m', 67 | }; 68 | 69 | console.log(' '); 70 | console.log(`${colorMap[color]}%s\x1b[0m`, val); 71 | } 72 | 73 | module.exports = { 74 | GUMRC, 75 | printer, 76 | getPrintTableData, 77 | getAllConfigInfo, 78 | getGumrcInfo, 79 | setGumrcInfo, 80 | getUsingGitUserConfig, 81 | getGlobalGitUserConfig, 82 | }; 83 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | const shell = require('shelljs'); 2 | const commander = require('commander'); 3 | const merge = require('lodash/merge'); 4 | const isGit = require('is-git-repository'); 5 | const { Table } = require('console-table-printer'); 6 | 7 | const { 8 | printer, 9 | getPrintTableData, 10 | getAllConfigInfo, 11 | getGumrcInfo, 12 | setGumrcInfo, 13 | getGlobalGitUserConfig, 14 | getUsingGitUserConfig, 15 | } = require('./utils'); 16 | 17 | const pkg = require('../package.json'); 18 | 19 | const program = new commander.Command('gum'); 20 | 21 | program.version(pkg.version); 22 | 23 | program.command('list').description('List all the user config group').action(onList); 24 | 25 | program 26 | .command('set ') 27 | .description('Set one group for user config') 28 | .option('--name ', 'user name') 29 | .option('--email ', 'user email') 30 | .action(onSet); 31 | 32 | program 33 | .command('use ') 34 | .description('Use one group name for user config') 35 | .option('--global', 'git global config') 36 | .action(onUse); 37 | 38 | program.command('delete ').description('Delete one group').action(onDelete); 39 | 40 | program.parse(process.argv); 41 | 42 | function onList() { 43 | const allConfig = getAllConfigInfo(); 44 | const using = getUsingGitUserConfig(); 45 | const tableData = getPrintTableData(allConfig); 46 | 47 | // currently used user info 48 | printer(`Currently used name=${using.name} email=${using.email}`, 'yellow'); 49 | 50 | // git user config group list 51 | const pt = new Table(); 52 | pt.addRows(tableData, { color: 'cyan' }); 53 | pt.printTable(); 54 | } 55 | 56 | function onSet(groupName, options) { 57 | const newGroup = { 58 | [groupName]: options, 59 | }; 60 | 61 | if (groupName === 'global') { 62 | printer(`Group name can't be 'global'`, 'red'); 63 | console.log(' '); 64 | return process.exit(1); 65 | } 66 | 67 | if (!options.name && !options.email) { 68 | printer(`Name and Email option must have one`, 'red'); 69 | console.log(' '); 70 | return process.exit(1); 71 | } 72 | 73 | const gumrcInfo = getGumrcInfo(); 74 | const finalGumrcInfo = merge(gumrcInfo, newGroup); 75 | 76 | setGumrcInfo(finalGumrcInfo, (err) => { 77 | if (err) { 78 | return process.exit(1); 79 | } 80 | printer(`Set ${groupName} group success`, 'green'); 81 | console.log(' '); 82 | }); 83 | } 84 | 85 | function onUse(groupName, options) { 86 | const allConfigInfo = getAllConfigInfo(); 87 | const user = allConfigInfo[groupName]; 88 | 89 | if (!shell.which('git')) { 90 | shell.echo('Sorry, this script requires git'); 91 | shell.exit(1); 92 | } 93 | 94 | if (!options.global && !isGit()) { 95 | printer(`Current project not a git repository (or any of the parent directories)`, 'red'); 96 | console.log(' '); 97 | process.exit(1); 98 | } 99 | 100 | if (user) { 101 | const g = options.global ? `--global` : ''; 102 | 103 | if (shell.exec(`git config ${g} user.name "${user.name}"`).code !== 0) { 104 | shell.echo('Error: Git config user.name failed'); 105 | } 106 | 107 | if (shell.exec(`git config ${g} user.email ${user.email}`).code !== 0) { 108 | shell.echo('Error: Git config user.email failed'); 109 | } 110 | 111 | const using = getUsingGitUserConfig(); 112 | 113 | if (options.global) { 114 | const globalGitUser = getGlobalGitUserConfig(); 115 | printer(`Global using name=${globalGitUser.name} email=${globalGitUser.email}`, 'green'); 116 | } 117 | 118 | printer(`Currently used name=${using.name} email=${using.email}`, 'yellow'); 119 | console.log(' '); 120 | } else { 121 | printer(`${groupName} is invalid group name`, 'red'); 122 | console.log(' '); 123 | } 124 | } 125 | 126 | function onDelete(groupName) { 127 | if (groupName === 'global') { 128 | printer(`Can't delete global`, 'red'); 129 | console.log(' '); 130 | return process.exit(1); 131 | } 132 | 133 | const gumrcInfo = getGumrcInfo(); 134 | gumrcInfo[groupName] && delete gumrcInfo[groupName]; 135 | 136 | setGumrcInfo(gumrcInfo, (err) => { 137 | if (err) { 138 | return process.exit(1); 139 | } 140 | printer(`Delete ${groupName} group success`, 'green'); 141 | console.log(' '); 142 | }); 143 | } 144 | --------------------------------------------------------------------------------