diff --git a/README.md b/README.md index e69c671d..c0ae8eb9 100644 --- a/README.md +++ b/README.md @@ -50,8 +50,6 @@ Build and share your own interactive tutorials. Learn more about [how tutorials area created](https://coderoad.github.io/docs/build-tutorial). -See an [interactive visualization](https://coderoad.github.io/coderoad-visual/) of a tutorial repository. - ## Editing Tutorials Tutorials can be edited directly as markdown on Github. diff --git a/docs/docs/build-tutorial.md b/docs/docs/build-tutorial.md index fce7d2a2..c60185eb 100644 --- a/docs/docs/build-tutorial.md +++ b/docs/docs/build-tutorial.md @@ -4,9 +4,12 @@ title: Building a Tutorial sidebar_label: Building a Tutorial --- -A tutorial is made up of two parts: +A tutorial is made from a github repository that includes three parts: 1. Markdown -2. Git Commits +2. YAML +3. Git Commits + +The Markdown and YAML live on the master branch of the repo, and the Git commits live on a version branch. We'll go into each in detail in more detail. diff --git a/docs/docs/create-a-practice-tutorial.md b/docs/docs/create-a-practice-tutorial.md new file mode 100644 index 00000000..709e087d --- /dev/null +++ b/docs/docs/create-a-practice-tutorial.md @@ -0,0 +1,309 @@ +--- +id: create-a-practice-tutorial +title: Create a Practice Tutorial +sidebar_label: Create a Practice Tutorial +--- + +## Create a CodeRoad tutorial + +Follow these instructions carefully to create your first CodeRoad tutorial. + +### Create a repo +- Go to GitHub and create a new repository for yourself named `first-tutorial` +- After you click create, it takes you to the repo. Copy the URL for the repo, it should look like: `https://github.com/your-username/first-tutorial.git` +- Open a terminal locally and find a place to clone your repo. Enter `git clone https://github.com/your-username/first-tutorial.git` with the repo URL you copied in place of that URL to clone it +- Create a `.gitignore` file in your repo and add this to it: +```md +node_modules +package-lock.json +``` +Add anything else that may interfere such as `.DS_Store` if you are on a mac. + +### Create the markdown +- Create a new file in your repo named `TUTORIAL.md`. + +This is the file that describes the structure of a tutorial. It contains all the lessons, lesson titles, descriptions, test text and all the other verbiage that will be displayed to a user. Enter this markdown into the file and save it: + +```md +# Introduction + +This is an introduction to your tutorial. It will show up on the first page when your tutorial is started. + +## L1 Create index.html + +> Optional summary for L1 + +Here's where you can put a description, examples, and instructions for the lesson. + +### L1S1 Level 1 Step 1 + +This is the test text. Create an `index.html` file to pass this lesson. + +#### HINTS + +* This is a hint to help people through the test +* Second hint for L1S1, don't worry if the hints don't show up yet +``` + +The above tutorial has an introduction page and one lesson. + +### Commit to github +- Back in the terminal, add all your new files to be committed with `git add .` +- Commit them with `git commit -m "create markdown"` +- Push them to github with `git push origin master` + +### Create a version branch +- Create and checkout a new orphan branch with `git checkout --orphan v0.1.0`. + +This will make a branch that isn't created from master, so it has no commit history. It will hold the tests for your tutorial. Each test is its own commit. You can also add an optional commit for a solution to each test. +- Check your `git status` +- Delete the tutorial file from this branch with `git rm -f TUTORIAL.md` + +### Create your project files +This branch is also where users create their projects, modify files for a tutorial, and most anything they need to do. +- Make a new folder named `coderoad` on your branch. + +This folder will hold as much of the CodeRoad stuff as it can so users aren't confused with extra files in their projects. +- Go to the `coderoad` folder in your terminal and run `npm init`. Press enter until you are through the setup. +- Open the `package.json` file you just made and make it look like this... + +```js +{ + "name": "coderoad", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "programmatic-test": "mocha --reporter=mocha-tap-reporter", + "test": "mocha" + }, + "author": "", + "license": "ISC" +} + +``` + +These scripts will be for CodeRoad and you to test things. + +- From the terminal, in your `coderoad` folder, run `npm install --save mocha mocha-tap-reporter` to install some depenedencies +- **Go back to the main repo folder** and add your changes with `git add .` +- Commit your files with `git commit -m "INIT"` + +The message of `INIT` in all caps is necessary. This message is used to add project setup files and anthing else you want to add before a user starts the tutorial. +- Push and Create a branch on your remote with `git push -u origin v0.1.0` + +### Create the first test +- Go in the `coderoad` folder and create new folder named `test` in it +- Create a file named `first-tutorial.test.js` in the `test` folder +- Add this to the file: + +```js +const assert = require('assert'); +const fs = require('fs'); +const util = require('util'); +const path = require('path'); + +const readdir = util.promisify(fs.readdir); +const getRootDir = async (dir = process.cwd()) => { + const pathToRoot = path.join(dir, '..'); + const rootDir = await readdir(pathToRoot); + + if (!rootDir) { + throw new Error(`Could not find folder ${pathToRoot}`); + } + + return rootDir; +} + +describe("first-tutorial folder", () => { + let rootDir; + before(async () => { + rootDir = await getRootDir(); + }); + + it('should have an index.html file', async () => { + assert(rootDir.indexOf('index.html') >= 0) + }); +}); +``` + +This will be the test for the one lesson in your tutorial. You can see that it checks for the existence of an `index.html` file in the root folder. + +- In the `coderoad` folder, run `npm run programmatic-test` from the terminal + +It will fail since `index.html` doesn't exist. +- Create an `index.html` file in the main repo folder and run the test again + +It should pass this time. So when a user creates the `index.html` file, this test will run, and the lesson will pass. + +### Commit your first test +- Go back to the main repo folder and add the test file to be committed with `git add coderoad/.` +- Commit it with `git commit -m "L1S1Q"` + +That stands for "Lesson 1 Step 1 Question". You can put an additional note after it, but it has to start with those letters so CodeRoad knows that this is the test for the L1S1 step. +- After that, add the index file with `git add index.html` +- Commit the file with `git commit -m "L1S1A"` + +That stands for "Lesson 1 Step 1 Answer", and it's the solution to the test. +- Take a quick look at the commit history with `git log`. You can see the messages there, they align with the titles you put in the markdown and there's one commit for the test (`L1S1Q`) and an optional commit for the solution (`L1S1A`) +- Push your changes to github with `git push origin v0.1.0` + +### Create the YAML file +- Go back your your master branch with `git checkout master` +You can think of these two branches like separate repositories, the branches will never merge and the files will always be different, even if some look the same. +- Create a new file named `coderoad.yaml` and add this to it: + +```yml +version: '0.1.0' +config: + testRunner: + command: ./node_modules/.bin/mocha + args: + tap: --reporter=mocha-tap-reporter + setup: + commands: + - npm install + directory: coderoad + repo: + uri: https://github.com/moT01/first-tut + branch: v0.1.0 + dependencies: + - name: node + version: '>=10' +levels: + - id: L1 + steps: + - id: L1S1 + setup: + subtasks: false +``` + +Replace the `repo uri` URL with your github repo, note that it's just the username and repo in the URL. This file links everything together. You can see the repo URL and the branch that you created. And the `L1` and `L1S1` id's that match the markdown. You can also add commands that will run when a lesson is started, as well as a host of other things. + +- Add this with `git add .` +- Commit it with `git commit -m "create yaml"` + +The commit messages on master can be whatever you want. +- Push it to github with `git push origin master` + +### Build the config.json file +You created the three things a tutorial needs from you; the markdown, the commits, and the yaml. Now you can build it. If you haven't installed the CodeRoad CLI tools, use `npm install -g @coderoad/cli` to do so. +- Run `coderoad build` from the terminal on the master branch + +If you didn't get any errors, it will have created a `tutorial.json` file which is what CodeRoad uses to find all the files, commits, and instructions you created. You should see it in your repo now. + +### Open your tutorial +To check out your tutorial, install the CodeRoad extension to VS Code if you haven't already +- Open a new VS Code window +- Put a **single empty folder** in the workspace +- Open the command palette with `ctrl+shift+p` +- Enter `CodeRoad: Start` in the search to start CodeRoad +- Click `Start New Tutorial` +- Click the `File` option +- Click `Upload` +- Find the `tutorial.json` file that you created in your repo folder and upload it + +### Review +Success! You can see the introduction page. It may not be a bad idea to take a look at the markdown file again to see it next to the running tutorial. + +Notice that when you click the `start` button, you can see that `npm install` is run in the `coderoad` folder, and the dependencies are installed. This is an instruction in your `coderoad.yaml` file. + +After you click start, open up any file and press `cmd+s` to save. This will run the tests. They should fail. After that, create the `index.html` file, and save it. The tests should run and pass this time :smile: + +Keep this VS Code window open and go back to your other one. + +### Add a second lesson +Your tutorial probably needs more than one lesson. +- Go back to the markdown file and add this at the bottom (make sure there's an empty line between the two lessons): + +```md +## L2 Add DOCTYPE + +> Add a DOCTYPE to an HTML file + +HTML files should have a `DOCTYPE`. You can add one at the top of the `index.html` file like this: ``. + +### L2S1 + +Add the DOCTYPE + +#### HINTS + +* Add `` at the top of `index.html` and save the file +``` + +#### Use git to: +- Add all the files +- Commit the files with any message +- Push the changes to github + +### Add second lesson test +- Checkout your version branch again +- Add a new test to your `.test` file below the other one, it can look like this: + +```js +const readFile = util.promisify(fs.readFile); +const getIndexFile = async (dir = process.cwd()) => { + const pathToIndex = path.join(dir, '..', 'index.html'); + const indexFile = await readFile(pathToIndex); + + if (!indexFile) { + throw new Error(`Could not find ${pathToIndex}`); + } + return indexFile; +} + +describe("index.html", () => { + let indexFile; + before(async () => { + indexFile = await getIndexFile(); + }); + + it('should have a DOCTYPE', () => { + assert(//i.test(indexFile)); + }); +}); +``` + +That should check if `` was added to the `index.html` file. +- Run the test to make sure it fails (`npm run programmatic-test` from the `coderoad` folder) + +There should be one passing and one failing test +- Add `!` to the `index.html` file +- Run the test again to see if it passed after adding that + +### Commit second test +#### Go to the root folder and: +- Add **only** the `.test` file to git to be committed +- Commit it with a message of "L2S1Q" +- Add the `index.html` file to be committed +- Commit it with a message of "L2S1A" +- Push your changes to github to your `v0.1.0` branch + +### Update the YAML +You added another lesson in the markdown, and the tests for it. Just need to update the YAML +- Go back to the master branch +- Add this at the bottom of the `.yaml` file, make sure the indentation is perfect and aligns with the first lesson: + +```yml + - id: L2 + steps: + - id: L2S1 + setup: + files: + - index.html +``` + +- Add, Commit, and Push your changes + +### Rebuild +- Run `coderoad build` again on your master branch (cross your fingers). + +### Restart the tutorial +- Go back to your CodeRoad tutorial if its still open +- In order to start over, close CodeRoad +- Delete All the files from the workspace, but leave the top level folder there +- Start CodeRoad back up +- Start a new tutorial using the `tutorial.json` file you just created. + +You should have two lessons to go through now :smile: diff --git a/docs/docs/edit-tutorial.md b/docs/docs/edit-tutorial.md index 7411b002..ca2287a3 100644 --- a/docs/docs/edit-tutorial.md +++ b/docs/docs/edit-tutorial.md @@ -37,15 +37,15 @@ git rebase -i --root Choose the commit you want to edit ```text -pick b73feaf commit 2.1 setup -pick 0a3aa83 commit 2.1 solution -pick 0d67935 commit 3.1 setup +pick b73feaf INIT +pick 0a3aa83 L1S1Q +pick 0d67935 L2S1Q ``` -Let's say we want to edit step 2.1 Change the word pick to "edit" or "e". +Let's say we want to edit step `L1S1Q` Change the word pick to "edit" or "e" ```text -e b73feaf commit 2.1 setup +e 0a3aa83 L1S1Q ``` Save the modified rebase summary file and your rebase will start. Git will run through the commits until the first flagged "edit", then stop at the commit. @@ -62,21 +62,21 @@ If you encounter any merge conflicts along the way, resolve them, add the change ### Adding Additional Commits -Let's say we wanted to add an additional commit after the 2.1 solution. +Let's say we wanted to add an additional commit after the `L1S1Q`. ```text -pick b73feaf commit 2.1 setup -pick 0a3aa83 commit 2.1 solution -pick 0d67935 commit 3.1 setup +pick b73feaf INIT +pick 0a3aa83 L1S1Q +pick 0d67935 L2S1Q ``` To cause the rebase to pause after a commit, use the word "break" or "b". ```text -pick b73feaf commit 2.1 setup -pick 0a3aa83 commit 2.1 solution +pick b73feaf INIT +pick 0a3aa83 L1S1Q break -pick 0d67935 commit 3.1 setup +pick 0d67935 L2S1Q ``` Save the rebase summary file to start the process. The process should stop at the "break". @@ -91,20 +91,20 @@ If you encounter any merge conflicts along the way, resolve them, add the change ### Rewording a Commit -Let's say we wanted to change the title of commit "3.1" to "2.2". +Let's say we wanted to change the title of commit "L2S1Q" to "L1S1A". ```text -pick b73feaf commit 2.1 setup -pick 0a3aa83 commit 2.1 solution -pick 0d67935 commit 3.1 setup +pick b73feaf INIT +pick 0a3aa83 L1S1Q +pick 0d67935 L2S1Q ``` You can use the "reword" or "r" method. ```text -pick b73feaf commit 2.1 setup -pick 0a3aa83 commit 2.1 solution -reword 0d67935 commit 3.1 setup +pick b73feaf INIT +pick 0a3aa83 L1S1Q +reword 0d67935 L2S1Q ``` When you're finished, just save the file and the commits will be updated. diff --git a/docs/docs/errors.md b/docs/docs/errors.md new file mode 100644 index 00000000..45bb0f31 --- /dev/null +++ b/docs/docs/errors.md @@ -0,0 +1,12 @@ +--- +id: errors +title: Errors +sidebar_label: Errors +--- + +```shell +Error loading commits: +Callback must be a function +``` + +If you get the above error when running `coderoad build`, check your node version with `node --version`. If it's less than version 12, try upgrading and run the command again. \ No newline at end of file diff --git a/docs/docs/examples.md b/docs/docs/examples.md new file mode 100644 index 00000000..d9a530a4 --- /dev/null +++ b/docs/docs/examples.md @@ -0,0 +1,10 @@ +--- +id: examples +title: Examples +sidebar_label: Examples +--- + +Check out some of these tutorial repositories for reference: + +- https://github.com/coderoad/fcc-learn-npm +- https://github.com/coderoad/fcc-basic-node-and-express diff --git a/docs/docs/git-timeline.md b/docs/docs/git-timeline.md index 124b24dd..295ec210 100644 --- a/docs/docs/git-timeline.md +++ b/docs/docs/git-timeline.md @@ -4,17 +4,21 @@ title: Git Timeline sidebar_label: Git Timeline --- -A CodeRoad tutorial runs on Git commits: +A CodeRoad tutorial runs on Git commits. These will be the commits on the version branch of a repo. -1. init +1. INIT - Basic project setup code - test runner dependencies - .vscode workspace configurations -2. setup +2. L1S1Q - add unit tests - add unit testing dependencies - add scaffolding code (if needed) -3. solution +3. L1S1A - the code required to make the tests pass Then repeat steps 2 & 3. + +The commit messages for these must start with those case sensitive letters. "L1S1Q" stands for "Lesson 1 Step 1 Question" and "L1S1A" stand for "Lesson 1 Step 1 Answer". The `L1S1` part of each commit message needs to match the id's from the markdown and yaml. + +You can add additional text after those required characters if you want. \ No newline at end of file diff --git a/docs/docs/markdown.md b/docs/docs/markdown.md index cefdff8d..a3f4ebd1 100644 --- a/docs/docs/markdown.md +++ b/docs/docs/markdown.md @@ -4,7 +4,7 @@ title: Markdown sidebar_label: Markdown --- -The markdown is the meta data that pulls the tutorial together. +The markdown file lives on the master branch and has a name of `TUTORIAL.md`. It describes the structure of a tutorial and contains all the lessons, their descriptions, and the text users will read. ### Example @@ -13,51 +13,52 @@ See a rough example below: ```md # Tutorial Title -> Tutorial summary description +> Tutorial introduction paragraph -\`\`\`config -config: -testRunner: -command: command to run tests -fileFormats: - fileType (eg. JS, TS, etc) -repo: -uri: https://path/to/repo -branch: git-branch -\`\`\` +## L1 Lesson 1 -## Level Name +> Lesson 1 summary -> Level summary description +Lesson 1 decription and instructions. -Level content in a paragraph. The text that appears when you load a level. +### L1S1 Lesson 1 Step 1 -### Step Name +Test text for L1S1 -\`\`\`config -setup: -files: - file-to-open.js -commits: - 'setup-commit-hash' -commands: - command to run -watchers: - files to watch and run tests if they change -solution: -files: - file-to-open.js -commits: - 'solution-commit-hash' -\`\`\` +#### HINTS -Text to describe the step. -``` +* This is a hint for L1S1 +* This is another hint for L1S1 + +## L2 Lesson 2 + +> Lessons 2 summary + +Lesson 2 content. + +### L2S1 Lesson 2 Step 1 + +Test text -### Format +#### HINTS + +* Hint for L2S1 + +### L2S2 Lesson 2 Step 2 + +Test text for L2S2 + +#### HINTS + +* Hint for L2S2 +``` -From a hierarchy perspective, a tutorial is made up of levels, which are made up of steps. When each level or step is loaded, if a config is provided, it will run in the extension. +#### Explanation -Level +The example above has an introduction page and two lessons. -- Optional level setup config -- Steps - - Step setup config - - Step solution config +The introduction page is first thing users will see when they start a tutorial. It shows an overview of all the lessons and displays the lesson summary. -### Parser +Lessons need to start with `## Lx ` where `x` is the lesson number. The text after `Lx` will display as the lesson title. -Markdown is parsed by a CLI script and converted into JSON. The JSON is loaded as the core of the tutorial. +The "Steps", or test text, need to start with `LxSy` where `x` matches the lesson number and `y` is the number for a "step". \ No newline at end of file diff --git a/docs/docs/setup.md b/docs/docs/setup.md index 878e9726..44de3d89 100644 --- a/docs/docs/setup.md +++ b/docs/docs/setup.md @@ -15,7 +15,7 @@ Install CodeRoad from [this link in the VSCode Marketplace](https://marketplace. - OS: MacOS, Windows, Linux - VSCode 1.39.2+ -- Node.js 10+ +- Node.js 12+ - Git ### Start diff --git a/docs/docs/test-runner.md b/docs/docs/test-runner.md index a048346d..c7ee722f 100644 --- a/docs/docs/test-runner.md +++ b/docs/docs/test-runner.md @@ -25,6 +25,6 @@ See an example using “Mocha” and the “Mocha Tap Reporter”: } ``` -In this example, the extension can run `nom run programmatic-test` to run the tests as TAP, but the user can still run `nom run test` to see a more human readable output. +In this example, the extension can run `npm run programmatic-test` to run the tests as TAP, but the user can still run `npm run test` to see a more human readable output. Ideally, try to choose a test runner that performs quickly. If possible, avoid Jest as it has slow install and running times. diff --git a/docs/docs/yaml.md b/docs/docs/yaml.md new file mode 100644 index 00000000..a03ab081 --- /dev/null +++ b/docs/docs/yaml.md @@ -0,0 +1,151 @@ +--- +id: yaml +title: Yaml +sidebar_label: Yaml +--- + +### Description + +The `coderoad.yaml` file also lives on the master branch. It describes commands to run when a lesson starts, files to start on and many other things. + +### Example + +An example of this for the markdown on the previous page might look like this: + +```yaml +version: '0.1.0' +config: + testRunner: + command: npm run programmatic-test + args: + filter: --grep + tap: --reporter=mocha-tap-reporter + repo: + uri: https://github.com/username/repo + branch: v0.1.0 + dependencies: + - name: node + version: '>=10' +levels: + - id: L1 + steps: + - id: L1S1 + setup: + subtasks: false + - id: L2 + steps: + - id: L2S1 + setup: + files: + - index.html + - id: L2S2 + setup: + subtasks: false +``` + +Note that the id's for each lesson and step match the id's in the markdown. + +### Options + +Here's an example of many available options and what they do: + +```yaml +# A configuration file for a CodeRoad Tutorial +# This is a YAML-formatted file. +## Your personal version of the tutorial +## +version: "0.1.0" +## Data used to configure and setup the tutorial +## +config: + ## Test runner setup. + testRunner: + ## The command called to run the test runner. For example "npm run test", or a path to the test runner binary. Required. + command: ./node_modules/.bin/mocha + ## Standard arguments used by a given test runner + args: + ## The command arg used to filter tests. Used by "subtasks" + filter: --grep + ## The command arg used to convert test runner output to TAP format. See https://testanything.org/ for more. Required. + tap: --reporter=mocha-tap-reporter + ## The directory where to run the test runner from. If not specified, tests will run from the root of the project. Optional. + directory: coderoad + ## Commits to load to setup the test runner. Optional. + ## + setup: + # - commit1 + # - commit2 + ## A list of commands to run to configure the tutorial + commands: + [] + # - npm install + ## App versions helps to ensure compatability with the Extension + appVersions: + ## Ensure compatability with a minimal VSCode CodeRoad version + vscode: ">=0.7.0" + ## Repo information to load code from + ## + repo: + ## The uri path to the repo containing the code commits. Required. + ## + uri: "" + ## The branch on the repo uri that contains the code commits. Required. + branch: "" + + ## A list of tutorial dependencies to ensure the environment is setup for the tutorial. Optional. + ## The dependencies will be checked by running `dependency.name` --version and comparing it to the version provided. + ## + dependencies: + [] + ## The name of the dependency + # - name: node + # ## The version requirement. See https://github.com/npm/node-semver for options. + # version: '>=10' + +## A level is made up of +levels: + - id: L1 + steps: + ## Example 1: Opening files + - id: L1S1 + ## Setup for the first task. Required. + setup: + ## Files to open in a text editor when the task loads. Optional. + files: + - package.json + ## Solution for the first task. Required. + solution: + ## Files to open when the solution loads. Optional. + files: + - package.json + ## Example Two: Running commands + - id: L1S2 + setup: + ## CLI commands that are run when the task loads. Optional. + commands: + - npm install + solution: + commits: + - commit6 + commands: + - npm install + ## Example Three: Watchers + - id: L1S3 + setup: + files: + - package.json + ## Listeners that run tests when a file or directory changes. + watchers: + - package.json + - node_modules/some-package + solution: + files: + - package.json + ## Example Four: Subtasks + - id: L1S4 + setup: + ## A filter is a regex that limits the test results + filter: "^Example 2" + ## A feature that shows subtasks: all filtered active test names and the status of the tests (pass/fail). + subtasks: true +``` \ No newline at end of file diff --git a/docs/sidebars.js b/docs/sidebars.js index 293a42c2..b4b83f63 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -4,11 +4,15 @@ module.exports = { Build: [ 'build-tutorial', 'markdown', + 'yaml', 'git-timeline', - 'test-runner', 'init-commit', + 'test-runner', 'test-examples', 'edit-tutorial', + 'create-a-practice-tutorial', + 'examples', + 'errors' ], }, }