@@ -2,197 +2,80 @@ import * as yamlParser from "js-yaml";
22import * as path from "path" ;
33import * as _ from "lodash" ;
44import * as fs from "fs" ;
5- import * as T from "../typings/tutorial " ;
5+ import * as util from "util " ;
66import { 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" ;
4410
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 ) ;
4813
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+ } ;
5819
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 ;
6424 output : string ;
6525} ;
6626
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+ } ;
10748
108- // Filter relevant logs
109- const parts = new Set ( ) ;
49+ async function build ( args : string [ ] ) {
50+ const options = parseArgs ( args ) ;
11051
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 ) ;
11554
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+ ] ) ;
11960
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 ) ;
13462
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 ) ;
15564
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+ } ) ;
16871
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" ) ;
17575 } 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 ) ) ;
18577 }
18678 }
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 ;
19679}
19780
19881export default build ;
0 commit comments