-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
## Description Implements the init command. When a student runs the init command it will do the following: - Ask for the batch ID and the API secret (since the CLI package will be public, it's still better if the secret is not hardcoded) - Check that the `Workspace` directory exists in the HOME of the machine - Clone the exercises directory as a cache in the CLI config root (`~/.config/sparta/exercises`) - Initialize the student's exercises repo in her `Workspace` - Display instructions for GitHub and open the new repository creation page in the browser ## Related Issue [Cu-7rp5br] ## Motivation and Context It will help students initialize their workspace for an easier start ## How Has This Been Tested? Manually for now. We're a little time bound. Tests will be added later once we're sure the CLI is ready for the upcoming session. ## Screenshots [![asciicast](https://asciinema.org/a/TIAby4UJNfzk69P4XHc03JhZo.svg)](https://asciinema.org/a/TIAby4UJNfzk69P4XHc03JhZo) ## Types of changes - ~Chore (non-breaking change which refactors / improves the existing code base)~ - ~Bug fix (non-breaking change which fixes an issue)~ - New feature (non-breaking change which adds functionality) - ~Breaking change (fix or feature that would cause existing functionality to change)~ ## Checklist: - ✅ My code follows the code style of this project. - ✅ My change requires a change to the documentation. - ✅ I have updated the documentation accordingly. - ✅ I have read the [**CONTRIBUTING**][CONTRIBUTING_FILE] document. - 🔴 I have added tests to cover my changes. - 🔴 All new and existing tests passed. [CONTRIBUTING_FILE]: https://github.com/fewlinesco/guidelines/blob/master/CONTRIBUTING.adoc
- Loading branch information
Yann IRBAH
authored
Sep 2, 2020
1 parent
bea6e16
commit 469fe2b
Showing
16 changed files
with
428 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
.DS_Store | ||
*-debug.log | ||
*-error.log | ||
/.nyc_output | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,58 @@ | ||
sparta | ||
====== | ||
|
||
Sparta CLI | ||
====== | ||
|
||
## Installation | ||
# Installation | ||
|
||
``` | ||
$ asdf install | ||
$ yarn install | ||
``` | ||
|
||
## Usage | ||
# Usage | ||
<!-- usage --> | ||
```sh-session | ||
$ npm install -g sparta | ||
$ sparta COMMAND | ||
running command... | ||
$ sparta (-v|--version|version) | ||
sparta/1.0.0 darwin-x64 node-v14.6.0 | ||
$ sparta --help [COMMAND] | ||
USAGE | ||
$ sparta COMMAND | ||
... | ||
``` | ||
<!-- usagestop --> | ||
# Commands | ||
<!-- commands --> | ||
* [`sparta help [COMMAND]`](#sparta-help-command) | ||
* [`sparta init`](#sparta-init) | ||
|
||
## `sparta help [COMMAND]` | ||
|
||
display help for sparta | ||
|
||
``` | ||
USAGE | ||
$ sparta help [COMMAND] | ||
ARGUMENTS | ||
COMMAND command to show help for | ||
## Commands | ||
OPTIONS | ||
--all see all commands in CLI | ||
``` | ||
|
||
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v3.2.0/src/commands/help.ts)_ | ||
|
||
## `sparta init` | ||
|
||
Initializes the Sparta workspace | ||
|
||
``` | ||
USAGE | ||
$ sparta init | ||
EXAMPLE | ||
$ sparta init | ||
``` | ||
<!-- commandsstop --> |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import Command, { flags } from "@oclif/command"; | ||
|
||
import { SpartaError } from "./services/errors/sparta-error"; | ||
|
||
export default abstract class extends Command { | ||
async catch(error: SpartaError): Promise<void> { | ||
this.error(error.message, { suggestions: error.suggestions }); | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import cli from "cli-ux"; | ||
import * as emoji from "node-emoji"; | ||
|
||
import Command from "../base"; | ||
import { loadConfig, ConfigInput, writeConfig } from "../config/config"; | ||
import initInstuctions from "../instructions/init"; | ||
import checkWorkspace from "../services/check-workspace"; | ||
import initExercicesRepository from "../services/init-exercises-repository"; | ||
import renderInstructions from "../services/render-instructions"; | ||
import updateExercisesRepoCache from "../services/update-exercises-repo-cache"; | ||
|
||
export default class Init extends Command { | ||
static description = "Initializes the Sparta workspace"; | ||
|
||
static examples = ["$ sparta init"]; | ||
|
||
async run(): Promise<void> { | ||
const configDir = this.config.configDir; | ||
const userInput = await getUserInput(); | ||
|
||
writeConfig(configDir, userInput); | ||
|
||
const config = loadConfig(configDir); | ||
|
||
this.log(emoji.emojify(":crossed_fingers: Checking Workspace directory")); | ||
checkWorkspace(config); | ||
|
||
this.log(emoji.emojify(":robot_face: Initializing exercises repository")); | ||
await initExercicesRepository(config); | ||
|
||
cli.action.start( | ||
emoji.emojify(":robot_face: Preparing the Sparta configuration"), | ||
); | ||
await updateExercisesRepoCache(configDir, { delete: true }); | ||
cli.action.stop(); | ||
|
||
this.log(emoji.emojify(":rocket: All Good! Follow the instructions now")); | ||
this.log(renderInstructions(initInstuctions)); | ||
|
||
await cli.anykey( | ||
"Press a key when you are ready to create your GitHub repository", | ||
); | ||
|
||
await cli.open("https://github.com/new"); | ||
} | ||
} | ||
|
||
async function getUserInput(): Promise<ConfigInput> { | ||
const batchID = await cli.prompt("What is the ID of your batch ?"); | ||
const sharedSecret = await cli.prompt("Enter the Sparta secret token", { | ||
type: "hide", | ||
}); | ||
|
||
return { | ||
batchID, | ||
sharedSecret, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import * as fs from "fs-extra"; | ||
import * as path from "path"; | ||
|
||
export interface Config { | ||
workspaceDir: string; | ||
exercicesDir: string; | ||
batchID: string; | ||
sharedSecret: string; | ||
} | ||
|
||
export interface ConfigInput { | ||
batchID: string; | ||
sharedSecret: string; | ||
} | ||
|
||
export function loadConfig(configDir: string): Config { | ||
const configPath = path.join(configDir, "config.json"); | ||
fs.ensureFileSync(configPath); | ||
|
||
const writtenConfig: ConfigInput = fs.readJSONSync(configPath); | ||
|
||
const homeDir = process.env.HOME; | ||
|
||
if (!homeDir) { | ||
throw new Error("HOME env variable not set"); | ||
} | ||
|
||
const workspaceDir = path.join(homeDir, "Workspace"); | ||
const exercicesDir = path.join( | ||
workspaceDir, | ||
"fewlines-education", | ||
"exercices", | ||
); | ||
|
||
return { | ||
...writtenConfig, | ||
workspaceDir, | ||
exercicesDir, | ||
}; | ||
} | ||
|
||
export function writeConfig(configDir: string, input: ConfigInput): void { | ||
const configPath = path.join(configDir, "config.json"); | ||
|
||
fs.ensureFileSync(configPath); | ||
fs.writeJsonSync(configPath, input, { | ||
spaces: 2, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
export default ` | ||
--- | ||
# Initialize your GitHub repository | ||
## Create the repository on GitHub | ||
When pressing a key, the GitHub repository creation will open. | ||
Create a \`public\` repository and fill the requested information. | ||
Check the \`Add .gitignore\` checkbox | ||
## Bind the repository to your local directory | ||
Go to your exercises directory and add your GitHub repo as a remote: | ||
\`\`\`bash | ||
$ git remote add origin git@github.com:<your-github-username>/<your-repository-name>.git | ||
$ git pull origin master | ||
\`\`\` | ||
Congratulations! Your exercises directory is now ready to be used. | ||
--- | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import * as fs from "fs-extra"; | ||
|
||
import { Config } from "../config/config"; | ||
import { SpartaError } from "./errors/sparta-error"; | ||
|
||
export class WorkspaceMissingError extends SpartaError { | ||
constructor(directory: string) { | ||
const name = "WorkspaceMissingError"; | ||
const message = `Workspace not found.`; | ||
const suggestions = [`Make sure the "${directory}" directory exists.`]; | ||
|
||
super(name, message, suggestions); | ||
} | ||
} | ||
|
||
export default function checkWorkspace(config: Config): void { | ||
if (!fs.existsSync(config.workspaceDir)) { | ||
throw new WorkspaceMissingError(config.workspaceDir); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
export class SpartaError extends Error { | ||
name: string; | ||
|
||
suggestions: string[]; | ||
|
||
constructor(name: string, message: string, suggestions: string[]) { | ||
super(message); | ||
|
||
this.name = name; | ||
this.suggestions = suggestions; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import * as fs from "fs-extra"; | ||
import simpleGit, { SimpleGit, SimpleGitOptions } from "simple-git"; | ||
|
||
import { Config } from "../config/config"; | ||
import { SpartaError } from "./errors/sparta-error"; | ||
|
||
export class ExercisesDirectoryExistsError extends SpartaError { | ||
constructor(directory: string) { | ||
const name = "ExercisesDirectoryExistsError"; | ||
const message = "Exercises directory already exists"; | ||
const suggestions = [ | ||
`Delete the ${directory} directory if you want to start over`, | ||
`Rename the ${directory} directory (e.g. ${directory}-backup) if you want to keep your progress`, | ||
]; | ||
|
||
super(name, message, suggestions); | ||
} | ||
} | ||
|
||
export default async function initExercicesRepository( | ||
config: Config, | ||
): Promise<void> { | ||
const directory = config.exercicesDir; | ||
|
||
if (fs.existsSync(directory)) { | ||
throw new ExercisesDirectoryExistsError(directory); | ||
} | ||
|
||
fs.ensureDirSync(directory); | ||
|
||
const gitOptions: SimpleGitOptions = { | ||
baseDir: directory, | ||
binary: "git", | ||
maxConcurrentProcesses: 6, | ||
}; | ||
|
||
const git: SimpleGit = simpleGit(gitOptions); | ||
await git.init(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import * as marked from "marked"; | ||
import * as TerminalRenderer from "marked-terminal"; | ||
|
||
export default function renderInstructions(markdown: string): string { | ||
marked.setOptions({ | ||
renderer: new TerminalRenderer(), | ||
}); | ||
|
||
return marked(markdown); | ||
} |
Oops, something went wrong.