Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Feature/version#8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
ShMcK merged 5 commits intomasterfromfeature/version
May 31, 2020
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletionpackage-lock.json
View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

2 changes: 1 addition & 1 deletionpackage.json
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
{
"name": "@coderoad/cli",
"version": "0.0.3",
"version": "0.0.4",
"description": "A CLI to build the configuration file for Coderoad Tutorials",
"main": "src/main.js",
"bin": {
Expand Down
231 changes: 57 additions & 174 deletionssrc/build.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,197 +2,80 @@ import * as yamlParser from "js-yaml";
import * as path from "path";
import * as _ from "lodash";
import * as fs from "fs";
import * asT from "../typings/tutorial";
import * asutil from "util";
import { parse } from "./utils/parse";
// import validate from './validator';

// import not working
const simpleGit = require("simple-git/promise");

const workingDir = "tmp";

function rmDir(dir: string, rmSelf = false) {
try {
let files;
rmSelf = rmSelf === undefined ? true : rmSelf;

try {
files = fs.readdirSync(dir);
} catch (e) {
console.log(`Sorry, directory '${dir}' doesn't exist.`);
return;
}

if (files.length > 0) {
files.forEach(function (filePath: string) {
if (fs.statSync(path.join(dir, filePath)).isDirectory()) {
rmDir(path.join(dir, filePath));
} else {
fs.unlinkSync(path.join(dir, filePath));
}
});
}

if (rmSelf) {
// check if user want to delete the directory ir just the files in this directory
fs.rmdirSync(dir);
}
} catch (error) {
return error;
}
}
import { getArg } from "./utils/args";
import { getCommits, CommitLogObject } from "./utils/commits";
import * as T from "../typings/tutorial";

async function cleanupFiles(workingDir: string) {
try {
const gitModule = simpleGit(process.cwd());
const write = util.promisify(fs.writeFile);
const read = util.promisify(fs.readFile);

await gitModule.subModule(["deinit", "-f", workingDir]);
await gitModule.rm(workingDir);
await gitModule.reset(["HEAD"]);
rmDir(path.join(process.cwd(), ".git", "modules", workingDir));
rmDir(workingDir);
} catch (error) {
return error;
}
}
export type BuildConfigOptions = {
text: string; // text document from markdown
config: T.Tutorial; // yaml config file converted to json
commits: CommitLogObject; // an object of tutorial positions with a list of commit hashes
};

export type BuildOptions = {
repo: string; // Git url to the repo. It should finish with .git
codeBranch: string; // The branch containing the tutorial code
setupBranch: string; // The branch containing the tutorialuration files
isLocal: boolean; // define if the repo is local or remote
type BuildArgs = {
dir: string;
markdown: string;
yaml: string;
output: string;
};

async function build({ repo, codeBranch, setupBranch, isLocal }: BuildOptions) {
let git: any;
let isSubModule = false;
let localPath: string;

if (isLocal) {
git = simpleGit(repo);
localPath = repo;
} else {
const gitTest = simpleGit(process.cwd());
const isRepo = await gitTest.checkIsRepo();
localPath = path.join(process.cwd(), workingDir);

if (isRepo) {
await gitTest.submoduleAdd(repo, workingDir);

isSubModule = true;
} else {
await gitTest.clone(repo, localPath);
}

git = simpleGit(localPath);
}

await git.fetch();

// checkout the branch to load tutorialuration and content branch
await git.checkout(setupBranch);

// Load files
const _content = fs.readFileSync(path.join(localPath, "TUTORIAL.md"), "utf8");
let _config = fs.readFileSync(path.join(localPath, "coderoad.yaml"), "utf8");

const tutorial = parse(_content, _config);

// Checkout the code branches
await git.checkout(codeBranch);

// Load all logs
const logs = await git.log();
const parseArgs = (args: string[]): BuildArgs => {
// default .
const dir = args[0] || ".";
// -o --output - default coderoad.json
const output =
getArg(args, { name: "output", alias: "o" }) || "coderoad.json";
// -m --markdown - default TUTORIAL.md
const markdown =
getArg(args, { name: "markdown", alias: "m" }) || "TUTORIAL.md";
// -y --yaml - default coderoad-config.yml
const yaml =
getArg(args, { name: "coderoad-config.yml", alias: "y" }) ||
"coderoad-config.yml";

return {
dir,
output,
markdown,
yaml,
};
};

// Filter relevant logs
constparts =new Set();
async function build(args: string[]) {
constoptions =parseArgs(args);

for (const commit of logs.all) {
const matches = commit.message.match(
/^(?<stepId>(?<levelId>L\d+)S\d+)(?<stepType>[QA])?/
);
// path to run build from
const localPath = path.join(process.cwd(), options.dir);

if (matches && !parts.has(matches[0])) {
// Uses a set to make sure only the latest commit is proccessed
parts.add(matches[0]);
// load files
const [_markdown, _yaml] = await Promise.all([
read(path.join(localPath, options.markdown), "utf8"),
read(path.join(localPath, options.yaml), "utf8"),
]);

// Add the content and git hash to the tutorial
if (matches.groups.stepId) {
// If it's a step: add the content and the setup/solution hashes depending on the type
const level: T.Level | null =
tutorial.levels.find(
(level: T.Level) => level.id === matches.groups.levelId
) || null;
if (!level) {
console.log(`Level ${matches.groups.levelId} not found`);
} else {
const theStep: T.Step | null =
level.steps.find(
(step: T.Step) => step.id === matches.groups.stepId
) || null;
const config = yamlParser.load(_yaml);

if (!theStep) {
console.log(`Step ${matches.groups.stepId} not found`);
} else {
if (matches.groups.stepType === "Q") {
theStep.setup.commits.push(commit.hash.substr(0, 7));
} else if (
matches.groups.stepType === "A" &&
theStep.solution &&
theStep.solution.commits
) {
theStep.solution.commits.push(commit.hash.substr(0, 7));
}
}
}
} else {
// If it's level: add the commit hash (if the level has the commit key) and the content to the tutorial
const theLevel: T.Level | null =
tutorial.levels.find(
(level: T.Level) => level.id === matches.groups.levelId
) || null;
const commits: CommitLogObject = await getCommits(config.config.repo.branch);

if (!theLevel) {
console.log(`Level ${matches.groups.levelId} not found`);
} else {
if (_.has(theLevel, "tutorial.commits")) {
if (theLevel.setup) {
theLevel.setup.commits.push(commit.hash.substr(0, 7));
}
}
}
}
}
}
// Otherwise, continue with the other options
const tutorial: T.Tutorial = await parse({
text: _markdown,
config,
commits,
});

// cleanup the submodules
if (!isLocal) {
let cleanupErr;

if (isSubModule) {
cleanupErr = await cleanupFiles(workingDir);
if (tutorial) {
if (options.output) {
await write(options.output, JSON.stringify(tutorial), "utf8");
} else {
cleanupErr = rmDir(path.join(process.cwd(), workingDir));
}

if (cleanupErr) {
console.log(
`Error when deleting temporary files on ${
isSubModule ? "module" : "folder"
} ${workingDir}.`
);
console.log(JSON.stringify(tutorial, null, 2));
}
}

// const isValid = validate(tutorial);

// if (!isValid) {
// console.log(JSON.stringify(validate.errors, null, 2));
// return;
// }

return tutorial;
}

export default build;
Loading

[8]ページ先頭

©2009-2025 Movatter.jp