initial drop
This commit is contained in:
Родитель
116c8dc4de
Коммит
22793b6b40
|
@ -0,0 +1,33 @@
|
|||
name: Build
|
||||
|
||||
# Controls when the action will run.
|
||||
on:
|
||||
# Triggers the workflow on push or pull request events but only for the main branch
|
||||
push:
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- uses: bahmutov/npm-install@v1
|
||||
- run: yarn build
|
||||
- run: npx semantic-release
|
||||
if: ${{ github.ref == 'refs/heads/main' }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
@ -0,0 +1,49 @@
|
|||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [main]
|
||||
schedule:
|
||||
- cron: '0 12 * * 3'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
# with:
|
||||
# languages: go, javascript, csharp, python, cpp, java
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
18
README.md
18
README.md
|
@ -1,14 +1,16 @@
|
|||
# Project
|
||||
# Jacdac CLI
|
||||
|
||||
> This repo has been populated by an initial template to help get you started. Please
|
||||
> make sure to update the content to build a great experience for community-building.
|
||||
A command line interface to support various tasks using Jacdac.
|
||||
|
||||
As the maintainer of this project, please make a few updates:
|
||||
## Installation
|
||||
|
||||
- Improving this README.MD file to provide a great experience
|
||||
- Updating SUPPORT.MD with content about this project's support experience
|
||||
- Understanding the security reporting process in SECURITY.MD
|
||||
- Remove this section from the README
|
||||
Install the tool globally
|
||||
|
||||
npm install -g jacdac-cli
|
||||
|
||||
Then call it
|
||||
|
||||
jacdac stream
|
||||
|
||||
## Contributing
|
||||
|
||||
|
|
10
SUPPORT.md
10
SUPPORT.md
|
@ -1,13 +1,3 @@
|
|||
# TODO: The maintainer of this repo has not yet edited this file
|
||||
|
||||
**REPO OWNER**: Do you want Customer Service & Support (CSS) support for this product/project?
|
||||
|
||||
- **No CSS support:** Fill out this template with information about how to file issues and get help.
|
||||
- **Yes CSS support:** Fill out an intake form at [aka.ms/spot](https://aka.ms/spot). CSS will work with/help you to determine next steps. More details also available at [aka.ms/onboardsupport](https://aka.ms/onboardsupport).
|
||||
- **Not sure?** Fill out a SPOT intake as though the answer were "Yes". CSS will help you decide.
|
||||
|
||||
*Then remove this first heading from this SUPPORT.MD file before publishing your repo.*
|
||||
|
||||
# Support
|
||||
|
||||
## How to file issues and get help
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"name": "jacdac-cli",
|
||||
"version": "0.0.0",
|
||||
"description": "Command line interface for Jacdac",
|
||||
"exports": {
|
||||
"require": "./dist/cli.cjs",
|
||||
"default": "./dist/cli.modern.js"
|
||||
},
|
||||
"main": "./dist/cli.ts",
|
||||
"module": "./dist/cli.module.js",
|
||||
"scripts": {
|
||||
"build": "microbundle",
|
||||
"dev": "microbundle watch"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/microsoft/jacdac-cli.git"
|
||||
},
|
||||
"keywords": [
|
||||
"jacdac",
|
||||
"cli"
|
||||
],
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/microsoft/jacdac-cli/issues"
|
||||
},
|
||||
"homepage": "https://github.com/microsoft/jacdac-cli#readme",
|
||||
"dependencies": {
|
||||
"commander": "^8.3.0",
|
||||
"jacdac-ts": "^1.22.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"microbundle": "^0.14.1",
|
||||
"@semantic-release/exec": "^6.0.2",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"semantic-release": "^18.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"serialport": "^9.2.5",
|
||||
"webusb": "^2.2.0",
|
||||
"ws": "^8.2.3"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
import {
|
||||
PACKET_PROCESS,
|
||||
PACKET_RECEIVE,
|
||||
PACKET_RECEIVE_ANNOUNCE,
|
||||
PACKET_SEND,
|
||||
WEBSOCKET_TRANSPORT,
|
||||
createUSBTransport,
|
||||
createNodeUSBOptions,
|
||||
JDBus,
|
||||
printPacket,
|
||||
parseLogicLog,
|
||||
replayLogicLog,
|
||||
Packet,
|
||||
createNodeWebSerialTransport,
|
||||
Transport,
|
||||
serializeToTrace,
|
||||
isCancelError,
|
||||
} from "jacdac-ts"
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { readFileSync } = require("fs")
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { program } = require("commander")
|
||||
import type { CommandOptions } from "commander"
|
||||
|
||||
const log = console.log
|
||||
const debug = console.debug
|
||||
const error = console.error
|
||||
|
||||
async function mainCli() {
|
||||
const createCommand = (name: string, opts?: CommandOptions) => {
|
||||
const cmd = program.command(name, opts)
|
||||
return cmd
|
||||
}
|
||||
|
||||
log(`jacdac cli`)
|
||||
|
||||
createCommand("parse")
|
||||
.argument("<file>", "logic analyzer log file")
|
||||
.description("parse a Logic analyzer trace and replay packets")
|
||||
.action(parseCommand)
|
||||
|
||||
createCommand("stream")
|
||||
.option("--sensors", "stream sensors data")
|
||||
.option("-u, --usb", "listen to Jacdac over USB")
|
||||
.option("-s, --serial", "listen to Jacdac over SERIAL")
|
||||
.option("-p, --packets", "show all packets")
|
||||
.option("--ws", "start web socket server")
|
||||
.option("--port <number>", "specify custom web socket server port")
|
||||
.option("--devices <string>", "regular expression filter for devices")
|
||||
.option("--services <string>", "regular expression filter for services")
|
||||
.option("--rm", "delete files from output folder")
|
||||
.option("--catalog", "generate .json files for device catalog")
|
||||
.action(streamCommand)
|
||||
|
||||
await program.parseAsync(process.argv)
|
||||
}
|
||||
|
||||
async function mainWrapper() {
|
||||
try {
|
||||
await mainCli()
|
||||
} catch (e) {
|
||||
error("Exception: " + e.stack)
|
||||
error("Build failed")
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
mainWrapper()
|
||||
|
||||
async function streamCommand(
|
||||
options: {
|
||||
usb?: boolean
|
||||
serial?: boolean
|
||||
ws?: boolean
|
||||
catalog?: boolean
|
||||
port?: number
|
||||
packets?: boolean
|
||||
sensors?: boolean
|
||||
} = {}
|
||||
) {
|
||||
if (!options.usb && !options.serial) options.usb = options.serial = true
|
||||
|
||||
const transports: Transport[] = []
|
||||
if (options.usb) {
|
||||
debug(`adding USB transport`)
|
||||
debug(
|
||||
`on windows, node.js will crash if you haven't setup libusb properly...`
|
||||
)
|
||||
transports.push(createUSBTransport(createNodeUSBOptions()))
|
||||
}
|
||||
if (options.serial) {
|
||||
debug(`adding serial transport`)
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
transports.push(createNodeWebSerialTransport(require("serialport")))
|
||||
}
|
||||
|
||||
log(`starting bus...`)
|
||||
const bus = new JDBus(transports, { client: false })
|
||||
if (options.ws) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const ws = require("ws")
|
||||
const port = options.port || 8080
|
||||
const urls = [`http://localhost:${port}/`, `http://127.0.0.1:${port}/`]
|
||||
log(`starting web socket server`)
|
||||
urls.forEach(url => debug(`\t${url}`))
|
||||
const wss = new ws.WebSocketServer({ port })
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
wss.on("connection", (ws: any) => {
|
||||
debug(`ws: client connected`)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
ws.on("message", (message: any) => {
|
||||
const data = new Uint8Array(message as ArrayBuffer)
|
||||
const pkt = Packet.fromBinary(data, bus.timestamp)
|
||||
pkt.sender = WEBSOCKET_TRANSPORT
|
||||
bus.processPacket(pkt)
|
||||
})
|
||||
const cleanup = bus.subscribe(
|
||||
[PACKET_PROCESS, PACKET_SEND],
|
||||
(pkt: Packet) => {
|
||||
ws.send(pkt.toBuffer())
|
||||
}
|
||||
)
|
||||
ws.on("close", () => {
|
||||
debug(`ws: client disconnected`)
|
||||
cleanup?.()
|
||||
})
|
||||
})
|
||||
wss.on("error", error)
|
||||
}
|
||||
if (options.packets)
|
||||
bus.on(PACKET_PROCESS, (pkt: Packet) => {
|
||||
const str = printPacket(pkt, {
|
||||
showTime: true,
|
||||
skipRepeatedAnnounce: true,
|
||||
skipResetIn: true,
|
||||
})
|
||||
if (str) debug(serializeToTrace(pkt, 0))
|
||||
})
|
||||
bus.streaming = !!options.sensors
|
||||
bus.start()
|
||||
const run = async () => {
|
||||
try {
|
||||
await bus.connect()
|
||||
} catch (e) {
|
||||
if (!isCancelError(e)) error(e)
|
||||
}
|
||||
}
|
||||
run()
|
||||
}
|
||||
|
||||
async function parseCommand(file: string) {
|
||||
const bus = new JDBus([], { client: false })
|
||||
const opts = {
|
||||
skipRepeatedAnnounce: false,
|
||||
showTime: true,
|
||||
}
|
||||
bus.on(PACKET_RECEIVE, pkt => log(printPacket(pkt, opts)))
|
||||
bus.on(PACKET_RECEIVE_ANNOUNCE, pkt => log(printPacket(pkt, opts)))
|
||||
|
||||
const text = readFileSync(file, "utf8")
|
||||
replayLogicLog(bus, parseLogicLog(text), Number.POSITIVE_INFINITY)
|
||||
setTimeout(() => process.exit(0), 500)
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче