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 from1 commit
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
PrevPrevious commit
NextNext commit
git commit check changes in progress
Signed-off-by: shmck <shawn.j.mckay@gmail.com>
  • Loading branch information
@ShMcK
ShMcK committedMay 31, 2020
commit1b47da5651ecff88778ff0a37a1952d78a334e9b
191 changes: 68 additions & 123 deletionssrc/build.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,12 +2,16 @@ 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 { getArg } from "./utils/args";
import { getCommits } from "./utils/commits";
import * as T from "../typings/tutorial";

const write = util.promisify(fs.writeFile);
const read = util.promisify(fs.readFile);

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

const workingDir = "tmp";

Expand DownExpand Up@@ -56,143 +60,84 @@ async function cleanupFiles(workingDir: string) {
}
}

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
output: string;
export type BuildConfigOptions = {
text: string; // text document from markdown
config: T.Tutorial; // yaml config file converted to json
commits: { [key: string]: 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);
async function generateConfig({ text, config, commits }: BuildConfigOptions) {
const tutorial = parse(text, config);

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

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

git = simpleGit(localPath);
}

await git.fetch();
// const isValid = validate(tutorial);

// checkout the branch to load tutorialuration and content branch
await git.checkout(setupBranch);
// if (!isValid) {
// console.log(JSON.stringify(validate.errors, null, 2));
// return;
// }

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

const tutorial = parse(_content, _config);
type BuildArgs = {
dir: string;
markdown: string;
yaml: string;
output: string;
};

// Checkout the code branches
await git.checkout(codeBranch);
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,
};
};

// Load all logs
constlogs =await git.log();
async function build(args: string[]) {
constoptions =parseArgs(args);

//Filter relevant logs
constparts =new Set();
//path to run build from
constlocalPath =path.join(process.cwd(), options.dir);

for (const commit of logs.all) {
const matches = commit.message.match(
/^(?<stepId>(?<levelId>L\d+)S\d+)(?<stepType>[QA])?/
);
// load files
const [_markdown, _yaml] = await Promise.all([
read(path.join(localPath, options.markdown), "utf8"),
read(path.join(localPath, options.yaml), "utf8"),
]);

if (matches && !parts.has(matches[0])) {
// Uses a set to make sure only the latest commit is proccessed
parts.add(matches[0]);
const config = yamlParser.load(_yaml);

// 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;

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;

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));
}
}
}
}
}
}
const commits = getCommits(config.config.repo.branch);

// cleanup the submodules
if (!isLocal) {
let cleanupErr;
// Otherwise, continue with the other options
const tutorial: T.Tutorial = await generateConfig({
text: _markdown,
config,
commits,
});

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;
141 changes: 7 additions & 134 deletionssrc/cli.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,152 +1,25 @@
import * as inquirer from "inquirer";
import * as fs from "fs";
import * as T from "../typings/tutorial";
import build, { BuildOptions } from "./build";
import build from "./build";
import create from "./create";

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

type Q = inquirer.Question<any> & { choices?: string[] };

type ParsedArgs = {
command: string;
git?: string;
dir?: string;
codeBranch: string;
setupBranch: string;
output?: string;
help: string;
version?: string;
};

type Options = {
repo: string;
setupBranch: string;
codeBranch: string;
output: string;
isLocal: boolean;
};

const localGit = "Local directory";
const remoteGit = "Git remote address";

export async function promptForMissingOptions(
options: ParsedArgs
): Promise<Options> {
const questions: Q[] = [];

// if no git remote addres is provided, assume current folder
if (!options.git && !options.dir) {
// check if the current dir is a valid repo
const git = simpleGit(process.cwd());
const isRepo = await git.checkIsRepo();

if (!isRepo) {
questions.push({
type: "list",
name: "source",
message: `The current directory (${process.cwd()}) is not a valid git repo. Would you like to provide a...`,
choices: [localGit, remoteGit],
default: localGit,
});

questions.push({
type: "input",
name: "localGit",
message:
"Please, provide a local directory of the valid git repository: ",
when: (input: any) => input.source === localGit,
});

questions.push({
type: "input",
name: "remoteGit",
message: "Please, provide the address of a remote git repository: ",
when: (input: any) => input.source === remoteGit,
});
}
}
// if both local dir and remote repos are provided
else if (options.git && options.dir) {
questions.push({
type: "list",
name: "source",
message:
"A local git directory and a remote address were both provided. Please, choose either one or those to parse: ",
choices: [localGit, remoteGit],
default: localGit,
});
}

// if the branch containing the code is not provided
if (!options.codeBranch) {
questions.push({
type: "input",
name: "codeBranch",
message: "Please, provide the branch with the code commits: ",
});
}

// if the branch containing the setup files is not provided
if (!options.setupBranch) {
questions.push({
type: "input",
name: "setupBranch",
message:
"Please, provide the branch with the setup files (coderoad.yaml and tutorial.md): ",
});
}

const answers: any = await inquirer.prompt(questions);

let repo: string;
let isLocal: boolean;

if (answers.source) {
repo = (answers.source === localGit ? options.dir : options.git) || "";
isLocal = answers.source === localGit;
} else {
repo = options.dir || options.git || process.cwd();
isLocal = options.git ? false : true;
}

return {
repo,
setupBranch: options.setupBranch || answers.setupBranch,
codeBranch: options.codeBranch || answers.codeBranch,
output: options.output || ".",
isLocal,
};
}

export async function cli(args: string[]): Promise<void> {
const command: string = args[2];
export async function cli(rawArgs: string[]): Promise<void> {
const command: string = rawArgs[2];
const args = rawArgs.slice(3);

switch (command) {
case "--version":
case "-v":
const version = require("../package.json").version;
console.log(`v${version}`);
return;
case "build":
// Otherwise, continue with the other options
// const options: BuildOptions = await promptForMissingOptions(parsedArgs);
// const tutorial: T.Tutorial = await build(options);

// if (tutorial) {
// if (options.output) {
// fs.writeFileSync(options.output, JSON.stringify(tutorial), "utf8");
// } else {
// console.log(JSON.stringify(tutorial, null, 2));
// }
// }
case "build":
build(args);
break;

case "create":
create(process.cwd());
break;

case "--help":
case "-h":
default:
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp