@tishlang/tish 1.9.2 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/tish +0 -0
- package/crates/js_to_tish/src/transform/expr.rs +8 -6
- package/crates/js_to_tish/src/transform/stmt.rs +12 -13
- package/crates/tish/Cargo.toml +1 -1
- package/crates/tish/src/cargo_native_registry.rs +4 -1
- package/crates/tish/src/main.rs +11 -8
- package/crates/tish/tests/integration_test.rs +145 -7
- package/crates/tish_ast/src/ast.rs +3 -9
- package/crates/tish_build_utils/src/lib.rs +43 -15
- package/crates/tish_builtins/src/array.rs +2 -3
- package/crates/tish_builtins/src/construct.rs +15 -28
- package/crates/tish_builtins/src/globals.rs +18 -16
- package/crates/tish_builtins/src/helpers.rs +1 -4
- package/crates/tish_builtins/src/lib.rs +1 -0
- package/crates/tish_builtins/src/object.rs +10 -10
- package/crates/tish_builtins/src/string.rs +1 -3
- package/crates/tish_builtins/src/symbol.rs +83 -0
- package/crates/tish_compile/src/codegen.rs +123 -138
- package/crates/tish_compile/src/lib.rs +25 -3
- package/crates/tish_compile/src/resolve.rs +6 -3
- package/crates/tish_compile/src/types.rs +6 -6
- package/crates/tish_compile_js/src/codegen.rs +8 -5
- package/crates/tish_core/src/console_style.rs +9 -0
- package/crates/tish_core/src/json.rs +17 -7
- package/crates/tish_core/src/macros.rs +2 -2
- package/crates/tish_core/src/value.rs +192 -4
- package/crates/tish_cranelift_runtime/Cargo.toml +4 -0
- package/crates/tish_eval/src/eval.rs +135 -73
- package/crates/tish_eval/src/http.rs +18 -12
- package/crates/tish_eval/src/lib.rs +29 -0
- package/crates/tish_eval/src/regex.rs +1 -1
- package/crates/tish_eval/src/value.rs +89 -4
- package/crates/tish_eval/src/value_convert.rs +30 -8
- package/crates/tish_fmt/src/lib.rs +4 -1
- package/crates/tish_lexer/src/lib.rs +7 -2
- package/crates/tish_llvm/src/lib.rs +2 -2
- package/crates/tish_lsp/src/builtin_goto.rs +111 -10
- package/crates/tish_lsp/src/import_goto.rs +35 -22
- package/crates/tish_lsp/src/main.rs +118 -85
- package/crates/tish_native/src/build.rs +187 -10
- package/crates/tish_native/src/lib.rs +92 -8
- package/crates/tish_parser/src/lib.rs +5 -2
- package/crates/tish_parser/src/parser.rs +45 -75
- package/crates/tish_pg/src/error.rs +1 -1
- package/crates/tish_pg/src/lib.rs +61 -73
- package/crates/tish_resolve/src/lib.rs +283 -158
- package/crates/tish_resolve/src/pos.rs +10 -2
- package/crates/tish_runtime/Cargo.toml +3 -0
- package/crates/tish_runtime/src/http.rs +39 -39
- package/crates/tish_runtime/src/http_fetch.rs +12 -12
- package/crates/tish_runtime/src/lib.rs +26 -43
- package/crates/tish_runtime/src/native_promise.rs +0 -11
- package/crates/tish_runtime/src/promise.rs +14 -1
- package/crates/tish_runtime/src/promise_io.rs +1 -4
- package/crates/tish_runtime/src/ws.rs +40 -27
- package/crates/tish_runtime/tests/fetch_readable_stream.rs +10 -8
- package/crates/tish_ui/src/jsx.rs +6 -4
- package/crates/tish_ui/src/lib.rs +2 -2
- package/crates/tish_ui/src/runtime/hooks.rs +5 -15
- package/crates/tish_ui/src/runtime/mod.rs +16 -17
- package/crates/tish_vm/Cargo.toml +2 -0
- package/crates/tish_vm/src/vm.rs +218 -153
- package/crates/tish_wasm/src/lib.rs +33 -7
- package/crates/tish_wasm_runtime/Cargo.toml +4 -1
- package/crates/tish_wasm_runtime/src/lib.rs +2 -1
- package/crates/tishlang_cargo_bindgen/src/classify.rs +1 -3
- package/crates/tishlang_cargo_bindgen/src/discover.rs +10 -5
- package/crates/tishlang_cargo_bindgen/src/infer.rs +18 -8
- package/crates/tishlang_cargo_bindgen/src/lib.rs +25 -26
- package/crates/tishlang_cargo_bindgen/src/main.rs +41 -38
- package/crates/tishlang_cargo_bindgen/src/metadata.rs +4 -1
- package/justfile +3 -3
- package/package.json +1 -1
- package/platform/darwin-arm64/tish +0 -0
- package/platform/darwin-x64/tish +0 -0
- package/platform/linux-arm64/tish +0 -0
- package/platform/linux-x64/tish +0 -0
- package/platform/win32-x64/tish.exe +0 -0
|
@@ -30,6 +30,22 @@ impl std::fmt::Display for WasmError {
|
|
|
30
30
|
|
|
31
31
|
impl std::error::Error for WasmError {}
|
|
32
32
|
|
|
33
|
+
/// Map CLI / import capability names to `tishlang_wasm_runtime` Cargo features for wasm32-wasip1.
|
|
34
|
+
/// The full `http` stack (tokio/socket2/…) does not build on WASI here; `http` maps to `promise`
|
|
35
|
+
/// so `Promise` / `await` work. `ws` is skipped for the same reason.
|
|
36
|
+
fn insert_wasi_runtime_cap(out: &mut BTreeSet<String>, cap: &str) {
|
|
37
|
+
match cap {
|
|
38
|
+
"http" => {
|
|
39
|
+
out.insert("promise".to_string());
|
|
40
|
+
}
|
|
41
|
+
"ws" => {}
|
|
42
|
+
"fs" | "process" | "promise" | "timers" | "regex" => {
|
|
43
|
+
out.insert(cap.to_string());
|
|
44
|
+
}
|
|
45
|
+
_ => {}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
33
49
|
/// Resolve project, merge modules, and compile to bytecode chunk.
|
|
34
50
|
/// Returns (Chunk, Program) so WASI can extract features for the runtime.
|
|
35
51
|
fn resolve_and_compile_to_chunk(
|
|
@@ -47,8 +63,8 @@ fn resolve_and_compile_to_chunk(
|
|
|
47
63
|
let prog = merge_modules(modules)
|
|
48
64
|
.map(|m| m.program)
|
|
49
65
|
.map_err(|e| WasmError {
|
|
50
|
-
|
|
51
|
-
|
|
66
|
+
message: e.to_string(),
|
|
67
|
+
})?;
|
|
52
68
|
if optimize {
|
|
53
69
|
tishlang_opt::optimize(&prog)
|
|
54
70
|
} else {
|
|
@@ -221,11 +237,16 @@ pub fn compile_to_wasm(
|
|
|
221
237
|
/// `wasmtime {output}.wasm`
|
|
222
238
|
///
|
|
223
239
|
/// Requires: `rustup target add wasm32-wasip1`
|
|
240
|
+
///
|
|
241
|
+
/// `capabilities` is the same capability list as `tish build --target native` (e.g. from
|
|
242
|
+
/// `native_build_features_from_cli`): merged with `import`-inferred features so globals like
|
|
243
|
+
/// `Promise` / `fetch` work without a top-level `import … from 'http'`.
|
|
224
244
|
pub fn compile_to_wasi(
|
|
225
245
|
entry_path: &Path,
|
|
226
246
|
project_root: Option<&Path>,
|
|
227
247
|
output_path: &Path,
|
|
228
248
|
optimize: bool,
|
|
249
|
+
capabilities: &[String],
|
|
229
250
|
) -> Result<(), WasmError> {
|
|
230
251
|
let (chunk, program) = resolve_and_compile_to_chunk(entry_path, project_root, optimize)?;
|
|
231
252
|
if has_external_native_imports(&program) {
|
|
@@ -233,7 +254,16 @@ pub fn compile_to_wasi(
|
|
|
233
254
|
message: "WASI backend does not support external native imports (tish:egui, @scope/pkg). Built-in tish:fs, tish:http, tish:process, tish:timers are supported.".to_string(),
|
|
234
255
|
});
|
|
235
256
|
}
|
|
236
|
-
let
|
|
257
|
+
let mut wasi_feature_set: BTreeSet<String> = BTreeSet::new();
|
|
258
|
+
for f in extract_native_import_features(&program) {
|
|
259
|
+
insert_wasi_runtime_cap(&mut wasi_feature_set, f.as_str());
|
|
260
|
+
}
|
|
261
|
+
for f in capabilities {
|
|
262
|
+
insert_wasi_runtime_cap(&mut wasi_feature_set, f.as_str());
|
|
263
|
+
}
|
|
264
|
+
// Many scripts use global setTimeout without `import` from timers.
|
|
265
|
+
wasi_feature_set.insert("timers".to_string());
|
|
266
|
+
|
|
237
267
|
let chunk_bytes = serialize(&chunk);
|
|
238
268
|
|
|
239
269
|
let stem = output_path
|
|
@@ -277,10 +307,6 @@ pub fn compile_to_wasi(
|
|
|
277
307
|
.to_string_lossy()
|
|
278
308
|
.replace('\\', "/");
|
|
279
309
|
|
|
280
|
-
// Bundled perf (`tests/main.tish`) and many scripts use global setTimeout without a top-level
|
|
281
|
-
// `import` (so `extract_native_import_features` is empty). Always link timers for WASI VM.
|
|
282
|
-
let mut wasi_feature_set: BTreeSet<String> = wasi_features.into_iter().collect();
|
|
283
|
-
wasi_feature_set.insert("timers".to_string());
|
|
284
310
|
let features_str = format!(
|
|
285
311
|
", features = [{}]",
|
|
286
312
|
wasi_feature_set
|
|
@@ -12,11 +12,14 @@ crate-type = ["cdylib", "rlib"]
|
|
|
12
12
|
[features]
|
|
13
13
|
# For wasm32-unknown-unknown (browser): wasm-bindgen, console output
|
|
14
14
|
browser = ["dep:wasm-bindgen", "tishlang_vm/wasm"]
|
|
15
|
-
# Built-in modules for WASI (wasm32-wasip1):
|
|
15
|
+
# Built-in modules for WASI (wasm32-wasip1): align with `tishlang_cranelift_runtime` / CLI caps
|
|
16
16
|
fs = ["tishlang_vm/fs"]
|
|
17
17
|
process = ["tishlang_vm/process"]
|
|
18
18
|
http = ["tishlang_vm/http"]
|
|
19
|
+
promise = ["tishlang_vm/promise"]
|
|
19
20
|
timers = ["tishlang_vm/timers"]
|
|
21
|
+
regex = ["tishlang_vm/regex"]
|
|
22
|
+
ws = ["tishlang_vm/ws"]
|
|
20
23
|
|
|
21
24
|
[dependencies]
|
|
22
25
|
tishlang_bytecode = { path = "../tish_bytecode", version = ">=0.1" }
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
//!
|
|
3
3
|
//! Two targets:
|
|
4
4
|
//! - **Browser** (wasm32-unknown-unknown): use `--features browser`, wasm-bindgen, console output
|
|
5
|
-
//! - **WASI/Wasmtime** (wasm32-wasip1): optional `timers` / `http` / … via Cargo features; `compile_to_wasi`
|
|
5
|
+
//! - **WASI/Wasmtime** (wasm32-wasip1): optional `timers` / `http` / … via Cargo features; `compile_to_wasi`
|
|
6
|
+
//! merges CLI capability flags with imports and always enables `timers` when globals use `setTimeout`.
|
|
6
7
|
|
|
7
8
|
use tishlang_bytecode::deserialize;
|
|
8
9
|
use tishlang_vm::Vm;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
//! Classify a `pub fn` from syn for glue emission (driven by signature shape, not crate name).
|
|
2
2
|
|
|
3
|
-
use syn::{
|
|
4
|
-
FnArg, GenericArgument, ItemFn, PathArguments, ReturnType, Type, TypeReference,
|
|
5
|
-
};
|
|
3
|
+
use syn::{FnArg, GenericArgument, ItemFn, PathArguments, ReturnType, Type, TypeReference};
|
|
6
4
|
|
|
7
5
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
8
6
|
pub enum SignatureClass {
|
|
@@ -26,8 +26,10 @@ pub fn discover_public_functions(crate_root: &Path) -> Result<HashMap<String, It
|
|
|
26
26
|
.filter(|e| e.path().extension().map(|x| x == "rs").unwrap_or(false))
|
|
27
27
|
{
|
|
28
28
|
let path = entry.path();
|
|
29
|
-
let text =
|
|
30
|
-
|
|
29
|
+
let text =
|
|
30
|
+
fs::read_to_string(path).map_err(|e| format!("read {}: {}", path.display(), e))?;
|
|
31
|
+
let file =
|
|
32
|
+
syn::parse_file(&text).map_err(|e| format!("parse {}: {}", path.display(), e))?;
|
|
31
33
|
|
|
32
34
|
for item in file.items {
|
|
33
35
|
if let Item::Fn(f) = item {
|
|
@@ -70,8 +72,10 @@ pub fn rust_public_fn_location(
|
|
|
70
72
|
.filter(|e| e.path().extension().map(|x| x == "rs").unwrap_or(false))
|
|
71
73
|
{
|
|
72
74
|
let path = entry.path();
|
|
73
|
-
let text =
|
|
74
|
-
|
|
75
|
+
let text =
|
|
76
|
+
fs::read_to_string(path).map_err(|e| format!("read {}: {}", path.display(), e))?;
|
|
77
|
+
let file =
|
|
78
|
+
syn::parse_file(&text).map_err(|e| format!("parse {}: {}", path.display(), e))?;
|
|
75
79
|
|
|
76
80
|
for item in file.items {
|
|
77
81
|
if let Item::Fn(f) = item {
|
|
@@ -85,7 +89,8 @@ pub fn rust_public_fn_location(
|
|
|
85
89
|
let line = u32::try_from(lc.line)
|
|
86
90
|
.map_err(|_| "span line out of range".to_string())?
|
|
87
91
|
.saturating_sub(1);
|
|
88
|
-
let col =
|
|
92
|
+
let col =
|
|
93
|
+
u32::try_from(lc.column).map_err(|_| "span column out of range".to_string())?;
|
|
89
94
|
return Ok((path.to_path_buf(), line, col));
|
|
90
95
|
}
|
|
91
96
|
}
|
|
@@ -28,7 +28,8 @@ pub fn select_glue_crate_from_package_json(
|
|
|
28
28
|
e
|
|
29
29
|
)
|
|
30
30
|
})?;
|
|
31
|
-
let j: Value =
|
|
31
|
+
let j: Value =
|
|
32
|
+
serde_json::from_str(&raw).map_err(|e| format!("{}: {}", pkg_json_path.display(), e))?;
|
|
32
33
|
let rust_deps = j
|
|
33
34
|
.get("tish")
|
|
34
35
|
.and_then(|t| t.get("rustDependencies"))
|
|
@@ -123,7 +124,8 @@ fn dep_version_req_string_glue(spec: &toml::Value) -> Result<String, String> {
|
|
|
123
124
|
}
|
|
124
125
|
|
|
125
126
|
/// Crates we ignore when inferring bindgen **upstream** from the **app** `Cargo.toml` (not the glue crate).
|
|
126
|
-
const ROOT_MANIFEST_SKIP_DEPS: &[&str] =
|
|
127
|
+
const ROOT_MANIFEST_SKIP_DEPS: &[&str] =
|
|
128
|
+
&["tishlang_runtime", "tishlang_core", "tishlang_build_utils"];
|
|
127
129
|
|
|
128
130
|
/// Registry semver for bindgen metadata probe; skips path/git/workspace-only entries (project root fallback).
|
|
129
131
|
fn dep_version_req_string_root(spec: &toml::Value) -> Option<String> {
|
|
@@ -136,7 +138,9 @@ fn dep_version_req_string_root(spec: &toml::Value) -> Option<String> {
|
|
|
136
138
|
if t.get("path").is_some() || t.get("git").is_some() {
|
|
137
139
|
return None;
|
|
138
140
|
}
|
|
139
|
-
t.get("version")
|
|
141
|
+
t.get("version")
|
|
142
|
+
.and_then(|v| v.as_str())
|
|
143
|
+
.map(|s| s.to_string())
|
|
140
144
|
}
|
|
141
145
|
_ => None,
|
|
142
146
|
}
|
|
@@ -209,13 +213,15 @@ fn disambiguate_upstream_candidates(
|
|
|
209
213
|
/// disambiguating when `serde_json` is present as a JSON-bridge helper alongside another crate.
|
|
210
214
|
pub fn parse_upstream_from_glue_cargo(cargo_toml_path: &Path) -> Result<(String, String), String> {
|
|
211
215
|
let s = fs::read_to_string(cargo_toml_path).map_err(|e| e.to_string())?;
|
|
212
|
-
let root: toml::Value =
|
|
216
|
+
let root: toml::Value =
|
|
217
|
+
toml::from_str(&s).map_err(|e| format!("{}: {}", cargo_toml_path.display(), e))?;
|
|
213
218
|
let deps = root
|
|
214
219
|
.get("dependencies")
|
|
215
220
|
.and_then(|d| d.as_table())
|
|
216
221
|
.ok_or_else(|| format!("{} has no [dependencies]", cargo_toml_path.display()))?;
|
|
217
222
|
|
|
218
|
-
let candidates =
|
|
223
|
+
let candidates =
|
|
224
|
+
collect_upstream_candidates_from_table(deps, &[], dep_version_req_string_glue)?;
|
|
219
225
|
disambiguate_upstream_candidates(
|
|
220
226
|
candidates,
|
|
221
227
|
cargo_toml_path,
|
|
@@ -226,9 +232,12 @@ pub fn parse_upstream_from_glue_cargo(cargo_toml_path: &Path) -> Result<(String,
|
|
|
226
232
|
/// Infer upstream from the **project** `Cargo.toml` when the glue crate does not exist yet.
|
|
227
233
|
/// Uses `[dependencies]` and `[dev-dependencies]`, skips Tish toolchain path crates (`tishlang_core`, …),
|
|
228
234
|
/// and only keeps entries with a registry semver (skips bare `path =` / `git` deps).
|
|
229
|
-
pub fn parse_upstream_from_root_package_cargo(
|
|
235
|
+
pub fn parse_upstream_from_root_package_cargo(
|
|
236
|
+
cargo_toml_path: &Path,
|
|
237
|
+
) -> Result<(String, String), String> {
|
|
230
238
|
let s = fs::read_to_string(cargo_toml_path).map_err(|e| e.to_string())?;
|
|
231
|
-
let root: toml::Value =
|
|
239
|
+
let root: toml::Value =
|
|
240
|
+
toml::from_str(&s).map_err(|e| format!("{}: {}", cargo_toml_path.display(), e))?;
|
|
232
241
|
|
|
233
242
|
let mut candidates = root
|
|
234
243
|
.get("dependencies")
|
|
@@ -255,7 +264,8 @@ pub fn infer_from_project_root(
|
|
|
255
264
|
project_root: &Path,
|
|
256
265
|
rust_dep_key: Option<&str>,
|
|
257
266
|
) -> Result<InferredProjectBindgen, String> {
|
|
258
|
-
let (output_crate_name, out_dir) =
|
|
267
|
+
let (output_crate_name, out_dir) =
|
|
268
|
+
select_glue_crate_from_package_json(project_root, rust_dep_key)?;
|
|
259
269
|
let glue_cargo = out_dir.join("Cargo.toml");
|
|
260
270
|
let root_cargo = project_root.join("Cargo.toml");
|
|
261
271
|
|
|
@@ -22,7 +22,9 @@ mod metadata;
|
|
|
22
22
|
|
|
23
23
|
pub use classify::SignatureClass;
|
|
24
24
|
pub use discover::rust_public_fn_location;
|
|
25
|
-
pub use metadata::{
|
|
25
|
+
pub use metadata::{
|
|
26
|
+
resolve_dependency_from_manifest, resolve_registry_dependency, ResolvedDependency,
|
|
27
|
+
};
|
|
26
28
|
|
|
27
29
|
use std::fs;
|
|
28
30
|
use std::io;
|
|
@@ -69,7 +71,10 @@ pub fn generate_from_manifest(
|
|
|
69
71
|
generate_from_resolved(cfg, &resolved)
|
|
70
72
|
}
|
|
71
73
|
|
|
72
|
-
fn generate_from_resolved(
|
|
74
|
+
fn generate_from_resolved(
|
|
75
|
+
cfg: &BindgenConfig,
|
|
76
|
+
resolved: &ResolvedDependency,
|
|
77
|
+
) -> Result<(), String> {
|
|
73
78
|
let root = resolved.source_root();
|
|
74
79
|
let fns = discover::discover_public_functions(&root)?;
|
|
75
80
|
|
|
@@ -102,17 +107,9 @@ fn generate_from_resolved(cfg: &BindgenConfig, resolved: &ResolvedDependency) ->
|
|
|
102
107
|
emitted.push((export.clone(), class));
|
|
103
108
|
}
|
|
104
109
|
|
|
105
|
-
let lib_rs = render_generated_lib(
|
|
106
|
-
&cfg.dependency_name,
|
|
107
|
-
&emitted,
|
|
108
|
-
need_json_helpers,
|
|
109
|
-
)?;
|
|
110
|
+
let lib_rs = render_generated_lib(&cfg.dependency_name, &emitted, need_json_helpers)?;
|
|
110
111
|
|
|
111
|
-
let cargo_toml = render_output_cargo_toml(
|
|
112
|
-
cfg,
|
|
113
|
-
resolved.version(),
|
|
114
|
-
need_json_helpers,
|
|
115
|
-
)?;
|
|
112
|
+
let cargo_toml = render_output_cargo_toml(cfg, resolved.version(), need_json_helpers)?;
|
|
116
113
|
|
|
117
114
|
fs::create_dir_all(cfg.out_dir.join("src")).map_err(|e| e.to_string())?;
|
|
118
115
|
fs::write(cfg.out_dir.join("Cargo.toml"), cargo_toml).map_err(|e| e.to_string())?;
|
|
@@ -128,16 +125,18 @@ impl BindgenConfig {
|
|
|
128
125
|
}
|
|
129
126
|
}
|
|
130
127
|
|
|
131
|
-
fn render_output_cargo_toml(
|
|
128
|
+
fn render_output_cargo_toml(
|
|
129
|
+
cfg: &BindgenConfig,
|
|
130
|
+
dep_exact_version: &str,
|
|
131
|
+
need_serde_json: bool,
|
|
132
|
+
) -> Result<String, String> {
|
|
132
133
|
let rt_line = match &cfg.tishlang_runtime {
|
|
133
|
-
TishlangRuntimeDep::Path(p) =>
|
|
134
|
-
"tishlang_runtime = {{ path = {} }}\n",
|
|
135
|
-
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
toml_string_value(req)
|
|
140
|
-
),
|
|
134
|
+
TishlangRuntimeDep::Path(p) => {
|
|
135
|
+
format!("tishlang_runtime = {{ path = {} }}\n", toml_string_value(p))
|
|
136
|
+
}
|
|
137
|
+
TishlangRuntimeDep::Version(req) => {
|
|
138
|
+
format!("tishlang_runtime = {}\n", toml_string_value(req))
|
|
139
|
+
}
|
|
141
140
|
};
|
|
142
141
|
let dep_line = format!(
|
|
143
142
|
"{} = {}\n",
|
|
@@ -185,10 +184,7 @@ fn render_generated_lib(
|
|
|
185
184
|
use tishlang_runtime::{ObjectMap, Value, VmRef};\n\n",
|
|
186
185
|
);
|
|
187
186
|
|
|
188
|
-
out.push_str(&format!(
|
|
189
|
-
"use {} as _tish_upstream;\n\n",
|
|
190
|
-
crate_ident
|
|
191
|
-
));
|
|
187
|
+
out.push_str(&format!("use {} as _tish_upstream;\n\n", crate_ident));
|
|
192
188
|
|
|
193
189
|
if need_json_helpers {
|
|
194
190
|
out.push_str(JSON_HELPERS);
|
|
@@ -318,7 +314,10 @@ fn canonical_path_string(p: &Path) -> Result<String, String> {
|
|
|
318
314
|
}
|
|
319
315
|
|
|
320
316
|
/// Relative path from `out_dir` to `runtime` for Cargo.toml `path =`.
|
|
321
|
-
pub fn runtime_path_relative_to_out_dir(
|
|
317
|
+
pub fn runtime_path_relative_to_out_dir(
|
|
318
|
+
out_dir: &Path,
|
|
319
|
+
runtime: impl AsRef<Path>,
|
|
320
|
+
) -> Result<String, String> {
|
|
322
321
|
let abs_rt = runtime
|
|
323
322
|
.as_ref()
|
|
324
323
|
.canonicalize()
|
|
@@ -8,7 +8,8 @@ use std::path::PathBuf;
|
|
|
8
8
|
use clap::Parser;
|
|
9
9
|
use tishlang_cargo_bindgen::{
|
|
10
10
|
generate_from_manifest, generate_from_registry_dependency, infer,
|
|
11
|
-
resolve_runtime_path_for_output, runtime_path_relative_to_out_dir, BindgenConfig,
|
|
11
|
+
resolve_runtime_path_for_output, runtime_path_relative_to_out_dir, BindgenConfig,
|
|
12
|
+
TishlangRuntimeDep,
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
#[derive(Parser, Debug)]
|
|
@@ -83,49 +84,51 @@ fn run() -> Result<(), String> {
|
|
|
83
84
|
|
|
84
85
|
let current_dir = std::env::current_dir().map_err(|e| e.to_string())?;
|
|
85
86
|
|
|
86
|
-
let (
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
87
|
+
let (output_crate_name, out_dir, dependency_name, dependency_version_req, search_root) =
|
|
88
|
+
if let Some(dep) = args.dependency.as_ref() {
|
|
89
|
+
if let Some(out) = args.out_dir.as_ref() {
|
|
90
|
+
let root = args
|
|
91
|
+
.project_root
|
|
92
|
+
.clone()
|
|
93
|
+
.unwrap_or_else(|| out.parent().unwrap_or(out).to_path_buf());
|
|
94
|
+
(
|
|
95
|
+
args.crate_name
|
|
96
|
+
.clone()
|
|
97
|
+
.unwrap_or_else(|| "tish_serde_json".into()),
|
|
98
|
+
out.clone(),
|
|
99
|
+
dep.clone(),
|
|
100
|
+
args.dependency_version.clone(),
|
|
101
|
+
root,
|
|
102
|
+
)
|
|
103
|
+
} else {
|
|
104
|
+
let root = args
|
|
105
|
+
.project_root
|
|
106
|
+
.clone()
|
|
107
|
+
.unwrap_or_else(|| current_dir.clone());
|
|
108
|
+
let (crate_key, od) =
|
|
109
|
+
infer::infer_glue_paths_only(&root, args.crate_name.as_deref())?;
|
|
110
|
+
(
|
|
111
|
+
crate_key,
|
|
112
|
+
od,
|
|
113
|
+
dep.clone(),
|
|
114
|
+
args.dependency_version.clone(),
|
|
115
|
+
root,
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
} else {
|
|
94
119
|
let root = args
|
|
95
120
|
.project_root
|
|
96
121
|
.clone()
|
|
97
|
-
.unwrap_or_else(||
|
|
122
|
+
.unwrap_or_else(|| current_dir.clone());
|
|
123
|
+
let inf = infer::infer_from_project_root(&root, args.crate_name.as_deref())?;
|
|
98
124
|
(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
dep.clone(),
|
|
104
|
-
args.dependency_version.clone(),
|
|
125
|
+
inf.output_crate_name,
|
|
126
|
+
inf.out_dir,
|
|
127
|
+
inf.dependency_name,
|
|
128
|
+
inf.dependency_version_req,
|
|
105
129
|
root,
|
|
106
130
|
)
|
|
107
|
-
}
|
|
108
|
-
let root = args.project_root.clone().unwrap_or_else(|| current_dir.clone());
|
|
109
|
-
let (crate_key, od) = infer::infer_glue_paths_only(&root, args.crate_name.as_deref())?;
|
|
110
|
-
(
|
|
111
|
-
crate_key,
|
|
112
|
-
od,
|
|
113
|
-
dep.clone(),
|
|
114
|
-
args.dependency_version.clone(),
|
|
115
|
-
root,
|
|
116
|
-
)
|
|
117
|
-
}
|
|
118
|
-
} else {
|
|
119
|
-
let root = args.project_root.clone().unwrap_or_else(|| current_dir.clone());
|
|
120
|
-
let inf = infer::infer_from_project_root(&root, args.crate_name.as_deref())?;
|
|
121
|
-
(
|
|
122
|
-
inf.output_crate_name,
|
|
123
|
-
inf.out_dir,
|
|
124
|
-
inf.dependency_name,
|
|
125
|
-
inf.dependency_version_req,
|
|
126
|
-
root,
|
|
127
|
-
)
|
|
128
|
-
};
|
|
131
|
+
};
|
|
129
132
|
|
|
130
133
|
let tishlang_runtime = if let Some(req) = args.tishlang_runtime_version.clone() {
|
|
131
134
|
TishlangRuntimeDep::Version(req)
|
|
@@ -35,7 +35,10 @@ fn from_package(pkg: &Package) -> ResolvedDependency {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
/// Build a tiny probe crate, run `cargo metadata`, and return the named package.
|
|
38
|
-
pub fn resolve_registry_dependency(
|
|
38
|
+
pub fn resolve_registry_dependency(
|
|
39
|
+
name: &str,
|
|
40
|
+
version_req: &str,
|
|
41
|
+
) -> Result<ResolvedDependency, String> {
|
|
39
42
|
let probe_dir = tempfile::tempdir().map_err(|e| format!("tempdir: {}", e))?;
|
|
40
43
|
let probe_toml = format!(
|
|
41
44
|
r#"[package]
|
package/justfile
CHANGED
|
@@ -125,15 +125,15 @@ test *ARGS:
|
|
|
125
125
|
|
|
126
126
|
# Run only tish package tests (same as CI: integration tests only)
|
|
127
127
|
test-tish *ARGS:
|
|
128
|
-
cargo nextest run -p tishlang--features full -- {{ARGS}}
|
|
128
|
+
cargo nextest run -p tishlang --features full -- {{ARGS}}
|
|
129
129
|
|
|
130
130
|
# Skip slow backend tests (native/cranelift/wasi) for fast local iteration
|
|
131
131
|
test-quick:
|
|
132
|
-
cargo nextest run -p tishlang--features full -- --skip test_mvp_programs_native --skip test_mvp_programs_cranelift --skip test_mvp_programs_wasi
|
|
132
|
+
cargo nextest run -p tishlang --features full -- --skip test_mvp_programs_native --skip test_mvp_programs_cranelift --skip test_mvp_programs_wasi
|
|
133
133
|
|
|
134
134
|
# Run tests with coverage (requires llvm-tools: rustup component add llvm-tools-preview)
|
|
135
135
|
test-coverage:
|
|
136
|
-
cargo llvm-cov nextest -p tishlang--features full --lcov --output-path lcov.info --html coverage-html
|
|
136
|
+
cargo llvm-cov nextest -p tishlang --features full --lcov --output-path lcov.info --html coverage-html
|
|
137
137
|
|
|
138
138
|
# Plain cargo test (whole workspace)
|
|
139
139
|
test-cargo:
|
package/package.json
CHANGED
|
Binary file
|
package/platform/darwin-x64/tish
CHANGED
|
Binary file
|
|
Binary file
|
package/platform/linux-x64/tish
CHANGED
|
Binary file
|
|
Binary file
|