Skip to content

Commit

Permalink
A new approach to share globals with sub-commands.
Browse files Browse the repository at this point in the history
Introduces a new way of sharing global properties with sub-commands without explicitly passing them around. 
We are able achieve by extending the Command class provided by Commander.
  • Loading branch information
kasipavankumar committed Jan 15, 2022
2 parents 9b827d9 + c9e4c45 commit ae4b64a
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 32 deletions.
4 changes: 2 additions & 2 deletions actions/auth/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { promptCredentials } from '../../utils/prompts/index.js'
import { logError, logSuccess } from '../../utils/loggers.js'

function login(config) {
return async function (_, command) {
const store = command.__store
return async function (_, options) {
const store = options.appState
const spinner = Spinner('Authenticating')

try {
Expand Down
4 changes: 3 additions & 1 deletion actions/auth/logout.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ export default function logout(config) {
const prompt = createPrompt()

return async function (_, options) {
const store = options.appState

// There was no user in the first place.
if (!options.__store.isAuthed) {
if (!store.isAuthed) {
logWarn('You are not logged in.')
return process.exit(0)
}
Expand Down
4 changes: 3 additions & 1 deletion actions/auth/register.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ function register(config) {
const spinner = Spinner('Registering a new user')

return async function (_, options) {
const store = options.appState

try {
if (options.__store.isAuthed) {
if (store.isAuthed) {
if (
!(await confirmationPrompt(
`It seems like you are already logged in`,
Expand Down
8 changes: 3 additions & 5 deletions actions/publish.js → actions/packages/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { globby } from 'globby'
import chalk from 'chalk'
import tar from 'tar'

import api from '../lib/api/index.js'
import { logError, logInfo, logSuccess } from '../utils/loggers.js'
import api from '../../lib/api/index.js'
import { logError, logInfo, logSuccess } from '../../utils/loggers.js'

//? The tarball created in the process will be placed in the OS's temp directory.
// TODO: Do we need to clean this directory post publishing?
Expand All @@ -28,7 +28,7 @@ const createTempTarDirIfNotExists = () => {
* Action to publish a package to JSCrates repository.
*/
async function publishPackage(_, options) {
const store = options.__store
const store = options.appState
const spinner = Spinner('Publishing package')

try {
Expand Down Expand Up @@ -119,8 +119,6 @@ async function publishPackage(_, options) {
}

logError(error)
} finally {
return process.exit(1)
}
}

Expand Down
2 changes: 1 addition & 1 deletion actions/packages/unload.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const getTarballName = (tarballURL) => {
async function unloadPackages(packages, ...args) {
// Since we are accepting variadic arguments, other arguments can only
// be accessing by spreading them.
const store = args[1].__store
const store = args[1].appState
const spinner = Spinner(`Downloading packages`)

try {
Expand Down
19 changes: 6 additions & 13 deletions jscrates.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,28 @@
#!/usr/bin/env node

import { Command } from 'commander'
import Configstore from 'configstore'
import checkOnlineStatus from 'is-online'

import BaseCommand from './lib/base-command.js'
import { CONFIG_FILE } from './lib/constants.js'
import unloadPackages from './actions/packages/unload.js'
import publishPackage from './actions/publish.js'
import publishPackage from './actions/packages/publish.js'
import login from './actions/auth/login.js'
import register from './actions/auth/register.js'
import logout from './actions/auth/logout.js'

async function jscratesApp() {
const isOnline = await checkOnlineStatus()
const program = new Command()
const configStore = new Configstore(CONFIG_FILE, {
createdAt: Date.now(),
})
const appState = {
const configStore = new Configstore(CONFIG_FILE)
const program = new BaseCommand({
isOnline,
isAuthed: configStore.has('auth.token'),
}
})

program
.name('jscrates')
.description(`Welcome to JSCrates 📦, yet another package manager for Node`)
// TODO: Find a way to read version build time.
.version('0.0.0-alpha', '-v, --version', 'display current version')
.hook('preAction', (_, actionCommand) => {
actionCommand['__store'] = appState
})
.version('v2.6.3', '-v, --version', 'Display installed version of JSCrates')

program
.command('login')
Expand Down
18 changes: 18 additions & 0 deletions lib/base-command.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// @ts-check

import { Command } from 'commander'

export default class BaseCommand extends Command {
constructor(appState) {
super(appState)
this.appState = appState
}

// To make properties available in all the subcommands.
// https://github.com/tj/commander.js/issues/1666#issuecomment-1003690872
createCommand(name) {
const cmd = new BaseCommand(this.appState)
cmd.name(name)
return cmd
}
}
16 changes: 8 additions & 8 deletions 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": "@jscrates/cli",
"version": "2.6.2",
"version": "2.6.3",
"description": "Official CLI client for JSCrates.",
"main": "jscrates.js",
"author": "Team JSCrates",
Expand Down

0 comments on commit ae4b64a

Please sign in to comment.