Skip to content

fix coderoad create #16

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 1, 2020
Merged
Show file tree
Hide file tree
Changes from all 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 deletion package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@coderoad/cli",
"version": "0.1.1",
"version": "0.1.2",
"description": "A CLI to build the configuration file for Coderoad Tutorials",
"keywords": [
"coderoad",
Expand Down
41 changes: 19 additions & 22 deletions src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,28 @@ type BuildArgs = {
output: string;
};

const parseArgs = (args: string[]): BuildArgs => {
// default .
const dir = args[0] || ".";

// -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: "yaml", alias: "y" }) || "coderoad.yaml";
// -o --output - default coderoad.json
const output =
getArg(args, { name: "output", alias: "o" }) || "tutorial.json";

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

async function build(args: string[]) {
let options: BuildArgs;
try {
options = parseArgs(args);
// default .
const dir = args[0].match(/^-/) ? "." : args[0];
// -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: "yaml", alias: "y" }) || "coderoad.yaml";
// -o --output - default coderoad.json
const output =
getArg(args, { name: "output", alias: "o" }) || "tutorial.json";

console.log(`Building CodeRoad ${output}...`);

options = {
dir,
output,
markdown,
yaml,
};
} catch (e) {
console.error("Error parsing build logs");
console.error(e.message);
Expand Down
2 changes: 1 addition & 1 deletion src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export async function cli(rawArgs: string[]): Promise<void> {
break;

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

case "--help":
Expand Down
69 changes: 60 additions & 9 deletions src/create.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,75 @@
import ncp from "ncp";
import * as path from "path";
import { promisify } from "util";
import { getArg } from "./utils/args";

const copy = promisify(ncp);

const copyFiles = async (filePath: string): Promise<void> => {
type CreateArgs = {
dir: string;
lang: string;
testRunner: string;
};

async function create(args: string[]): Promise<void> {
let options: CreateArgs;

// default .
const dir = !args.length || args[0].match(/^-/) ? "." : args[0];
const lang = getArg(args, { name: "lang", alias: "l" }) || "js";
const testRunner =
getArg(args, { name: "testRunner", alias: "t" }) || "mocha";

// validate lang
if (!["js"].includes(lang)) {
throw new Error(`Language ${lang} not supported yet in create`);
}

// validate test runner
if (!["mocha"].includes(testRunner)) {
throw new Error(`Test Runner ${testRunner} not supported yet in create`);
}

console.info(`Creating CodeRoad project for ${lang} ${testRunner}`);

options = {
dir,
lang,
testRunner,
};

const localPath = path.join(process.cwd(), options.dir);

// TODO: git init ?

// copy tutorial file
const pathToSrc = path.join(__dirname, "..", "src");
const templateDirectory = path.resolve(pathToSrc, "templates");

const markdownPath = path.join(templateDirectory, "TUTORIAL.md");
const targetMarkdownPath = path.join(localPath, "TUTORIAL.md");
try {
const pathToSrc = path.join(__dirname, "..", "src");
const templateDirectory = path.resolve(pathToSrc, "templates");
const targetDirectory = process.cwd();
await copy(markdownPath, targetMarkdownPath, {
clobber: false,
});
} catch (e) {
console.error("Error on creating markdown file");
console.error(e.message);
}

await copy(templateDirectory, targetDirectory, {
// TODO: copy master yaml
const pathToYaml = path.join(templateDirectory, `${lang}-${testRunner}`);
const targetYamlPath = path.join(localPath, "coderoad.yaml");
try {
await copy(pathToYaml, targetYamlPath, {
clobber: false,
});
} catch (e) {
console.log("Error on creating the files:");
console.log(JSON.stringify(e, null, 1));
console.error("Error on creating yaml file");
console.error(e.message);
}
};

const create = copyFiles;
// TODO: copy code files with commits
}

export default create;
File renamed without changes.
File renamed without changes.
14 changes: 6 additions & 8 deletions src/templates/TUTORIAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,37 @@

Short description to be shown as a tutorial's subtitle


## L1 Put Level's title here

> Level's summary: a short description of the level's content in one line.

The level is identified and distributed following the regex:
The level is identified and distributed following the regex:

```js
/^(##\s(?<levelId>L\d+)\s(?<levelTitle>.*)\n*(>\s*(?<levelSummary>.*))?\n+(?<levelContent>[^]*))/
/^(##\s(?<levelId>L\d+)\s(?<levelTitle>.*)\n*(>\s*(?<levelSummary>.*))?\n+(?<levelContent>[^]*))/;
```

The Level can be split into steps or have no steps. Levels without steps are meant to be used as only informative content, for example: use a Level without steps at the end of the tutorial to congratulate the student and provide some additional related resources.

Tutorial's content. It can span through multiple paragraphs and use headers `####` and `#####`.
Tutorial's content. It can span through multiple paragraphs and use headers `####` and `#####`.

Steps are identified and their content described using the following regex:

```js
/^(###\s(?<stepId>(?<levelId>L\d+)S\d+)\s(?<stepTitle>.*)\n+(?<stepContent>[^]*))/
/^(###\s(?<stepId>(?<levelId>L\d+)S\d+)\s(?<stepTitle>.*)\n+(?<stepContent>[^]*))/;
```

The numbers identifying the levels and steps are irrelevant but keep in mind that they will be executed in order. A level with id `10` will be executed before another one with id `20` and so on. These `ids` should have a match in the configuration file (`coderoad.yaml`).


### L1S1 A step title (not being shown on the extension at this moment)

Short description of the step's purpose. Should be short and fit in one line

**Important**

1. Both level and step ids must have an entry with the same id on the configuration file;
2. Step Ids are based on its level id. Any step from level `L234` must start with `L234S`, followed by the sequential digits.


### L1S2 Another step

Step's short description.
Step's short description.
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ config:
## Commits to load to setup the test runner. Optional.
##
setup:
## A list of commits to load to setup the tutorial
commits: []
# - commit1
# - commit2
## A list of commands to run to configure the tutorial
Expand Down
2 changes: 1 addition & 1 deletion src/utils/validate.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import schema from "./schema";
import schema from "../schema";

// https://www.npmjs.com/package/ajv
// @ts-ignore ajv typings not working
Expand Down