1
1
import path from 'node:path' ;
2
- import execa from 'execa' ;
3
2
import fs from 'fs-extra' ;
3
+ import type { IntentionalCommit , StorageData } from '../types/intent.js' ;
4
4
import { generateId } from './generateId.js' ;
5
5
import { getPackageInfo } from './get-package-info.js' ;
6
- import git , { checkIsRepo } from './git.js' ;
7
-
8
- export type IntentionalCommit = {
9
- id : string ;
10
- message : string ;
11
- status : 'created' | 'in_progress' ;
12
- metadata : {
13
- createdAt : string ;
14
- startedAt ?: string ;
15
- branch ?: string ;
16
- } ;
17
- } ;
18
-
19
- export type StorageData = {
20
- version : string ;
21
- commits : IntentionalCommit [ ] ;
22
- } ;
6
+ import git , {
7
+ checkIsRepo ,
8
+ hashObject ,
9
+ createTree ,
10
+ createCommitTree ,
11
+ updateRef ,
12
+ deleteRef ,
13
+ checkRefExists ,
14
+ } from './git.js' ;
23
15
24
16
export class GitIntentionalCommitStorage {
25
17
private static instance : GitIntentionalCommitStorage ;
@@ -77,7 +69,6 @@ export class GitIntentionalCommitStorage {
77
69
}
78
70
}
79
71
80
- // NOTE: Migrate old data
81
72
private migrateData ( data : any ) : StorageData {
82
73
return data ;
83
74
}
@@ -105,14 +96,12 @@ export class GitIntentionalCommitStorage {
105
96
const commitsFile = await this . getCommitsFile ( ) ;
106
97
const content = JSON . stringify ( data , null , 2 ) ;
107
98
108
- const { stdout : hash } = await execa ( 'git' , [ 'hash-object' , '-w' , '--stdin' ] , { input : content , cwd : root } ) ;
109
- const treeContent = `100644 blob ${ hash . trim ( ) } \t${ this . storageFilename } \n` ;
110
- const { stdout : treeHash } = await execa ( 'git' , [ 'mktree' ] , { input : treeContent , cwd : root } ) ;
111
- const { stdout : commitHash } = await execa ( 'git' , [ 'commit-tree' , treeHash . trim ( ) , '-m' , 'Update intent commits' ] , {
112
- cwd : root ,
113
- } ) ;
99
+ const hash = await hashObject ( content , root ) ;
100
+ const treeContent = `100644 blob ${ hash } \t${ this . storageFilename } \n` ;
101
+ const treeHash = await createTree ( treeContent , root ) ;
102
+ const commitHash = await createCommitTree ( treeHash , 'Update intent commits' , root ) ;
114
103
115
- await git . cwd ( root ) . raw ( [ 'update-ref' , `${ this . REFS_PREFIX } /commits` , commitHash . trim ( ) ] ) ;
104
+ await updateRef ( `${ this . REFS_PREFIX } /commits` , commitHash , root ) ;
116
105
await fs . writeJSON ( commitsFile , data , { spaces : 2 } ) ;
117
106
}
118
107
@@ -128,14 +117,14 @@ export class GitIntentionalCommitStorage {
128
117
async addCommit ( commit : Omit < IntentionalCommit , 'id' > ) : Promise < string > {
129
118
const currentCommits = await this . loadCommits ( ) ;
130
119
const newCommitId = generateId ( 8 ) ;
120
+ const newCommit = { ...commit , id : newCommitId } ;
131
121
132
122
const data : StorageData = {
133
123
version : getPackageInfo ( ) . version ,
134
- commits : [ ...currentCommits , { ... commit , id : newCommitId } ] ,
124
+ commits : [ ...currentCommits , newCommit ] ,
135
125
} ;
136
126
137
127
await this . saveCommitsData ( data ) ;
138
-
139
128
return newCommitId ;
140
129
}
141
130
@@ -165,29 +154,24 @@ export class GitIntentionalCommitStorage {
165
154
const root = await this . getGitRoot ( ) ;
166
155
const commitsFile = await this . getCommitsFile ( ) ;
167
156
await fs . remove ( commitsFile ) ;
168
- await git . cwd ( root ) . raw ( [ 'update-ref' , '-d' , `${ this . REFS_PREFIX } /commits` ] ) ;
157
+ await deleteRef ( `${ this . REFS_PREFIX } /commits` , root ) ;
169
158
}
170
159
171
160
async initializeRefs ( ) : Promise < void > {
172
161
const root = await this . getGitRoot ( ) ;
173
162
await checkIsRepo ( root ) ;
174
163
175
- try {
176
- await git . cwd ( root ) . raw ( [ 'show-ref' , '--verify' , `${ this . REFS_PREFIX } /commits` ] ) ;
177
- } catch {
164
+ const refExists = await checkRefExists ( `${ this . REFS_PREFIX } /commits` , root ) ;
165
+ if ( ! refExists ) {
178
166
const initialData = this . getInitialData ( ) ;
179
167
const content = JSON . stringify ( initialData , null , 2 ) ;
180
168
181
- const { stdout : hash } = await execa ( 'git' , [ 'hash-object' , '-w' , '--stdin' ] , { input : content , cwd : root } ) ;
182
- const treeContent = `100644 blob ${ hash . trim ( ) } \t${ this . storageFilename } \n` ;
183
- const { stdout : treeHash } = await execa ( 'git' , [ 'mktree' ] , { input : treeContent , cwd : root } ) ;
184
- const { stdout : commitHash } = await execa (
185
- 'git' ,
186
- [ 'commit-tree' , treeHash . trim ( ) , '-m' , 'Initialize intent commits' ] ,
187
- { cwd : root }
188
- ) ;
169
+ const hash = await hashObject ( content , root ) ;
170
+ const treeContent = `100644 blob ${ hash } \t${ this . storageFilename } \n` ;
171
+ const treeHash = await createTree ( treeContent , root ) ;
172
+ const commitHash = await createCommitTree ( treeHash , 'Initialize intent commits' , root ) ;
189
173
190
- await git . cwd ( root ) . raw ( [ 'update-ref' , `${ this . REFS_PREFIX } /commits` , commitHash . trim ( ) ] ) ;
174
+ await updateRef ( `${ this . REFS_PREFIX } /commits` , commitHash , root ) ;
191
175
}
192
176
}
193
177
}
0 commit comments