diff --git a/README.md b/README.md index d6f5811..67e53af 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -Sparta CLI -====== +# Sparta CLI # Installation @@ -9,7 +8,9 @@ $ yarn install ``` # Usage + + ```sh-session $ npm install -g sparta $ sparta COMMAND @@ -21,13 +22,17 @@ USAGE $ sparta COMMAND ... ``` + + # Commands + -* [`sparta help [COMMAND]`](#sparta-help-command) -* [`sparta init`](#sparta-init) -* [`sparta sync`](#sparta-sync) -* [`sparta today`](#sparta-today) + +- [`sparta help [COMMAND]`](#sparta-help-command) +- [`sparta init`](#sparta-init) +- [`sparta sync`](#sparta-sync) +- [`sparta today`](#sparta-today) ## `sparta help [COMMAND]` @@ -58,6 +63,11 @@ EXAMPLE $ sparta init ``` +There are two flags that are hidden from the help (because we don't want students to use them): + +- `--spartaURL=""` will update the URL that will be called when talking to Sparta API. +- `--force` or `-f` will recreate the exercises repository (deleting the previous folder, beware). + ## `sparta sync` Updates all the courses for the past days @@ -75,4 +85,5 @@ Downloads the exercises for the current day USAGE $ sparta today ``` + diff --git a/src/base.ts b/src/base.ts index fd0d7d0..be0ff46 100644 --- a/src/base.ts +++ b/src/base.ts @@ -1,4 +1,4 @@ -import Command, { flags } from "@oclif/command"; +import Command from "@oclif/command"; import { SpartaError } from "./services/errors/sparta-error"; diff --git a/src/commands/init.ts b/src/commands/init.ts index 5d594ab..b108cdd 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -1,8 +1,9 @@ +import { flags } from "@oclif/command"; import cli from "cli-ux"; import * as emoji from "node-emoji"; import Command from "../base"; -import { loadConfig, ConfigInput, writeConfig } from "../config/config"; +import { loadConfig, writeConfig } from "../config/config"; import initInstuctions from "../instructions/init"; import checkWorkspace from "../services/check-workspace"; import initExercicesRepository from "../services/init-exercises-repository"; @@ -14,11 +15,20 @@ export default class Init extends Command { static examples = ["$ sparta init"]; + static flags = { + force: flags.boolean({ char: "f", default: false, hidden: true }), + spartaURL: flags.string({ + hidden: true, + default: "https://sparta.fewlines.dev", + }), + }; + async run(): Promise { const configDir = this.config.configDir; const userInput = await getUserInput(); + const { flags } = this.parse(Init); - writeConfig(configDir, userInput); + writeConfig(configDir, { ...userInput, spartaURL: flags.spartaURL }); const config = loadConfig(configDir); @@ -26,7 +36,7 @@ export default class Init extends Command { checkWorkspace(config); this.log(emoji.emojify(":robot_face: Initializing exercises repository")); - await initExercicesRepository(config); + await initExercicesRepository(config, flags.force); cli.action.start( emoji.emojify(":robot_face: Preparing the Sparta configuration"), @@ -45,7 +55,10 @@ export default class Init extends Command { } } -async function getUserInput(): Promise { +async function getUserInput(): Promise<{ + batchID: string; + sharedSecret: string; +}> { const batchID = await cli.prompt("What is the ID of your batch ?"); const sharedSecret = await cli.prompt("Enter the Sparta secret token", { type: "hide", diff --git a/src/config/config.ts b/src/config/config.ts index 063ff53..2769709 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -19,11 +19,13 @@ export interface Config { exercisesCacheDir: string; batchID: string; sharedSecret: string; + spartaURL: string; } export interface ConfigInput { batchID: string; sharedSecret: string; + spartaURL: string; } export function loadConfig(configDir: string): Config { diff --git a/src/services/fetch-past-days-exercises-paths.ts b/src/services/fetch-past-days-exercises-paths.ts index 53afb1b..18d1761 100644 --- a/src/services/fetch-past-days-exercises-paths.ts +++ b/src/services/fetch-past-days-exercises-paths.ts @@ -18,7 +18,11 @@ export default async function fetchPastDaysExercisesPaths( let calendar: Calendar; try { - calendar = await fetchCalendar(config.batchID, config.sharedSecret); + calendar = await fetchCalendar( + config.spartaURL, + config.batchID, + config.sharedSecret, + ); } catch (error) { throw new CalendarFetchError(error.message); } diff --git a/src/services/fetch-today-exercises-path.ts b/src/services/fetch-today-exercises-path.ts index b889b0a..e2e70f1 100644 --- a/src/services/fetch-today-exercises-path.ts +++ b/src/services/fetch-today-exercises-path.ts @@ -28,7 +28,11 @@ export default async function fetchTodayExercisesPath( let calendar: Calendar; try { - calendar = await fetchCalendar(config.batchID, config.sharedSecret); + calendar = await fetchCalendar( + config.spartaURL, + config.batchID, + config.sharedSecret, + ); } catch (error) { throw new CalendarFetchError(error.message); } diff --git a/src/services/init-exercises-repository.ts b/src/services/init-exercises-repository.ts index ca14b75..61c3025 100644 --- a/src/services/init-exercises-repository.ts +++ b/src/services/init-exercises-repository.ts @@ -19,11 +19,14 @@ export class ExercisesDirectoryExistsError extends SpartaError { export default async function initExercicesRepository( config: Config, + force = false, ): Promise { const directory = config.exercisesDir; - if (fs.existsSync(directory)) { + if (fs.existsSync(directory) && !force) { throw new ExercisesDirectoryExistsError(directory); + } else if (force) { + fs.removeSync(directory); } fs.ensureDirSync(directory); diff --git a/src/services/update-today-exercises-directory.ts b/src/services/update-today-exercises-directory.ts index 19e4067..e22da52 100644 --- a/src/services/update-today-exercises-directory.ts +++ b/src/services/update-today-exercises-directory.ts @@ -16,8 +16,10 @@ export default async function updateDayExercisesDirectory( const todayCurrentPath = path.join(exercisesDir, dayPath, "current"); const todaySHAPath = path.join(exercisesDir, dayPath, directorySHA); - fs.ensureDirSync(todaySHAPath); - fs.copySync(todayCachePath, todaySHAPath); - fs.removeSync(todayCurrentPath); - fs.ensureSymlinkSync(todaySHAPath, todayCurrentPath); + if (!fs.existsSync(todaySHAPath)) { + fs.ensureDirSync(todaySHAPath); + fs.copySync(todayCachePath, todaySHAPath); + fs.removeSync(todayCurrentPath); + fs.ensureSymlinkSync(todaySHAPath, todayCurrentPath); + } } diff --git a/src/utils/fetch-calendar.ts b/src/utils/fetch-calendar.ts index 19f895a..c827130 100644 --- a/src/utils/fetch-calendar.ts +++ b/src/utils/fetch-calendar.ts @@ -3,17 +3,15 @@ import fetch from "node-fetch"; import Calendar from "../models/calendar"; export default async function fetchCalendar( + spartaURL: string, batchID: string, sharedSecret: string, ): Promise { - const response = await fetch( - `https://sparta.fewlines.dev/cli/calendar/${batchID}`, - { - headers: { - Authorization: `Bearer ${sharedSecret}`, - }, + const response = await fetch(`${spartaURL}/cli/calendar/${batchID}`, { + headers: { + Authorization: `Bearer ${sharedSecret}`, }, - ); + }); return response.json(); }