Skip to content

Commit

Permalink
refactor: rebuild CLI functionality with Gluegun framework (#5)
Browse files Browse the repository at this point in the history
* chore: scaffold gluegun CLI project

* chore: upgrade deps, use eslint

* feat: setup command

* feat: add mac setup

* feat: add wasm setup

* feat: add esp32 setup

* refactor: split up setup commands

* feat: add esp8266 setup

* refactor: create file upsert helper

* feat: add init command

* feat: add run command

* feat: add python server for running wasm sim

* refactor: replace python server with node server

* feat(run): select, list example project

* feat: add include, remove commands for manifest modules

* feat: add update command w/ mac support

* docs: update README for new CLI reference

* refactor: prettier format

* chore(package): update yarn -> pnpm references

* chore(deps): downgrade to v12 of node types

* chore(deps): use v12 of node types again

* chore: skipLibCheck in tsconfig

* chore: prettier formatting

* chore: remove private field from package.json

* refactor: remove legacy zx script

* docs: add dev instructions to README
  • Loading branch information
HipsterBrown authored Jan 17, 2022
1 parent a7004af commit 9b718a3
Show file tree
Hide file tree
Showing 39 changed files with 5,524 additions and 505 deletions.
6 changes: 6 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
extends: ['standard-with-typescript', 'prettier'],
parserOptions: {
project: './tsconfig.json',
},
}
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.DS_Store
node_modules
npm-debug.log
coverage
.nyc_output
dist
build
.vscode
77 changes: 54 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The Moddable SDK and associated dev board tooling is incredibly empowering for e
- [ ] [Gecko SDK setup](https://github.com/Moddable-OpenSource/moddable/blob/public/documentation/devices/gecko/GeckoBuild.md)
- [ ] [QCA4020 SDK setup](https://github.com/Moddable-OpenSource/moddable/blob/public/documentation/devices/qca4020/README.md)
- [X] Update Moddable SDK
- [ ] Project management, including dependencies
- [X] Project management, including dependencies
- [X] WASM simulator
- [ ] Raspberry Pi Pico

Expand All @@ -22,14 +22,14 @@ The Moddable SDK and associated dev board tooling is incredibly empowering for e
- [ ] Windows
- [ ] Linux

## Usage
## Requirements

Globally install [`zx`](https://github.com/google/zx) before running the script.
[Node.js >= v12](https://nodejs.org/en/)

Clone this repo and `cd` into the directory:
## Install

```
git clone https://github.com/HipsterBrown/xs-setup && cd xs-setup
npm install -g xs-dev
```

## Features
Expand All @@ -45,13 +45,13 @@ This process mostly automates the instructions provided by Moddable's "Getting S
Run script for initial setup:

```
./xs-dev.mjs setup
xs-dev setup
```

Run script for updating SDK:

```
./xs-dev.mjs update
xs-dev update
```

### ESP32 SDK install / setup
Expand All @@ -61,13 +61,13 @@ This process automates the instructions for downloading and building the esp-idf
Run script for platform setup:

```
./xs-dev.mjs setup --device=esp32
xs-dev setup --device=esp32
```

Run script to confirm the setup:

```
./xs-dev.mjs test --device=esp32
xs-dev run --example helloworld --device=esp32
```

Flags:
Expand All @@ -82,13 +82,13 @@ This process automates the instructions for downloading all the dependencies for
Run script for platform setup:

```
./xs-dev.mjs setup --device=esp8266
xs-dev setup --device=esp8266
```

Run script to confirm the setup:

```
./xs-dev.mjs test --device=esp8266
xs-dev run --example helloworld --device=esp8266
```

Flags:
Expand All @@ -103,7 +103,7 @@ This process automates the instructions for downloading all the dependencies for
Run script for platform setup:

```
./xs-dev.mjs setup --device=wasm
xs-dev setup --device=wasm
```

_If there are issues building the Moddable wasm tools, please try running `eval $SHELL` or starting a new shell insance before running the setup script again._
Expand All @@ -112,7 +112,7 @@ _If there are issues building the Moddable wasm tools, please try running `eval
Run script to confirm the setup:

```
./xs-dev.mjs test --device=wasm
xs-dev run --example helloworld --device=wasm
```

### Run Moddable examples
Expand All @@ -128,12 +128,12 @@ This tool aims to simplify that process.

List available examples:
```
./xs-dev.mjs run-example --list
xs-dev run --list-examples
```

Run an example (coming soon):
```
./xs-dev.mjs run-example helloworld
xs-dev run --example helloworld
```

Flags:
Expand All @@ -147,52 +147,83 @@ Flags:


```
./xs-dev.mjs init my-project
xs-dev init my-project
```

Creates a `main.js` and base configured `manifest.json` for running in the simulator.

Flags:

- `typescript`: includes typings and creates `main.ts` (experimental)
- `io`: includes [TC53 IO manifest](https://github.com/Moddable-OpenSource/moddable/blob/public/documentation/io/io.md)

### Build and run a project

In the project directory:

```
xs-dev run
```

When not in the project directory:

```
./xs-dev.mjs run path/to/project
xs-dev run path/to/project
```

Flags:

- `device`: `esp8266` | `esp32` | [any of the allowed platform identifiers](https://github.com/Moddable-OpenSource/moddable/blob/public/documentation/tools/tools.md#arguments) (defaults to current OS platform)
- `port`: path to port for connected device (defaults to: `UPLOAD_PORT` environment variable)

### Add a core dependency (Coming soon)
### Add a Moddable module

```
xs-dev include network/wifi
```

Or select from available modules:

```
./xs-dev.mjs include moddable/network/wifi
xs-dev include
```

Updates the `manifest.json` with the path to the dependency.

### Add a remote dependency (Coming soon)

```
./xs-dev.mjs get dtex/j5e
xs-dev get dtex/j5e
```

Assumes the dependency is a GitHub repo, clones it to `~/.local/share`, creates an environment variable with the name of the repo, and updates the `manifest.json` with the path to that dependency.

To include a specific module for the installed dependency:

```
./xs-dev.mjs include j5e/lib/led
xs-dev include j5e/lib/led
```

### Remove a dependency (Coming soon)
### Remove a dependency

```
./xs-dev.mjs remove moddable/network/wifi
xs-dev remove network/wifi
```

Updates the `manifest.json` to remove the dependency.

## Development

Clone the project and install dependencies. We're using [pnpm](https://pnpm.io/) and [volta](https://volta.sh/) to manage packages and Node.

```
git clone https://github.com/HipsterBrown/xs-dev.git
cd xs-dev
pnpm install
```

Link dev version of CLI:

```
pnpm link .
```
29 changes: 29 additions & 0 deletions __tests__/cli-integration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const { system, filesystem } = require('gluegun')

const src = filesystem.path(__dirname, '..')

const cli = async (cmd: string) =>
system.run('node ' + filesystem.path(src, 'bin', 'xs-dev') + ` ${cmd}`)

test('outputs version', async () => {
const output = await cli('--version')
expect(output).toContain('0.0.1')
})

test('outputs help', async () => {
const output = await cli('--help')
expect(output).toContain('0.0.1')
})

test('generates file', async () => {
const output = await cli('generate foo')

expect(output).toContain('Generated file at models/foo-model.ts')
const foomodel = filesystem.read('models/foo-model.ts')

expect(foomodel).toContain(`module.exports = {`)
expect(foomodel).toContain(`name: 'foo'`)

// cleanup artifact
filesystem.remove('models')
})
21 changes: 21 additions & 0 deletions bin/xs-dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env node


/* tslint:disable */
// check if we're running in dev mode
var devMode = require('fs').existsSync(`${__dirname}/../src`)
// or want to "force" running the compiled version with --compiled-build
var wantsCompiled = process.argv.indexOf('--compiled-build') >= 0

if (wantsCompiled || !devMode) {
// this runs from the compiled javascript source
require(`${__dirname}/../build/cli`).run(process.argv)
} else {
// this runs from the typescript source (for dev only)
// hook into ts-node so we can run typescript on the fly
require('ts-node').register({ project: `${__dirname}/../tsconfig.json` })
// run the CLI with the current process arguments
require(`${__dirname}/../src/cli`).run(process.argv)
}


3 changes: 3 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Command Reference for xs-dev

TODO: Add your command reference here
47 changes: 47 additions & 0 deletions docs/plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Plugin guide for xs-dev

Plugins allow you to add features to xs-dev, such as commands and
extensions to the `toolbox` object that provides the majority of the functionality
used by xs-dev.

Creating a xs-dev plugin is easy. Just create a repo with two folders:

```
commands/
extensions/
```

A command is a file that looks something like this:

```js
// commands/foo.js

module.exports = {
run: (toolbox) => {
const { print, filesystem } = toolbox

const desktopDirectories = filesystem.subdirectories(`~/Desktop`)
print.info(desktopDirectories)
}
}
```

An extension lets you add additional features to the `toolbox`.

```js
// extensions/bar-extension.js

module.exports = (toolbox) => {
const { print } = toolbox

toolbox.bar = () => { print.info('Bar!') }
}
```

This is then accessible in your plugin's commands as `toolbox.bar`.

# Loading a plugin

To load a particular plugin (which has to start with `xs-dev-*`),
install it to your project using `npm install --save-dev xs-dev-PLUGINNAME`,
and xs-dev will pick it up automatically.
69 changes: 69 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"name": "xs-dev",
"version": "0.0.1",
"description": "CLI for automating the setup and usage of Moddable XS tools",
"types": "build/types/types.d.ts",
"bin": {
"xs-dev": "bin/xs-dev"
},
"scripts": {
"format": "prettier --write **/*.{js,ts,json}",
"lint": "eslint src/",
"clean-build": "rm -rf ./build",
"compile": "tsc -p .",
"copy-templates": "if [ -e ./src/templates ]; then cp -a ./src/templates ./build/; fi",
"build": "pnpm run format && pnpm run lint && pnpm run clean-build && pnpm run compile && pnpm run copy-templates",
"prepublishOnly": "pnpm run build",
"test": "jest",
"watch": "jest --watch",
"snapupdate": "jest --updateSnapshot",
"coverage": "jest --coverage"
},
"files": [
"tsconfig.json",
"build",
"LICENSE",
"README.md",
"docs",
"bin"
],
"license": "MIT",
"dependencies": {
"axios": "^0.24.0",
"gluegun": "latest",
"serve-handler": "^6.1.3",
"tar-fs": "^2.1.1",
"unzip-stream": "^0.3.1"
},
"devDependencies": {
"@types/jest": "^27.4.0",
"@types/node": "^16.11.0",
"@types/serve-handler": "^6.1.1",
"@types/tar-fs": "^2.0.1",
"@types/unzip-stream": "^0.3.1",
"@typescript-eslint/eslint-plugin": "^4.0.1",
"@typescript-eslint/parser": "^4.0.0",
"eslint": "^7.12.1",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard-with-typescript": "^21.0.1",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.0.0",
"jest": "^27.4.0",
"prettier": "^2.5.1",
"ts-jest": "^27.1.0",
"ts-node": "^10.4.0",
"typescript": "^4.5.x"
},
"jest": {
"preset": "ts-jest",
"testEnvironment": "node"
},
"volta": {
"node": "16.2.0"
},
"prettier": {
"semi": false,
"singleQuote": true
}
}
Loading

0 comments on commit 9b718a3

Please sign in to comment.