@@ -2,197 +2,80 @@ import * as yamlParser from "js-yaml";
2
2
import * as path from "path" ;
3
3
import * as _ from "lodash" ;
4
4
import * as fs from "fs" ;
5
- import * as T from "../typings/tutorial " ;
5
+ import * as util from "util " ;
6
6
import { parse } from "./utils/parse" ;
7
- // import validate from './validator';
8
-
9
- // import not working
10
- const simpleGit = require ( "simple-git/promise" ) ;
11
-
12
- const workingDir = "tmp" ;
13
-
14
- function rmDir ( dir : string , rmSelf = false ) {
15
- try {
16
- let files ;
17
- rmSelf = rmSelf === undefined ? true : rmSelf ;
18
-
19
- try {
20
- files = fs . readdirSync ( dir ) ;
21
- } catch ( e ) {
22
- console . log ( `Sorry, directory '${ dir } ' doesn't exist.` ) ;
23
- return ;
24
- }
25
-
26
- if ( files . length > 0 ) {
27
- files . forEach ( function ( filePath : string ) {
28
- if ( fs . statSync ( path . join ( dir , filePath ) ) . isDirectory ( ) ) {
29
- rmDir ( path . join ( dir , filePath ) ) ;
30
- } else {
31
- fs . unlinkSync ( path . join ( dir , filePath ) ) ;
32
- }
33
- } ) ;
34
- }
35
-
36
- if ( rmSelf ) {
37
- // check if user want to delete the directory ir just the files in this directory
38
- fs . rmdirSync ( dir ) ;
39
- }
40
- } catch ( error ) {
41
- return error ;
42
- }
43
- }
7
+ import { getArg } from "./utils/args" ;
8
+ import { getCommits , CommitLogObject } from "./utils/commits" ;
9
+ import * as T from "../typings/tutorial" ;
44
10
45
- async function cleanupFiles ( workingDir : string ) {
46
- try {
47
- const gitModule = simpleGit ( process . cwd ( ) ) ;
11
+ const write = util . promisify ( fs . writeFile ) ;
12
+ const read = util . promisify ( fs . readFile ) ;
48
13
49
- await gitModule . subModule ( [ "deinit" , "-f" , workingDir ] ) ;
50
- await gitModule . rm ( workingDir ) ;
51
- await gitModule . reset ( [ "HEAD" ] ) ;
52
- rmDir ( path . join ( process . cwd ( ) , ".git" , "modules" , workingDir ) ) ;
53
- rmDir ( workingDir ) ;
54
- } catch ( error ) {
55
- return error ;
56
- }
57
- }
14
+ export type BuildConfigOptions = {
15
+ text : string ; // text document from markdown
16
+ config : T . Tutorial ; // yaml config file converted to json
17
+ commits : CommitLogObject ; // an object of tutorial positions with a list of commit hashes
18
+ } ;
58
19
59
- export type BuildOptions = {
60
- repo : string ; // Git url to the repo. It should finish with .git
61
- codeBranch : string ; // The branch containing the tutorial code
62
- setupBranch : string ; // The branch containing the tutorialuration files
63
- isLocal : boolean ; // define if the repo is local or remote
20
+ type BuildArgs = {
21
+ dir : string ;
22
+ markdown : string ;
23
+ yaml : string ;
64
24
output : string ;
65
25
} ;
66
26
67
- async function build ( { repo, codeBranch, setupBranch, isLocal } : BuildOptions ) {
68
- let git : any ;
69
- let isSubModule = false ;
70
- let localPath : string ;
71
-
72
- if ( isLocal ) {
73
- git = simpleGit ( repo ) ;
74
- localPath = repo ;
75
- } else {
76
- const gitTest = simpleGit ( process . cwd ( ) ) ;
77
- const isRepo = await gitTest . checkIsRepo ( ) ;
78
- localPath = path . join ( process . cwd ( ) , workingDir ) ;
79
-
80
- if ( isRepo ) {
81
- await gitTest . submoduleAdd ( repo , workingDir ) ;
82
-
83
- isSubModule = true ;
84
- } else {
85
- await gitTest . clone ( repo , localPath ) ;
86
- }
87
-
88
- git = simpleGit ( localPath ) ;
89
- }
90
-
91
- await git . fetch ( ) ;
92
-
93
- // checkout the branch to load tutorialuration and content branch
94
- await git . checkout ( setupBranch ) ;
95
-
96
- // Load files
97
- const _content = fs . readFileSync ( path . join ( localPath , "TUTORIAL.md" ) , "utf8" ) ;
98
- let _config = fs . readFileSync ( path . join ( localPath , "coderoad.yaml" ) , "utf8" ) ;
99
-
100
- const tutorial = parse ( _content , _config ) ;
101
-
102
- // Checkout the code branches
103
- await git . checkout ( codeBranch ) ;
104
-
105
- // Load all logs
106
- const logs = await git . log ( ) ;
27
+ const parseArgs = ( args : string [ ] ) : BuildArgs => {
28
+ // default .
29
+ const dir = args [ 0 ] || "." ;
30
+ // -o --output - default coderoad.json
31
+ const output =
32
+ getArg ( args , { name : "output" , alias : "o" } ) || "coderoad.json" ;
33
+ // -m --markdown - default TUTORIAL.md
34
+ const markdown =
35
+ getArg ( args , { name : "markdown" , alias : "m" } ) || "TUTORIAL.md" ;
36
+ // -y --yaml - default coderoad-config.yml
37
+ const yaml =
38
+ getArg ( args , { name : "coderoad-config.yml" , alias : "y" } ) ||
39
+ "coderoad-config.yml" ;
40
+
41
+ return {
42
+ dir,
43
+ output,
44
+ markdown,
45
+ yaml,
46
+ } ;
47
+ } ;
107
48
108
- // Filter relevant logs
109
- const parts = new Set ( ) ;
49
+ async function build ( args : string [ ] ) {
50
+ const options = parseArgs ( args ) ;
110
51
111
- for ( const commit of logs . all ) {
112
- const matches = commit . message . match (
113
- / ^ (?< stepId > (?< levelId > L \d + ) S \d + ) (?< stepType > [ Q A ] ) ? /
114
- ) ;
52
+ // path to run build from
53
+ const localPath = path . join ( process . cwd ( ) , options . dir ) ;
115
54
116
- if ( matches && ! parts . has ( matches [ 0 ] ) ) {
117
- // Uses a set to make sure only the latest commit is proccessed
118
- parts . add ( matches [ 0 ] ) ;
55
+ // load files
56
+ const [ _markdown , _yaml ] = await Promise . all ( [
57
+ read ( path . join ( localPath , options . markdown ) , "utf8" ) ,
58
+ read ( path . join ( localPath , options . yaml ) , "utf8" ) ,
59
+ ] ) ;
119
60
120
- // Add the content and git hash to the tutorial
121
- if ( matches . groups . stepId ) {
122
- // If it's a step: add the content and the setup/solution hashes depending on the type
123
- const level : T . Level | null =
124
- tutorial . levels . find (
125
- ( level : T . Level ) => level . id === matches . groups . levelId
126
- ) || null ;
127
- if ( ! level ) {
128
- console . log ( `Level ${ matches . groups . levelId } not found` ) ;
129
- } else {
130
- const theStep : T . Step | null =
131
- level . steps . find (
132
- ( step : T . Step ) => step . id === matches . groups . stepId
133
- ) || null ;
61
+ const config = yamlParser . load ( _yaml ) ;
134
62
135
- if ( ! theStep ) {
136
- console . log ( `Step ${ matches . groups . stepId } not found` ) ;
137
- } else {
138
- if ( matches . groups . stepType === "Q" ) {
139
- theStep . setup . commits . push ( commit . hash . substr ( 0 , 7 ) ) ;
140
- } else if (
141
- matches . groups . stepType === "A" &&
142
- theStep . solution &&
143
- theStep . solution . commits
144
- ) {
145
- theStep . solution . commits . push ( commit . hash . substr ( 0 , 7 ) ) ;
146
- }
147
- }
148
- }
149
- } else {
150
- // If it's level: add the commit hash (if the level has the commit key) and the content to the tutorial
151
- const theLevel : T . Level | null =
152
- tutorial . levels . find (
153
- ( level : T . Level ) => level . id === matches . groups . levelId
154
- ) || null ;
63
+ const commits : CommitLogObject = await getCommits ( config . config . repo . branch ) ;
155
64
156
- if ( ! theLevel ) {
157
- console . log ( `Level ${ matches . groups . levelId } not found` ) ;
158
- } else {
159
- if ( _ . has ( theLevel , "tutorial.commits" ) ) {
160
- if ( theLevel . setup ) {
161
- theLevel . setup . commits . push ( commit . hash . substr ( 0 , 7 ) ) ;
162
- }
163
- }
164
- }
165
- }
166
- }
167
- }
65
+ // Otherwise, continue with the other options
66
+ const tutorial : T . Tutorial = await parse ( {
67
+ text : _markdown ,
68
+ config,
69
+ commits,
70
+ } ) ;
168
71
169
- // cleanup the submodules
170
- if ( ! isLocal ) {
171
- let cleanupErr ;
172
-
173
- if ( isSubModule ) {
174
- cleanupErr = await cleanupFiles ( workingDir ) ;
72
+ if ( tutorial ) {
73
+ if ( options . output ) {
74
+ await write ( options . output , JSON . stringify ( tutorial ) , "utf8" ) ;
175
75
} else {
176
- cleanupErr = rmDir ( path . join ( process . cwd ( ) , workingDir ) ) ;
177
- }
178
-
179
- if ( cleanupErr ) {
180
- console . log (
181
- `Error when deleting temporary files on ${
182
- isSubModule ? "module" : "folder"
183
- } ${ workingDir } .`
184
- ) ;
76
+ console . log ( JSON . stringify ( tutorial , null , 2 ) ) ;
185
77
}
186
78
}
187
-
188
- // const isValid = validate(tutorial);
189
-
190
- // if (!isValid) {
191
- // console.log(JSON.stringify(validate.errors, null, 2));
192
- // return;
193
- // }
194
-
195
- return tutorial ;
196
79
}
197
80
198
81
export default build ;
0 commit comments