Skip to content
Permalink
Browse files

Add install command

  • Loading branch information...
cdupuis committed Jan 14, 2019
1 parent 115cb0e commit b706d70831e98cfcb7738d537bfc89b6af10198d
Showing with 146 additions and 3 deletions.
  1. +25 −1 index.ts
  2. +3 −2 lib/config.ts
  3. +118 −0 lib/install.ts
@@ -29,6 +29,7 @@ import { config } from "./lib/config";
import { execute } from "./lib/execute";
import { gitHook } from "./lib/gitHook";
import { gqlFetch } from "./lib/gqlFetch";
import { install } from "./lib/install";
import { kube } from "./lib/kube";
import * as print from "./lib/print";
import { start } from "./lib/start";
@@ -97,6 +98,29 @@ function setupYargs(yargBuilder: yb.YargBuilder): void {
args: argv._.filter((a: any) => a !== "execute" && a !== "exec" && a !== "cmd"),
})),
});
yargBuilder.withSubcommand({
command: "install [keywords]",
describe: "Search and install an SDM extension pack",
positional: [{
key: "keywords",
opts: {
describe: "keywords to search for",
},
}],
parameters: [
commonOptions.changeDir,
{
parameterName: "registry",
describe: "NPM registry to search",
type: "string",
required: false,
}],
handler: argv => cliCommand(() => install({
keywords: [argv.keywords, ...argv._.filter((a: any) => a !== "install")],
cwd: argv["change-dir"],
registry: argv.registry,
})),
});
yargBuilder.withSubcommand({
command: "git-hook",
describe: "Process Git hook data for local SDM",
@@ -114,7 +138,7 @@ function setupYargs(yargBuilder: yb.YargBuilder): void {
command: "kube", describe: "Deploy Atomist utilities to Kubernetes cluster",
parameters: [{
parameterName: "environment",
describe: "Informative name for yout Kubernetes cluster",
describe: "Informative name for your Kubernetes cluster",
type: "string",
}, {
parameterName: "namespace",
@@ -177,7 +177,7 @@ async function createApiKey(cfg: Configuration): Promise<string> {
type: "input",
name: "apiKey",
transformer: maskString,
message: `Enter your ${chalk.cyan("api key")} from ${chalk.blue("https://app.atomist.com/apikeys")}
message: `Enter your ${chalk.cyan("api key")} from ${chalk.yellow("https://app.atomist.com/apikeys")}
or hit ${chalk.cyan("<ENTER>")} to select an authentication provider to login with Atomist`,
},
];
@@ -331,6 +331,7 @@ async function configureWorkspaces(apiKey: string, cfg: Configuration): Promise<
name: `${p.team.id} - ${p.team.name}`,
value: p.team.id,
checked: cfg.workspaceIds.includes(p.team.id),
short: p.team.id,
})),
},
];
@@ -339,7 +340,7 @@ async function configureWorkspaces(apiKey: string, cfg: Configuration): Promise<
return answers.workspaceIds || [];
}

function createSpinner(text: string): any {
export function createSpinner(text: string): any {
const Spinner = require("cli-spinner").Spinner;
const spinner = new Spinner(`${text} ${chalk.yellow("%s")} `);
spinner.setSpinnerDelay(100);
@@ -0,0 +1,118 @@
/*
* Copyright © 2019 Atomist, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { execPromise } from "@atomist/sdm";
import chalk from "chalk";
import * as fs from "fs-extra";
import * as inquirer from "inquirer";
import * as path from "path";
import { createSpinner } from "./config";
import * as print from "./print";

/**
* Command-line options and arguments for install.
*/
export interface InstallOptions {
/** Name or keywords to install for */
keywords: string[];
/** Directory to run command in, must be an SDM directory */
cwd?: string;
/** NPM Registry to install */
registry?: string;
}

interface ExtensionPack {
name: string;
description: string;
version: string;
maintainers: [{
username: string;
email: string;
}];
}

/**
* Search for an SDM extension pack.
*
* @param opts see InstallOptions
* @return integer return value
*/
export async function install(opts: InstallOptions): Promise<number> {
const keywords = opts.keywords.filter(k => !!k);
let spinner = createSpinner(
`Searching extension packs${keywords.length > 0 ? " for " : ""}${chalk.cyan(keywords.join(", "))}`);
let packs: ExtensionPack[];

try {
const registryArgs = opts.registry ? ["--registry", opts.registry] : [];
const result = await execPromise(
"npm",
[
"search",
"--json",
...registryArgs,
"atomist",
"SDM",
"extension",
"pack",
...opts.keywords.filter(k => !!k)],
{});
packs = JSON.parse(result.stdout);
spinner.stop(true);
} catch (e) {
spinner.stop(true);
print.error(`Failed to search registry: ${e.message}`);
return 1;
}

if (packs.length > 0) {
const questions: inquirer.Question[] = [
{
type: "list",
name: "package",
message: "Extension Packs",
choices: packs
.map(p => ({
name: `${p.name} ${chalk.yellow(p.description)} ${chalk.reset("by")} ${
chalk.gray(p.maintainers.map(m => m.username).join(", "))}`,
value: p,
short: p.name,
})),

},
];
const answers: any = await inquirer.prompt(questions);
spinner = createSpinner(`Installing extension pack ${chalk.cyan(answers.package.name)} in ${opts.cwd}`);
try {
await execPromise("npm", ["install", answers.package.name], { cwd: opts.cwd });
spinner.stop(true);
print.log(`Successfully installed extension pack ${chalk.cyan(answers.package.name)} by ${
chalk.gray(answers.package.maintainers.map((m: any) => m.username).join(", "))}`);
const p = path.join(opts.cwd, "node_modules", answers.package.name, "package.json");
const pj = JSON.parse((await fs.readFile(p)).toString());
print.log(`Visit ${chalk.yellow(pj.homepage)} for install and usage instructions`);
} catch (e) {
spinner.stop(true);
print.error(`Failed to install extension pack '${answers.package.name}': ${e.message}`);
return 1;
}

} else {
print.log(`No SDM extension packs found for: ${opts.keywords.join(", ")}`);
return 1;
}
return 0;
}

0 comments on commit b706d70

Please sign in to comment.
You can’t perform that action at this time.