forked from antfu-collective/bumpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoperation.ts
110 lines (96 loc) · 2.95 KB
/
operation.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import type { NormalizedOptions } from './normalize-options'
import { normalizeOptions } from './normalize-options'
import type { ReleaseType } from './release-type'
import type { VersionBumpOptions } from './types/version-bump-options'
import type { NpmScript, ProgressEvent, VersionBumpProgress } from './types/version-bump-progress'
import type { VersionBumpResults } from './types/version-bump-results'
type ProgressCallback = (progress: VersionBumpProgress) => void
interface OperationState {
release: ReleaseType | undefined
oldVersionSource: string
oldVersion: string
newVersion: string
commitMessage: string
tagName: string
updatedFiles: string[]
skippedFiles: string[]
}
interface UpdateOperationState extends Partial<OperationState> {
event?: ProgressEvent
script?: NpmScript
}
/**
* All of the inputs, outputs, and state of a single `versionBump()` call.
*/
export class Operation {
/**
* The options for this operation.
*/
public options: NormalizedOptions
/**
* The current state of the operation.
*/
public readonly state: Readonly<OperationState> = {
release: undefined,
oldVersion: '',
oldVersionSource: '',
newVersion: '',
commitMessage: '',
tagName: '',
updatedFiles: [],
skippedFiles: [],
}
/**
* The results of the operation.
*/
public get results(): VersionBumpResults {
const options = this.options
const state = this.state
return {
release: state.release,
oldVersion: state.oldVersion,
newVersion: state.newVersion,
commit: options.commit ? state.commitMessage : false,
tag: options.tag ? state.tagName : false,
updatedFiles: state.updatedFiles.slice(),
skippedFiles: state.skippedFiles.slice(),
}
}
/**
* The callback that's used to report the progress of the operation.
*/
private readonly _progress?: ProgressCallback
/**
* Private constructor. Use the `Operation.start()` static method instead.
*/
private constructor(options: NormalizedOptions, progress?: ProgressCallback, oldVersion?: string) {
this.options = options
this._progress = progress
if (oldVersion) {
this.update({
oldVersion,
oldVersionSource: 'user',
})
}
}
/**
* Starts a new `versionBump()` operation.
*/
public static async start(input: VersionBumpOptions & { oldVersion?: string }): Promise<Operation> {
// Validate and normalize the options
const options = await normalizeOptions(input)
return new Operation(options, input.progress, input.oldVersion)
}
/**
* Updates the operation state and results, and reports the updated progress to the user.
*/
public update({ event, script, ...newState }: UpdateOperationState): this {
// Update the operation state
Object.assign(this.state, newState)
if (event && this._progress) {
// Report the progress to the user
this._progress({ event, script, ...this.results })
}
return this
}
}