diff --git a/packages/schema/src/cli/actions/check.ts b/packages/schema/src/cli/actions/check.ts new file mode 100644 index 000000000..df161b5c0 --- /dev/null +++ b/packages/schema/src/cli/actions/check.ts @@ -0,0 +1,14 @@ +import { getDefaultSchemaLocation, loadDocument } from '../cli-util'; + +type Options = { + schema: string; +}; + +/** + * CLI action for checking schema + */ +export async function check(_projectPath: string, options: Options) { + const schema = options.schema ?? getDefaultSchemaLocation(); + await loadDocument(schema); + console.log('The schema is valid.'); +} diff --git a/packages/schema/src/cli/actions/index.ts b/packages/schema/src/cli/actions/index.ts index e56e4797c..7e172d4bc 100644 --- a/packages/schema/src/cli/actions/index.ts +++ b/packages/schema/src/cli/actions/index.ts @@ -1,5 +1,6 @@ +export * from './check'; +export * from './format'; export * from './generate'; export * from './info'; export * from './init'; export * from './repl'; -export * from './format'; diff --git a/packages/schema/src/cli/cli-util.ts b/packages/schema/src/cli/cli-util.ts index 7309aa49a..6db9eaaf3 100644 --- a/packages/schema/src/cli/cli-util.ts +++ b/packages/schema/src/cli/cli-util.ts @@ -27,7 +27,7 @@ const CHECK_VERSION_TIMEOUT = 1000; * @param services Language services * @returns Parsed and validated AST */ -export async function loadDocument(fileName: string): Promise { +export async function loadDocument(fileName: string, validateOnly = false): Promise { const services = createZModelServices(NodeFileSystem).ZModel; const extensions = services.LanguageMetaData.fileExtensions; if (!extensions.includes(path.extname(fileName))) { @@ -93,6 +93,10 @@ export async function loadDocument(fileName: string): Promise { const model = document.parseResult.value as Model; + if (validateOnly) { + return model; + } + // merge all declarations into the main document const imported = mergeImportsDeclarations(langiumDocuments, model); diff --git a/packages/schema/src/cli/index.ts b/packages/schema/src/cli/index.ts index f430f7662..600d14b47 100644 --- a/packages/schema/src/cli/index.ts +++ b/packages/schema/src/cli/index.ts @@ -60,6 +60,16 @@ export const formatAction = async (options: Parameters[1] ); }; +export const checkAction = async (options: Parameters[1]): Promise => { + await telemetry.trackSpan( + 'cli:command:start', + 'cli:command:complete', + 'cli:command:error', + { command: 'check' }, + () => actions.check(process.cwd(), options) + ); +}; + export function createProgram() { const program = new Command('zenstack'); @@ -131,6 +141,12 @@ export function createProgram() { .option('--no-prisma-style', 'do not use prisma style') .action(formatAction); + program + .command('check') + .description('Check a ZenStack schema file for syntax or semantic errors.') + .addOption(schemaOption) + .action(checkAction); + // make sure config is loaded before actions run program.hook('preAction', async (_, actionCommand) => { let configFile: string | undefined = actionCommand.opts().config;