Skip to content

Commit

Permalink
Added --list option for apex run and updated readme/descriptions (#…
Browse files Browse the repository at this point in the history
…21)

* added --list for apex run, unified ui tables, updated readme, replaced justfile with apex.yaml, centralized some dependencies, updated cliffy
* updated descriptions
* Adding version column to template list
* updated git url

Co-authored-by: Phil Kedy <phil.kedy@gmail.com>
  • Loading branch information
jsoverson and pkedy authored Jan 23, 2023
1 parent 4f134a7 commit ad7c563
Show file tree
Hide file tree
Showing 22 changed files with 234 additions and 106 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Test Deno Module
name: Apex tests

on:
push:
Expand All @@ -11,8 +11,7 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: extractions/setup-just@v1
- uses: actions/checkout@v2
- uses: denolib/setup-deno@v2
- name: Run tests
run: just test
run: ./apex test
66 changes: 47 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,43 @@
# Apex CLI
# Apexlang CLI

Apex is an interface definition language (IDL) for modeling software. Generate
source code, documentation, integration, everything automatically.
The `apex` CLI is a one-stop shop for all projects across all languages.

### Goals:
It's a

- <ins>A</ins>pproachable - Apex was designed from the ground up to be succinct.
Interfaces and data types are described using familiar syntax that won't slow
you down.
- <ins>P</ins>rotocol agnostic - Regardless of the architecture, your data and
interfaces are fundamentally the same. Use Apex to generate code for any
serialization format or protocol.
- <ins>Ex</ins>tensible - Generators are written in TypeScript. Easily add
custom generators that satisfy your unique needs and publish them for everyone
to use.
- Project templating and scaffolding tool
- Extensible code generation tool
- Task runner

For more information, visit [https://apexlang.io](https://apexlang.io).

## Installation
## Prerequisites

The `apex` CLI depends on Deno.

First, install [Deno](https://github.com/denoland/deno_install).
Install `deno` with instructions
[here](https://github.com/denoland/deno_install).

Then run the command below from a terminal.
## Installation

To install a release version of the `apex` CLI, run the command below:

```
deno install -A --unstable -f -n apex https://deno.land/x/apex_cli/apex.ts
```

To install from source, clone this repository and run `./apex run install`

```sh
git clone https://github.com/apexlang/apex.git
cd apex
./apex install # or deno install -A --unstable ./apex.ts
```

## Usage

Visit [https://apexlang.io](https://apexlang.io) for official documentation and
usage.

```shell
apex --help
```
Expand All @@ -39,7 +50,7 @@ Output:
Description:
A code generation tool using Apex, an interface definition language (IDL) for modeling software.
A code generation tool using Apexlang, an interface definition language (IDL) for modeling software.
Options:
Expand All @@ -51,16 +62,33 @@ Output:
install <location> - Install templates locally.
new <template> <dir> - Create a new project directory using a template.
init <template> - Initialize a project using a template.
generate [configuration...] - Run apex generators from a given configuration.
generate [configuration...] - Run Apexlang generators from a given configuration.
list - List available resources.
describe - Describe available resources.
watch [configuration...] - Watch apex configuration for changes and trigger code generation.
watch [configuration...] - Watch configuration for changes and trigger code generation.
run [tasks...] - Run tasks.
upgrade - Upgrade apex executable to latest or given version.
help [command] - Show this help or the help of a sub-command.
completions - Generate shell completions.
```

## Running tests

To run tests, run the command below:

```sh
apex test
```

## Development

To run the development version of the `apex` CLI, use the `apex` script in the
root of this repository, e.g.

```sh
./apex help
```

## Contributing

Please read
Expand Down
3 changes: 3 additions & 0 deletions apex
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh
# deno install mocker
exec deno run --allow-all --unstable './apex.ts' "$@"
15 changes: 4 additions & 11 deletions apex.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
#!/usr/bin/env -S deno run --allow-read --allow-write --allow-env --allow-net --allow-run --unstable

import {
Command,
CompletionsCommand,
HelpCommand,
} from "https://deno.land/x/cliffy@v0.25.5/command/mod.ts";
import {
GithubProvider,
UpgradeCommand,
} from "https://deno.land/x/cliffy@v0.25.5/command/upgrade/mod.ts";
import { Command, CompletionsCommand, HelpCommand } from "./src/deps/cliffy.ts";
import { GithubProvider, UpgradeCommand } from "./src/deps/cliffy.ts";
import * as log from "https://deno.land/std@0.171.0/log/mod.ts";

const LEVEL =
Expand Down Expand Up @@ -45,7 +38,7 @@ if (
.version(version)
.name("apex")
.description(
"A code generation tool using Apex, an interface definition language (IDL) for modeling software.",
"A complete project tool suite based on Apexlang, an interface definition language (IDL) for modeling software.",
)
.command("install", install.command)
.command("new", newCmd.command)
Expand Down Expand Up @@ -78,7 +71,7 @@ if (
if (nonFlagArgs.length > 0 && !cli.getBaseCommand(args[0], true)) {
const configPath = findApexConfig();
if (!configPath) {
console.log("could not find configuration");
log.error("could not find configuration");
Deno.exit(1);
}
let config;
Expand Down
10 changes: 10 additions & 0 deletions apex.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
tasks:
test:
description: Run tests
cmds:
- deno fmt --check src/ test/
- deno test --unstable -A
install:
description: Install apex
cmds:
- deno install -f -A --unstable ./apex.ts
7 changes: 0 additions & 7 deletions justfile

This file was deleted.

15 changes: 4 additions & 11 deletions src/commands/describe.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Command } from "https://deno.land/x/cliffy@v0.25.5/command/mod.ts";
import { Row, Table } from "https://deno.land/x/cliffy@v0.25.5/table/mod.ts";
import { Command } from "../deps/cliffy.ts";
import * as ui from "../ui.ts";

import { loadTemplateRegistry } from "../utils.ts";
import { templateCompletion } from "./utils.ts";
Expand All @@ -11,7 +11,7 @@ export const templates = new Command()
.action(async (_options, template: string) => {
const registry = await loadTemplateRegistry();
const temp = registry.templates[template];
if (!template) {
if (!temp) {
throw new Error(`template ${template} is not installed`);
}

Expand All @@ -23,14 +23,7 @@ export const templates = new Command()
const variables = temp.variables || [];
if (variables.length > 0) {
console.log("\nVariables:");
new Table()
.header(Row.from(["Name", "Description", "Default"]).border(true))
.body(
variables.map((
t,
) => [t.name, t.description || "", (t.default || "").toString()]),
)
.render();
ui.listToTable(variables, ["description", "default"]);
}
});

Expand Down
4 changes: 2 additions & 2 deletions src/commands/generate.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Command } from "https://deno.land/x/cliffy@v0.25.5/command/mod.ts";
import { Command } from "../deps/cliffy.ts";
import * as streams from "https://deno.land/std@0.171.0/streams/read_all.ts";
import * as log from "https://deno.land/std@0.171.0/log/mod.ts";

Expand All @@ -7,7 +7,7 @@ import { processConfiguration, writeOutput } from "../process.ts";

export const command = new Command()
.arguments("[...configuration:string[]]")
.description("Run apex generators from a given configuration.")
.description("Run Apexlang generators from a given configuration.")
.action(async (_options: unknown, configFiles: string[]) => {
configFiles ||= [];
if (!configFiles.length) {
Expand Down
2 changes: 1 addition & 1 deletion src/commands/init.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Command } from "https://deno.land/x/cliffy@v0.25.5/command/mod.ts";
import { Command } from "../deps/cliffy.ts";

import { Variables } from "../config.ts";
import {
Expand Down
2 changes: 1 addition & 1 deletion src/commands/install.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as path from "https://deno.land/std@0.171.0/path/mod.ts";
import * as yaml from "https://deno.land/std@0.171.0/encoding/yaml.ts";

import { Command } from "https://deno.land/x/cliffy@v0.25.5/command/mod.ts";
import { Command } from "../deps/cliffy.ts";
import { getInstallDirectories } from "../utils.ts";
import { installTemplate } from "../install.ts";
import { TemplateMap, TemplateRegistry } from "../config.ts";
Expand Down
24 changes: 17 additions & 7 deletions src/commands/list.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
import { Command } from "https://deno.land/x/cliffy@v0.25.5/command/mod.ts";
import { Row, Table } from "https://deno.land/x/cliffy@v0.25.5/table/mod.ts";
import { Command } from "../deps/cliffy.ts";
import { action as runAction } from "./run.ts";

import { templateList } from "../utils.ts";
import * as ui from "../ui.ts";

export const templates = new Command()
.description("List installed templates.")
.action(async (_options) => {
const templates = await templateList();
new Table()
.header(Row.from(["Name", "Description"]).border(true))
.body(templates.map((t) => [t.name, t.description]))
.render();
ui.objToTable(templates, ["version", "description"]);
});

export const tasks = new Command()
.description("List tasks.")
.option(
"-c, --config <string>",
"specify an Apex configuration",
{ default: "apex.yaml" },
)
.action(async (options) => {
await runAction({ list: true, config: options.config }, "");
});

export const command = new Command()
.description("List available resources.")
.default("help")
.command("templates", templates);
.command("templates", templates)
.command("tasks", tasks);
2 changes: 1 addition & 1 deletion src/commands/new.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Command } from "https://deno.land/x/cliffy@v0.25.5/command/mod.ts";
import { Command } from "../deps/cliffy.ts";

import { Variables } from "../config.ts";
import {
Expand Down
63 changes: 32 additions & 31 deletions src/commands/run.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { Command } from "https://deno.land/x/cliffy@v0.25.5/command/mod.ts";
import { Command } from "../deps/cliffy.ts";
import * as log from "https://deno.land/std@0.171.0/log/mod.ts";
import { fromConfigs } from "./generate.ts";
import * as ui from "../ui.ts";

import { Configuration, parseConfigYaml } from "../config.ts";
import { Configuration, findConfigFile, parseConfigYaml } from "../config.ts";
import { processPlugins } from "../process.ts";
import { findApexConfig, flatten } from "../utils.ts";
import { flatten } from "../utils.ts";
import { CmdOutput, Task } from "../task.ts";

export interface RunOptions {
config?: string;
quiet?: boolean;
failUndefined?: boolean;
list?: boolean;
}

export const command = new Command()
.arguments("[...tasks:string[]]")
.arguments("[...tasks]")
.option(
"-c, --config <string>",
"specify an Apex configuration",
Expand All @@ -24,38 +26,38 @@ export const command = new Command()
"-q, --quiet",
"silence extraneous apex output",
)
.option(
"-l, --list",
"list tasks",
)
.option(
"--fail-undefined",
"when there are multiple configurations, force the command to fail if a task is not defined",
)
.description("Run tasks.")
.action(async (options: RunOptions, tasks: string[]) => {
const configFile = options.config || "apex.yaml";
const configPath = findApexConfig(configFile);
if (!configPath) {
console.log("could not find configuration");
Deno.exit(1);
}
let config;
try {
config = await Deno.readTextFile(configPath);
} catch (_e) {
log.error(`Could not read config ${configPath}`);
Deno.exit(1);
}

const configs = parseConfigYaml(config);
for (const cfg of configs) {
const taskMap = await loadTasks(cfg);
await runTasks(
cfg,
taskMap,
tasks,
configs.length == 1 || options.failUndefined == true,
options,
);
.action(action);

export async function action(
options: RunOptions,
...tasks: string[]
) {
const config = await findConfigFile(options.config);
const configs = parseConfigYaml(config);
for (const cfg of configs) {
const taskMap = await loadTasks(cfg);
if (options.list) {
ui.objToTable(taskMap, ["description"]);
continue;
}
});
await runTasks(
cfg,
taskMap,
tasks,
configs.length == 1 || options.failUndefined == true,
options,
);
}
}

export function parseTasks(
config: Configuration,
Expand Down Expand Up @@ -98,7 +100,6 @@ export async function loadTasks(
config: Configuration,
): Promise<Record<string, Task>> {
config = await processPlugins(config);

return parseTasks(config);
}

Expand Down
4 changes: 2 additions & 2 deletions src/commands/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ValidationError } from "https://deno.land/x/cliffy@v0.25.5/command/mod.ts";
import { ValidationError } from "../deps/cliffy.ts";
import { templateList } from "../utils.ts";

export const varOptions = {
Expand All @@ -23,5 +23,5 @@ export const varOptions = {
};

export async function templateCompletion(): Promise<string[]> {
return (await templateList()).map((t) => t.name || "");
return Object.values(await templateList()).map((t) => t.name || "");
}
Loading

0 comments on commit ad7c563

Please sign in to comment.