1
1
import simpleGit , { SimpleGit } from "simple-git" ;
2
2
import chain from "@softwareventures/chain" ;
3
- import { concat } from "@softwareventures/array" ;
3
+ import { concat , map } from "@softwareventures/array" ;
4
+ import wrap = require( "wordwrap" ) ;
4
5
import { mapFn as mapAsyncFn } from "../collections/async-iterable" ;
5
6
import { FsStage , InsertResult } from "../fs-stage/fs-stage" ;
6
7
import {
@@ -30,12 +31,14 @@ export type Update = FsStageUpdate | DirectUpdate;
30
31
export interface FsStageUpdate {
31
32
readonly type : "fs-stage-update" ;
32
33
readonly log : string ;
34
+ readonly breaking ?: readonly string [ ] ;
33
35
readonly apply : ( stage : FsStage ) => Promise < InsertResult > ;
34
36
}
35
37
36
38
export interface DirectUpdate {
37
39
readonly type : "direct-update" ;
38
40
readonly log : string ;
41
+ readonly breaking ?: readonly string [ ] ;
39
42
readonly apply : ( ) => Promise < Result < UpdateStepFailureReason > > ;
40
43
}
41
44
@@ -45,8 +48,13 @@ export type UpdateFailureReason = GitNotClean | CommitFailureReason | UpdateStep
45
48
46
49
export type UpdateStepFailureReason = YarnFixFailureReason | PrettierFixFailureReason ;
47
50
48
- export async function updateProject ( project : Project ) : Promise < UpdateResult > {
49
- const git = simpleGit ( project . path ) ;
51
+ export interface UpdateProjectOptions {
52
+ readonly project : Project ;
53
+ readonly breaking ?: boolean ;
54
+ }
55
+
56
+ export async function updateProject ( options : UpdateProjectOptions ) : Promise < UpdateResult > {
57
+ const git = simpleGit ( options . project . path ) ;
50
58
51
59
return chain ( [
52
60
updateLintScript ,
@@ -56,7 +64,7 @@ export async function updateProject(project: Project): Promise<UpdateResult> {
56
64
addMissingLicense ,
57
65
addNewNodeVersionsToPackageJson
58
66
] )
59
- . map ( mapAsyncFn ( step ( project , git ) ) )
67
+ . map ( mapAsyncFn ( step ( options , git ) ) )
60
68
. map ( combineAsyncResults ) . value ;
61
69
}
62
70
@@ -70,14 +78,19 @@ export function gitNotClean(path: string): GitNotClean {
70
78
}
71
79
72
80
function step (
73
- project : Project ,
81
+ { project, breaking } : UpdateProjectOptions ,
74
82
git : SimpleGit
75
83
) : ( update : ( project : Project ) => Promise < Update | null > ) => Promise < UpdateResult > {
76
84
return async update =>
77
85
git
78
86
. status ( )
79
87
. then ( status => ( status . isClean ( ) ? success ( ) : failure ( [ gitNotClean ( project . path ) ] ) ) )
80
88
. then ( mapAsyncResultFn ( async ( ) => update ( project ) ) )
89
+ . then (
90
+ mapAsyncResultFn ( async update =>
91
+ breaking || ( update ?. breaking ?. length ?? 0 ) === 0 ? update : null
92
+ )
93
+ )
81
94
. then ( bindAsyncResultFn ( async update => commitUpdate ( project , git , update ) ) ) ;
82
95
}
83
96
@@ -102,7 +115,7 @@ async function commitUpdate(
102
115
mapAsyncResultFn ( async files =>
103
116
files . length === 0
104
117
? undefined
105
- : git . add ( files ) . then ( async ( ) => git . commit ( update . log ) )
118
+ : git . add ( files ) . then ( async ( ) => git . commit ( generateCommitLog ( update ) ) )
106
119
)
107
120
)
108
121
. then (
@@ -114,6 +127,15 @@ async function commitUpdate(
114
127
) ;
115
128
}
116
129
130
+ function generateCommitLog ( update : Update ) : string {
131
+ return (
132
+ update . log +
133
+ map ( update . breaking ?? [ ] , breaking => wrap ( 62 ) ( `\n\nBREAKING CHANGE: ${ breaking } ` ) ) . join (
134
+ ""
135
+ )
136
+ ) ;
137
+ }
138
+
117
139
async function writeUpdate ( project : Project , update : Update ) : Promise < UpdateResult > {
118
140
switch ( update . type ) {
119
141
case "fs-stage-update" :
0 commit comments