Files
actions/src/tools/gitversion/tool.ts
2023-03-12 00:43:11 +01:00

161 lines
5.3 KiB
TypeScript

import { inject, injectable } from 'inversify'
import { IBuildAgent, IExecResult, TYPES } from '../../core/models'
import { DotnetTool, IDotnetTool } from '../../core/dotnet-tool'
import { GitVersionOutput, GitVersionSettings } from './models'
import { IVersionManager } from '../../core/versionManager'
import { ISetupSettings } from '../common/models'
export interface IGitVersionTool extends IDotnetTool {
install(setupSettings: ISetupSettings): Promise<void>
run(options: GitVersionSettings): Promise<IExecResult>
writeGitVersionToAgent(gitversion: GitVersionOutput): void
}
@injectable()
export class GitVersionTool extends DotnetTool implements IGitVersionTool {
constructor(@inject(TYPES.IBuildAgent) buildAgent: IBuildAgent, @inject(TYPES.IVersionManager) versionManager: IVersionManager) {
super(buildAgent, versionManager)
}
public async install(setupSettings: ISetupSettings): Promise<void> {
await this.toolInstall('GitVersion.Tool', setupSettings)
}
public run(options: GitVersionSettings): Promise<IExecResult> {
const workDir = this.getRepoDir(options.targetPath)
const args = this.getArguments(workDir, options)
return this.execute('dotnet-gitversion', args)
}
private getRepoDir(targetPath: string): string {
let workDir: string
const srcDir = this.buildAgent.getSourceDir() || '.'
if (!targetPath) {
workDir = srcDir
} else {
if (this.buildAgent.directoryExists(targetPath)) {
workDir = targetPath
} else {
throw new Error('Directory not found at ' + targetPath)
}
}
return workDir.replace(/\\/g, '/')
}
private getArguments(workDir: string, options: GitVersionSettings): string[] {
let args = [workDir, '/output', 'json', '/output', 'buildserver']
const { useConfigFile, configFilePath, updateAssemblyInfo, updateAssemblyInfoFilename, additionalArguments } = options
if (useConfigFile) {
if (this.buildAgent.isValidInputFile('configFilePath', configFilePath)) {
args.push('/config', configFilePath)
} else {
throw new Error('GitVersion configuration file not found at ' + configFilePath)
}
}
if (updateAssemblyInfo) {
args.push('/updateassemblyinfo')
// You can specify 'updateAssemblyInfo' without 'updateAssemblyInfoFilename'.
if (updateAssemblyInfoFilename?.length > 0) {
if (this.buildAgent.isValidInputFile('updateAssemblyInfoFilename', updateAssemblyInfoFilename)) {
args.push(updateAssemblyInfoFilename)
} else {
throw new Error('AssemblyInfoFilename file not found at ' + updateAssemblyInfoFilename)
}
}
}
if (additionalArguments) {
args = args.concat(this.argStringToArray(additionalArguments))
}
return args
}
public writeGitVersionToAgent(gitversion: GitVersionOutput): void {
let properties = Object.keys(gitversion)
let gitversionOutput = <any>gitversion
properties.forEach(property => {
const name = this.toCamelCase(property)
const value = gitversionOutput[property]
this.buildAgent.setOutput(name, value)
this.buildAgent.setOutput(`GitVersion_${name}`, value)
this.buildAgent.setVariable(name, value)
this.buildAgent.setVariable(`GitVersion_${name}`, value)
})
}
private argStringToArray(argString: string): string[] {
var args: string[] = []
var inQuotes = false
var escaped = false
var lastCharWasSpace = true
var arg = ''
var append = function (c: string) {
// we only escape double quotes.
if (escaped && c !== '"') {
arg += '\\'
}
arg += c
escaped = false
}
for (var i = 0; i < argString.length; i++) {
var c = argString.charAt(i)
if (c === ' ' && !inQuotes) {
if (!lastCharWasSpace) {
args.push(arg)
arg = ''
}
lastCharWasSpace = true
continue
} else {
lastCharWasSpace = false
}
if (c === '"') {
if (!escaped) {
inQuotes = !inQuotes
} else {
append(c)
}
continue
}
if (c === '\\' && escaped) {
append(c)
continue
}
if (c === '\\' && inQuotes) {
escaped = true
continue
}
append(c)
lastCharWasSpace = false
}
if (!lastCharWasSpace) {
args.push(arg.trim())
}
return args
}
private toCamelCase(input: string): string {
return input.replace(/^\w|[A-Z]|\b\w|\s+/g, function (match, index) {
if (+match === 0) return '' // or if (/\s+/.test(match)) for white spaces
return index == 0 ? match.toLowerCase() : match.toUpperCase()
})
}
}