mirror of
https://github.com/chenasraf/dotfiles.git
synced 2026-05-17 17:28:07 +00:00
feat(home): home ts util (wip)
This commit is contained in:
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"dotfiles"
|
||||
],
|
||||
"python.linting.enabled": true,
|
||||
"i18next.i18nPaths": "/Users/chen/.dotfiles/scaffolds/nextjs/public/locales"
|
||||
}
|
||||
4
.zshrc
4
.zshrc
@@ -5,7 +5,7 @@ export DOTBIN="$CFG/bin"
|
||||
# echo 'Loading '$DOTFILES/functions.sh
|
||||
source "$DOTFILES/functions.sh"
|
||||
|
||||
motd
|
||||
[[ "$1" == "-q" ]] || motd
|
||||
|
||||
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
|
||||
# Initialization code that may require console input (password prompts, [y/n]
|
||||
@@ -59,7 +59,7 @@ fi
|
||||
|
||||
export VISUAL="$EDITOR"
|
||||
|
||||
tmux source-file ~/.config/.tmux.conf
|
||||
tmux source-file "$HOME/.config/.tmux.conf"
|
||||
|
||||
# echo 'Loading '$DOTFILES/exports.sh
|
||||
source "$DOTFILES/exports.sh" # must run before zsh_init
|
||||
|
||||
@@ -6,10 +6,12 @@
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
"tx": "tmux/cmd.js",
|
||||
"h_": "home/home.js",
|
||||
"tblf": "tblf.js"
|
||||
},
|
||||
"scripts": {
|
||||
"tx": "ts-node src/tmux/cmd.ts",
|
||||
"h": "ts-node src/home/home.ts",
|
||||
"tblf": "ts-node src/tblf.ts",
|
||||
"build": "tsc && cp package.json build/",
|
||||
"ginst": "pnpm build && pnpm i -g utils@file:$(pwd)/build",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { MassargCommand } from 'massarg/command'
|
||||
import { spawn } from 'node:child_process'
|
||||
|
||||
export type Opts = {
|
||||
@@ -6,16 +7,39 @@ export type Opts = {
|
||||
dry: boolean
|
||||
}
|
||||
|
||||
export function withDefaultOpts<T extends Opts, OT extends {} = {}>(
|
||||
command: MassargCommand<OT>,
|
||||
): MassargCommand<OT & T> {
|
||||
return (command as MassargCommand<OT & T>)
|
||||
.flag({
|
||||
name: 'verbose',
|
||||
description: 'Verbose output',
|
||||
aliases: ['v'],
|
||||
})
|
||||
.flag({
|
||||
name: 'dry',
|
||||
description: 'Dry run',
|
||||
aliases: ['d'],
|
||||
})
|
||||
.help({
|
||||
bindOption: true,
|
||||
bindCommand: true,
|
||||
})
|
||||
}
|
||||
|
||||
export function log({ verbose, dry }: Opts, ...content: any[]) {
|
||||
if (!verbose && !dry) return
|
||||
console.log(...content)
|
||||
}
|
||||
|
||||
export async function runCommand(opts: Opts, command: string) {
|
||||
export async function runCommand(opts: Opts, command: string | string[]): Promise<number> {
|
||||
if (Array.isArray(command)) {
|
||||
command = command.join('; ')
|
||||
}
|
||||
const [cmd, ...args] = command.split(' ')
|
||||
log(opts, '$ ' + command)
|
||||
if (opts.dry) return 0
|
||||
const proc = spawn(cmd, args, { stdio: 'inherit' })
|
||||
const proc = spawn(cmd, args, { stdio: 'inherit', shell: '/bin/zsh' })
|
||||
return new Promise((resolve, reject) => {
|
||||
proc.on('close', (code) => {
|
||||
if (code === 0) {
|
||||
@@ -29,8 +53,11 @@ export async function runCommand(opts: Opts, command: string) {
|
||||
|
||||
export async function getCommandOutput(
|
||||
opts: Opts,
|
||||
command: string,
|
||||
command: string | string[],
|
||||
): Promise<{ code: number; output: string }> {
|
||||
if (Array.isArray(command)) {
|
||||
command = command.join('; ')
|
||||
}
|
||||
const [cmd, ...args] = command.split(' ')
|
||||
log(opts, '$ ' + command)
|
||||
if (opts.dry) return { code: 0, output: '' }
|
||||
|
||||
0
utils/src/home/brew_cmd.ts
Normal file
0
utils/src/home/brew_cmd.ts
Normal file
7
utils/src/home/common.ts
Normal file
7
utils/src/home/common.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import * as path from 'node:path'
|
||||
import * as os from 'node:os'
|
||||
import { Opts } from '../common'
|
||||
|
||||
export type HomeOpts = Opts
|
||||
|
||||
export const DF_DIR = path.join(os.homedir(), '/.dotfiles')
|
||||
63
utils/src/home/git_cmd.ts
Normal file
63
utils/src/home/git_cmd.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { CommandConfig, MassargCommand } from 'massarg/command'
|
||||
import { DF_DIR, HomeOpts } from './common'
|
||||
import { runCommand } from '../common'
|
||||
|
||||
type PushOpts = HomeOpts & {
|
||||
message?: string
|
||||
}
|
||||
|
||||
type GitOpts = HomeOpts & {
|
||||
args: string[]
|
||||
}
|
||||
|
||||
function createGitCommand<O extends HomeOpts>(
|
||||
name: string,
|
||||
commands?: (opts: O) => string[],
|
||||
config?: Partial<CommandConfig<O>>,
|
||||
): MassargCommand<O> {
|
||||
return new MassargCommand<O>({
|
||||
name,
|
||||
description: `Run git ${name}`,
|
||||
aliases: [name[0].toLowerCase()],
|
||||
run: async (opts) => {
|
||||
if (commands) {
|
||||
for (const command of commands(opts)) {
|
||||
await runCommand(opts, `git -C ${DF_DIR} ${command}`)
|
||||
}
|
||||
} else {
|
||||
runCommand(opts, `git -C ${DF_DIR} ${name}`)
|
||||
}
|
||||
},
|
||||
...config,
|
||||
})
|
||||
}
|
||||
export const gitCommand = createGitCommand<GitOpts>(
|
||||
'git',
|
||||
(opts) => [opts.args.map((e) => (e.includes(' ') ? JSON.stringify(e) : e)).join(' ')],
|
||||
{ description: 'Run git command' },
|
||||
).option({
|
||||
name: 'args',
|
||||
description: 'Arguments to pass to git',
|
||||
aliases: ['a'],
|
||||
array: true,
|
||||
isDefault: true,
|
||||
required: true,
|
||||
})
|
||||
|
||||
export const pushCommand = createGitCommand<PushOpts>(
|
||||
'push',
|
||||
(opts) => [`add .`, `commit ${opts.message ? `-m "${opts.message}"` : ''}`, `push`],
|
||||
{
|
||||
description: 'Push all (incl. uncommitted) changes to remote',
|
||||
},
|
||||
).option({
|
||||
name: 'message',
|
||||
description: 'Commit message',
|
||||
aliases: ['m'],
|
||||
})
|
||||
|
||||
export const pullCommand = createGitCommand('pull', undefined, { aliases: ['l'] })
|
||||
|
||||
export const statusCommand = createGitCommand('status', undefined, {
|
||||
description: 'Show git status',
|
||||
})
|
||||
31
utils/src/home/home.ts
Normal file
31
utils/src/home/home.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { massarg } from 'massarg'
|
||||
import { Opts, runCommand, withDefaultOpts } from '../common'
|
||||
import { gitCommand, pullCommand, pushCommand, statusCommand } from './git_cmd'
|
||||
import { DF_DIR, HomeOpts } from './common'
|
||||
import { utilsCommand } from './utils_cmd'
|
||||
|
||||
async function sourceRun(opts: Opts, cmd: string | string[]) {
|
||||
return runCommand(opts, [`source "${DF_DIR}/.zshrc" -q`, ...(Array.isArray(cmd) ? cmd : [cmd])])
|
||||
}
|
||||
|
||||
withDefaultOpts(
|
||||
massarg<HomeOpts>({
|
||||
name: 'home',
|
||||
description: 'Dotfiles management',
|
||||
}),
|
||||
)
|
||||
.command(gitCommand)
|
||||
.command(statusCommand)
|
||||
.command(pushCommand)
|
||||
.command(pullCommand)
|
||||
.command(utilsCommand)
|
||||
.command({
|
||||
name: 'install',
|
||||
aliases: ['i'],
|
||||
description: 'Install dotfiles',
|
||||
run: async (opts) => {
|
||||
const vOpts = { ...opts, verbose: true }
|
||||
await sourceRun(vOpts, `source "${DF_DIR}/install.sh"`)
|
||||
},
|
||||
})
|
||||
.parse()
|
||||
30
utils/src/home/utils_cmd.ts
Normal file
30
utils/src/home/utils_cmd.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { MassargCommand } from 'massarg/command'
|
||||
import { DF_DIR, HomeOpts } from './common'
|
||||
import { massarg } from 'massarg'
|
||||
import { runCommand } from '../common'
|
||||
|
||||
const install = async (opts: HomeOpts) => {
|
||||
await runCommand(opts, [
|
||||
`pushd ${DF_DIR}/utils`,
|
||||
'pnpm install && pnpm build && pnpm ginst',
|
||||
'popd',
|
||||
])
|
||||
}
|
||||
const installCommand = new MassargCommand<HomeOpts>({
|
||||
name: 'install',
|
||||
aliases: ['i'],
|
||||
description: 'Install utilities',
|
||||
run: install,
|
||||
})
|
||||
|
||||
export const utilsCommand = massarg<HomeOpts>({
|
||||
name: 'utils',
|
||||
aliases: ['u'],
|
||||
description: 'Manage utilities',
|
||||
})
|
||||
.main(install)
|
||||
.command(installCommand)
|
||||
.help({
|
||||
bindCommand: true,
|
||||
bindOption: true,
|
||||
})
|
||||
Reference in New Issue
Block a user