Skip to content

Commit bf360c5

Browse files
committed
feat(CLI): Add initial CLI interface
1 parent 0122bba commit bf360c5

4 files changed

Lines changed: 119 additions & 60 deletions

File tree

executa

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/sh
2+
3+
# A little script to make it a litle easier to test the CLI
4+
# during development of this repo
5+
6+
# Change into the current directory of this script so it can be run from anywhere
7+
cd "$(dirname "$0")"
8+
npm run cli -- "$@"

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
"description": "Execution delegator for various language backends.",
55
"main": "index.js",
66
"scripts": {
7-
"serve": "ts-node src/serve.ts --tcp=7300",
8-
"serve:dev": "ts-node-dev src/serve.ts --tcp=7300",
7+
"cli": "ts-node src/cli.ts",
8+
"cli:dev": "ts-node-dev src/cli.ts",
99
"console": "ts-node src/console.ts",
1010
"format": "npx prettier --write './**/*.{js,json,md,ts,yaml}'",
1111
"lint": "eslint 'src/**/*.{ts,js}' --fix",

src/cli.ts

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import { defaultHandler, getLogger, LogLevel, replaceHandlers } from '@stencila/logga';
2+
import fs from 'fs';
3+
import minimist from 'minimist';
4+
import { promisify } from 'util';
5+
import { ClientType } from './base/Client';
6+
import Executor from './base/Executor';
7+
import Server from './base/Server';
8+
import discoverStdio from './stdio/discover';
9+
import StdioClient from './stdio/StdioClient';
10+
import TcpServer from './tcp/TcpServer';
11+
12+
const readFile = promisify(fs.readFile)
13+
const writeFile = promisify(fs.writeFile)
14+
15+
const { _: args, ...options } = minimist(process.argv.slice(2))
16+
17+
const log = getLogger('executa:serve')
18+
replaceHandlers(data =>
19+
defaultHandler(data, {
20+
level: options.debug !== undefined ? LogLevel.debug : LogLevel.info
21+
})
22+
)
23+
24+
const main = async () => {
25+
// Initialize the executor
26+
const executor = await init()
27+
28+
// Run command
29+
const command = args[0]
30+
if (command === 'serve' || command === undefined) return serve(executor)
31+
else if (command === 'execute') return execute(executor)
32+
else {
33+
log.error(`Unrecognised command: ${command}`)
34+
}
35+
}
36+
37+
/**
38+
* Initialize the executor
39+
*/
40+
const init = async () => {
41+
// Discover other executors registered on this machine
42+
// In the future this may attempt to discover remote executors as well
43+
const manifests = await discoverStdio()
44+
if (manifests.length === 0) {
45+
log.warn(
46+
'No peer executors discovered on this machine. Executor will have limited capabilities.'
47+
)
48+
}
49+
50+
// Create a list of client types that can be used by executor
51+
const clientTypes: ClientType[] = [StdioClient as ClientType]
52+
53+
return new Executor(manifests, clientTypes)
54+
}
55+
56+
/**
57+
* Serve the executor
58+
*/
59+
const serve = (executor: Executor) => {
60+
// Add server classes based on supplied options
61+
const servers: Server[] = []
62+
if (options.tcp !== undefined) {
63+
servers.push(new TcpServer(executor, options.tcp))
64+
}
65+
if (servers.length === 0) {
66+
log.warn(
67+
'No servers specified in options (e.g. --tcp --stdio). Executor will not be accessible.'
68+
)
69+
}
70+
executor.start(servers)
71+
}
72+
73+
/**
74+
* Convert a document
75+
*/
76+
const convert = async (executor: Executor): Promise<void> => {
77+
const input = args[1]
78+
const output = args[2] || '-'
79+
80+
const content = await readFile(input, 'utf8')
81+
82+
const decoded = await executor.decode(content)
83+
const encoded = await executor.encode(decoded)
84+
85+
if (output === '-') console.log(encoded)
86+
else await writeFile(output, encoded)
87+
}
88+
89+
/**
90+
* Execute a document
91+
*/
92+
const execute = async (executor: Executor): Promise<void> => {
93+
const input = args[1]
94+
const output = args[2] || input
95+
96+
const content = await readFile(input, 'utf8')
97+
98+
const decoded = await executor.decode(content)
99+
const executed = await executor.execute(decoded)
100+
const encoded = await executor.encode(executed)
101+
102+
if (output === '-') console.log(encoded)
103+
else await writeFile(output, encoded)
104+
}
105+
106+
// Run the main function and log any exceptions
107+
main()
108+
.then(() => {})
109+
.catch(err => log.error(err))

src/serve.ts

Lines changed: 0 additions & 58 deletions
This file was deleted.

0 commit comments

Comments
 (0)