Skip to content

Commit 6c305cc

Browse files
authored
@rescript/tools package (#829)
* add tools package * update readme * use rescript v11 * simplify * remove .bs.js * remove test.json * remove bs.js * last edits * remove bs.js * remove bs.js * add public config * fix ci
1 parent 9fc353f commit 6c305cc

File tree

11 files changed

+545
-0
lines changed

11 files changed

+545
-0
lines changed

.github/workflows/ci.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,19 @@ jobs:
219219
run: npm publish
220220
env:
221221
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
222+
223+
- name: Copy analysis binaries to tools folder
224+
run: cp -r server/analysis_binaries/* tools/analysis_binaries
225+
226+
- name: Build @rescript/tools package
227+
working-directory: tools
228+
run: |
229+
npm ci
230+
npm run build
231+
232+
- name: Publish @rescript/tools package
233+
if: ${{ startsWith(github.event.head_commit.message, 'publish tools') && (github.ref == 'refs/heads/master') }}
234+
working-directory: tools
235+
run: npm publish
236+
env:
237+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ analysis/_build
88
analysis/tests/.merlin
99
analysis/rescript-editor-analysis.exe
1010
analysis/_opam
11+
tools/node_modules
12+
tools/lib
13+
tools/**/*.bs.js

tools/README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# ReScript Tools
2+
3+
## Install
4+
5+
```sh
6+
npm install --save-dev @rescript/tools
7+
```
8+
9+
## CLI Usage
10+
11+
```sh
12+
restools --help
13+
```
14+
15+
### Generate documentation
16+
17+
Print JSON:
18+
19+
```sh
20+
restools doc src/EntryPointLibFile.res
21+
```
22+
23+
Write JSON:
24+
25+
```sh
26+
restools doc src/EntryPointLibFile.res > doc.json
27+
```
28+
29+
### Reanalyze
30+
31+
```sh
32+
restools reanalyze --help
33+
```
34+
35+
## Decode JSON
36+
37+
Add to `bs-dev-dependencies`:
38+
39+
```json
40+
"bs-dev-dependencies": ["@rescript/tools"]
41+
```
42+
43+
```rescript
44+
// Read JSON file and parse with `Js.Json.parseExn`
45+
json->RescriptTools.Docgen.decodeFromJson
46+
```

tools/analysis_binaries/.gitkeep

Whitespace-only changes.

tools/package-lock.json

Lines changed: 43 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tools/package.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"name": "@rescript/tools",
3+
"description": "ReScript Tools",
4+
"version": "0.1.0",
5+
"author": "chenglou",
6+
"license": "MIT",
7+
"bin": {
8+
"restools": "./src/Cli.bs.js"
9+
},
10+
"keywords": [
11+
"ReScript",
12+
"Tools",
13+
"Docgen"
14+
],
15+
"files": [
16+
"src/Cli.bs.js",
17+
"src/*.res",
18+
"src/*.resi",
19+
"analysis_binaries/",
20+
"README.md"
21+
],
22+
"engines": {
23+
"node": "*"
24+
},
25+
"homepage": "https://github.com/rescript-lang/rescript-vscode/tools/README.md",
26+
"repository": {
27+
"type": "git",
28+
"url": "https://github.com/rescript-lang/rescript-vscode",
29+
"directory": "tools"
30+
},
31+
"bugs": {
32+
"url": "https://github.com/rescript-lang/rescript-vscode/issues"
33+
},
34+
"scripts": {
35+
"build": "rescript build"
36+
},
37+
"dependencies": {
38+
"rescript": "^11.0.0-rc.4"
39+
}
40+
}

tools/rescript.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "@rescript/tools",
3+
"version": "0.1.0",
4+
"sources": [
5+
{
6+
"dir": "src",
7+
"public": ["RescriptTools"]
8+
}
9+
],
10+
"suffix": ".bs.js",
11+
"package-specs": {
12+
"module": "commonjs",
13+
"in-source": true
14+
}
15+
}

tools/src/Cli.res

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
@@directive("#!/usr/bin/env node")
2+
3+
@module("fs") external readFileSync: string => string = "readFileSync"
4+
@variadic @module("path") external join: array<string> => string = "join"
5+
@module("path") external dirname: string => string = "dirname"
6+
@val external __dirname: string = "__dirname"
7+
8+
module Buffer = {
9+
type t
10+
11+
@send external toString: t => string = "toString"
12+
}
13+
14+
type spawnSyncResult = {
15+
stdout: Buffer.t,
16+
stderr: Buffer.t,
17+
status: Js.Null.t<int>,
18+
}
19+
@module("child_process")
20+
external spawnSync: (string, array<string>) => spawnSyncResult = "spawnSync"
21+
22+
@val @scope("process")
23+
external exit: int => unit = "exit"
24+
25+
@val
26+
external process: {"arch": string, "platform": string, "argv": array<string>} = "process"
27+
28+
let argv = process["argv"]
29+
30+
let args = argv->Js.Array2.slice(~start=2, ~end_=Js.Array2.length(argv))
31+
32+
let platformDir =
33+
process["arch"] === "arm64" ? process["platform"] ++ process["arch"] : process["platform"]
34+
35+
let analysisProdPath = join([
36+
dirname(__dirname),
37+
"analysis_binaries",
38+
platformDir,
39+
"rescript-editor-analysis.exe",
40+
])
41+
42+
let docHelp = `ReScript Tools
43+
44+
Output documentation to standard output
45+
46+
Usage: restools doc <FILE>
47+
48+
Example: restools doc ./path/to/EntryPointLib.res`
49+
50+
let help = `ReScript Tools
51+
52+
Usage: restools [command]
53+
54+
Commands:
55+
56+
doc Generate documentation
57+
reanalyze Reanalyze
58+
-v, --version Print version
59+
-h, --help Print help`
60+
61+
let logAndExit = (~log, ~code) => {
62+
Js.log(log)
63+
exit(code)
64+
}
65+
66+
switch args->Belt.List.fromArray {
67+
| list{"doc", ...rest} =>
68+
switch rest {
69+
| list{"-h" | "--help"} => logAndExit(~log=docHelp, ~code=0)
70+
| list{filePath} =>
71+
let spawn = spawnSync(analysisProdPath, ["extractDocs", filePath])
72+
73+
switch spawn.status->Js.Null.toOption {
74+
| Some(code) if code !== 0 => logAndExit(~log=spawn.stderr->Buffer.toString, ~code)
75+
| Some(code) => logAndExit(~log=spawn.stdout->Buffer.toString, ~code)
76+
| None => logAndExit(~log=`error: unexpected error to extract docs for ${filePath}`, ~code=1)
77+
}
78+
| _ => logAndExit(~log=docHelp, ~code=1)
79+
}
80+
| list{"reanalyze", ...rest} =>
81+
let args = ["reanalyze"]->Js.Array2.concat(Belt.List.toArray(rest))
82+
let spawn = spawnSync(analysisProdPath, args)
83+
84+
switch spawn.status->Js.Null.toOption {
85+
| Some(code) if code !== 0 => logAndExit(~log=spawn.stderr->Buffer.toString, ~code)
86+
| Some(code) => logAndExit(~log=spawn.stdout->Buffer.toString, ~code)
87+
| None =>
88+
logAndExit(
89+
~log=`error: unexpected error to run reanalyze with arguments: ${args->Js.Array2.joinWith(
90+
" ",
91+
)}`,
92+
~code=1,
93+
)
94+
}
95+
| list{"-h" | "--help"} => logAndExit(~log=help, ~code=0)
96+
| list{"-v" | "--version"} =>
97+
switch readFileSync("./package.json")->Js.Json.parseExn->Js.Json.decodeObject {
98+
| None => logAndExit(~log="error: failed to find version in package.json", ~code=1)
99+
| Some(dict) => logAndExit(~log=dict->Js.Dict.unsafeGet("version"), ~code=0)
100+
}
101+
| _ => logAndExit(~log=help, ~code=1)
102+
}

tools/src/RescriptTools.res

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module Docgen = Tools_Docgen

0 commit comments

Comments
 (0)