feat(home): home ts util (wip)

This commit is contained in:
2023-12-18 03:12:38 +02:00
parent 75df778781
commit ff340066d0
9 changed files with 165 additions and 12 deletions

View File

@@ -1,7 +0,0 @@
{
"cSpell.words": [
"dotfiles"
],
"python.linting.enabled": true,
"i18next.i18nPaths": "/Users/chen/.dotfiles/scaffolds/nextjs/public/locales"
}

4
.zshrc
View File

@@ -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

View File

@@ -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",

View File

@@ -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: '' }

View File

7
utils/src/home/common.ts Normal file
View 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
View 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
View 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()

View 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,
})