🌳
pt0/deployF/libF/gitF/appDeployDiffF.mts
1import * as _ from 'lodash-es'
2import { liveRepoExec } from "./gitRepoF.mts"
11const deployFlagA = Object.keys({...applyCli, ...forceCli}).map(k => `--${k}`)
13export type AppDeployDiffResult = {
14 cmd: string
15 stdout: string
16 isNameOnly: boolean
17 existingGitSha?: string
18 newGitSha: string
19 lastDeployCommitsAgo?: number
20 lastDeployDurAgo?: string
23const getExtraGitArgsFromArgv = () => {
24 return _.filter(getProcArgv().slice(3), arg =>
25 arg.startsWith('-') && !arg.startsWith(`--${epScopeKey}=`) && !deployFlagA.includes(arg)
26 )
29const getDeployDiffStats = async ({git_repo_name, existingGitSha, newGitSha, filterPathList}: {git_repo_name?: string, existingGitSha: string, newGitSha: string, filterPathList: string[]}) => {
30 const commitCountCmd = `git rev-list --count ${existingGitSha}..${newGitSha} -- ${filterPathList.join(' ')}`
31 const lastDeployCommitsAgo = parseInt(await liveRepoExec({git_repo_name, cmd: commitCountCmd}), 10)
33 const commitDateCmd = `git log -1 --format=%ct ${existingGitSha}`
34 const existingShaUnixTs = parseInt(await liveRepoExec({git_repo_name, cmd: commitDateCmd}), 10)
35 const nowSec = Date.now() / 1000
36 const lastDeployDurAgo = secToHumanAbs(nowSec - existingShaUnixTs)
38 return {lastDeployCommitsAgo, lastDeployDurAgo}
41export const appDeployDiff = async ({
42 git_repo_name, diffcmd,
43 git_sha: newGitSha,
44 existingGitSha, filterPathList, logLimit,
45 noExtraGitArgs, rangeless,
46}: {git_repo_name?: string, diffcmd: string, git_sha?: string, existingGitSha?: string, filterPathList: string[], logLimit?: number, noExtraGitArgs?: boolean, rangeless?: boolean}): Promise<AppDeployDiffResult> => {
47 const manualRange = getManualRange()
48 if (manualRange) {
49 ;([existingGitSha, newGitSha] = [manualRange.from, manualRange.to])
50 }
52 const extraGitArgs = noExtraGitArgs ? [] : getExtraGitArgsFromArgv()
53 const isNameOnly = extraGitArgs.includes('--name-only')
55 assertDefined(newGitSha)
56 assertIncludes(/** @type {const} */ (['git diff', 'git log']), diffcmd, {diffcmd})
58 const useLogLimit = diffcmd === 'git log' && logLimit && !manualRange
59 const isRangeless = rangeless ?? (diffcmd === 'git log' && !existingGitSha)
61 let cmd = isRangeless ? diffcmd : `${diffcmd} ${existingGitSha}..${newGitSha}`
62 if (!isNameOnly && !_.some(extraGitArgs, a => a.startsWith('--no-color'))) {
63 cmd += ' --color-moved --color=always'
64 }
65 if (diffcmd == 'git log') {
66 cmd += ' --oneline'
67 if (useLogLimit) cmd += ` -${logLimit}`
68 } else if (diffcmd == 'git diff') {
69 cmd += ` --diff-algorithm=histogram`
70 }
71 if (extraGitArgs.length) {
72 cmd += ` ${extraGitArgs.join(' ')}`
73 }
75 assertDefined(filterPathList)
76 assertNonEmpty(filterPathList, {diffcmd, manualRange})
78 cmd += ` -- ${filterPathList.join(' ')}`
80 const stdout = await liveRepoExec({git_repo_name, cmd})
81 if (isRangeless && !existingGitSha) return {cmd, stdout, isNameOnly, existingGitSha, newGitSha}
82 const deployDiffStats = await getDeployDiffStats({git_repo_name, existingGitSha: existingGitSha as string, newGitSha, filterPathList})
83 return {cmd, stdout, isNameOnly, existingGitSha, newGitSha, ...deployDiffStats}