@curvenote/cli
Version:
CLI Client library for Curvenote
116 lines (115 loc) • 5.69 kB
JavaScript
import chalk from 'chalk';
import { submissionRuleChecks } from '@curvenote/check-implementations';
import { build } from 'myst-cli';
import { logCheckReport, runChecks } from '../check/runner.js';
import { writeJsonLogs } from '../utils/utils.js';
import { checkVenueExists, determineCollectionAndKind, getSubmissionKind, getVenueCollections, listSubmissionKinds, } from './submit.utils.js';
import { determineKindFromVenue } from './kind.utils.js';
/**
* Return list of checks from `kind` object and print log message
*/
export function prepareChecksForSubmission(session, venue, kind) {
var _a, _b;
const checks = kind.checks;
const numChecks = (_a = checks === null || checks === void 0 ? void 0 : checks.length) !== null && _a !== void 0 ? _a : 0;
if (numChecks === 0) {
session.log.info(`✅ "${venue}" does not require checks for "${kind.name}"`);
}
else {
session.log.info(`🚦 "${venue}" specifies ${(_b = checks === null || checks === void 0 ? void 0 : checks.length) !== null && _b !== void 0 ? _b : 0} checks for "${kind.name}"`);
}
return checks !== null && checks !== void 0 ? checks : [];
}
/**
* Combine available checks from @curvenote/check-implementations and local plugins
*/
function getCheckImplementations(session) {
var _a, _b;
return [...submissionRuleChecks, ...((_b = (_a = session.plugins) === null || _a === void 0 ? void 0 : _a.checks) !== null && _b !== void 0 ? _b : [])];
}
/**
* Get checks to run based on venue and other optional inputs
*
* If no `venue` is supplied, this just returns a default list of checks.
*
* If `venue` is supplied, this only needs a valid `kind` to get checks;
* `kind` may be provided explicitly or selected interactively.
*
* This function also accepts `collection`. In this case, if `kind` is not provided,
* the interactive selection will only present the collection's kinds.
* If `collection` and `kind` are provided, `kind` will be used to get
* the checks, but there may be warnings logged if the `collection` and
* `kind` are incompatible.
*
* Invalid `kind` or `venue` fail with `process.exit(1)`.
*/
async function getChecks(session, opts) {
if (opts.venue) {
await checkVenueExists(session, opts.venue);
const collections = await getVenueCollections(session, opts.venue, false);
let kind;
let prompted = false;
if (opts.kind) {
try {
kind = await getSubmissionKind(session, opts.venue, opts.kind);
}
catch (err) {
try {
const kinds = await listSubmissionKinds(session, opts.venue);
session.log.error(chalk.bold(`⛔️ Submission Kind "${opts.kind}" not found for venue "${opts.venue}"`));
session.log.info(chalk.bold(`📚 accepted kinds for venue "${opts.venue}": ${kinds.items.map((k) => { var _a; return (k.content ? `${(_a = k.content) === null || _a === void 0 ? void 0 : _a.title} (${k.name})` : k.name); }).join(', ')}`));
}
catch (error) {
session.log.error(`⛔️ ${err.message}`);
process.exit(1);
}
process.exit(1);
}
if (opts.collection) {
const collection = collections.items.find((c) => c.name === opts.collection);
if (!collection) {
session.log.info(`${chalk.red(`Unknown collection "${opts.collection}" for venue "${opts.venue}"`)}`);
}
else {
if (!collection.open) {
session.log.info(`${chalk.red(`Collection "${opts.collection}" is not open for submissions`)}`);
}
if (!collection.kinds.find((k) => k.id === kind.id)) {
session.log.info(`${chalk.red(`Collection "${opts.collection}" does not support kind "${opts.kind}"`)}`);
}
}
}
}
else if (opts.collection) {
const result = await determineCollectionAndKind(session, opts.venue, collections, {
...opts,
allowClosedCollection: true,
});
kind = result.kind;
prompted = result.prompted || prompted;
}
else {
const result = await determineKindFromVenue(session, opts.venue, collections, opts);
kind = result.kind;
prompted = result.prompted || prompted;
}
session.log.info(`${chalk.green(`🏃♂️ Running checks against kind "${kind.name}" from venue "${opts.venue}"`)}`);
if (prompted) {
session.log.info(`${chalk.bold.green(`👉 You may run these same checks again with: \`curvenote check ${opts.venue} --kind ${kind.name}\``)}`);
}
return prepareChecksForSubmission(session, opts.venue, kind);
}
session.log.warn('No venue provided, running basic submission checks');
const allChecks = getCheckImplementations(session);
return allChecks.map(({ id }) => ({ id }));
}
export async function check(session, venue, opts) {
var _a;
const checks = await getChecks(session, { venue, ...opts });
const implementations = getCheckImplementations(session);
await build(session, [], { all: true, checkLinks: true });
const report = await runChecks(session, checks, implementations);
const checkLog = { input: {}, venue, kind: (_a = opts.kind) !== null && _a !== void 0 ? _a : null, report };
writeJsonLogs(session, 'curvenote.checks.json', checkLog);
logCheckReport(session, report);
}