0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

denoでgitを呼び出してみた2

Last updated at Posted at 2020-06-12

はじめに

前回は1ファイルにベタ書きしてしまったので、今回はgit呼び出し関数をモジュールに切り分けて別スクリプトからも利用できるようにしてみた。

コード

そのままモジュール化するのも芸がないので、各関数の中身もベタ書きしてたのを共通処理runCmd: string[] -> Promise<string | null>として括り出してみた。
runCmdはコマンドを呼び出して、失敗したならnullを、成功したなら標準出力を文字列として返す。

git.ts
export async function branches(): Promise<string[]> {
  const ret = await runCmd(['git', 'rev-parse', '--abbrev-ref', '--branches'])
  if (ret === null) return []
  return ret.split(/\r\n|\n/)
}

export const currentBranch = () => runCmd(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
export const checkoutBranch = async (branch: string) => null !== await runCmd(['git', 'checkout', '-b', branch])
export const checkout = async (branch: string) =>  null !== await runCmd(['git', 'checkout', branch])
export const merge = async (branch: string) => null !== await runCmd(['git', 'merge', '--no-ff', branch])
export const deleteBranch = async (branch: string) => null !== await runCmd(['git', 'branch', '-D', branch])

async function runCmd(cmds: string[]): Promise<string | null> {
  const p = Deno.run({ cmd: cmds, stdout: 'piped', stderr: 'piped' })
  const { code } = await p.status()
  return code !== 0 ? null : (new TextDecoder().decode(await p.output())).trim()
}

あとはgit.tsをインポートする形にgit-wip.tsを書き換えて終了。

git-wip.ts
// Usage: deno run --allow-run git-wip.ts
// 現在のブランチがworkなら wip/YYYYMMDD_hh ブランチを作成し移動
// wip/~ ブランチならworkブランチにマージ
//
// Script install: deno install --allow-run ~/denoscripts/git-wip.ts
// 上記でインストールすると ~/.deno/bin に ~/denoscripts/git-wip.ts を呼び出すスクリプトが作られる
// ~/denoscripts/git-wip.ts自体は~/.deno/binにコピーされない

import * as git from './git.ts'

async function main(): Promise<number> {
  const work = 'work'
  const twoDigits = (n: number): string => (n > 9 ? '' : '0') + n

  const current = await git.currentBranch()
  if (current === null) {
    console.error('not a git repository')
    return -1
  } else if (current === work) {
    const now = new Date()
    const wip = `wip/${now.getFullYear()}${twoDigits(now.getMonth() + 1)}${twoDigits(now.getDate())}_${twoDigits(now.getHours())}`
    if (await git.checkoutBranch(wip)) {
      console.log(`branching "${wip}"`)
    } else {
      console.error(`do not branching "${wip}"`)
      return -1
    }
  } else if (current.startsWith('wip/')) {
    if (!(await git.branches()).includes(work)) {
      console.error('no exists "work" branch')
      return -1
    } else {
      console.log(`${current} is merging to work`)
      await git.checkout(work)
      await git.merge(current)
      await git.deleteBranch(current)
    }
  } else {
    console.error('not a work or wip branch')
    return -1
  }
  return 0
}

Deno.exit(await main())

せっかくなのでgit.tsを利用したマージ処理も作る。
処理の流れは、現在のブランチを覚えておいて、toブランチに切り替え、fromブランチをマージ、覚えておいた元のブランチに戻るというもの。

git-mgft.ts
// Usage: deno run --allow-run git-mgft.ts from to
// fromをtoにマージする

import * as git from './git.ts'

async function main(): Promise<number> {
  if (Deno.args.length < 2) {
    console.error('Usage: git-mgft from to');
    return -1
  }
  const [branchFrom, branchTo] = Deno.args
  const current = await git.currentBranch()
  if (current === null) {
    console.error('not a git repository')
    return -1
  }
  const info = await git.branches()
  if (info.indexOf(branchFrom) < 0 || info.indexOf(branchTo) < 0) {
    console.error('no branch: ' + branchTo)
    return -1
  }
  console.log(`git merge: ${branchFrom} -> ${branchTo}`)
  await git.checkout(branchTo)
  await git.merge(branchFrom)
  await git.checkout(current)
  return 0
}

Deno.exit(await main())
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?