Skip to content

Commit 621f8a7

Browse files
authored
Publish native package (#22)
* feat: migrate to use explicit subcommands What was at the root is now under the "generate" subcommand * feat: add subcommand for creating a native package to wrap a given dlib * fix: rename out_disable_auto_loading_lib => out_lib_disable_auto_loading to match new upcoming args * fix: update native package scaffolding output to generate functions rather than just constants * feat: add out_lib_path_module for use with generated native modules * feat: add filters matching actual js values to check * feat: add better support for modules without filters * feat: expose last resolution error if requiring module fails * feat: move LibPath::Module resolution logic into commonjs shim layer This should ensure that `require` will definitely exist. * feat: add optional dependency generation from lib path modules * feat: expose os / cpu package json fields * feat: add --out-lib-path-module json parsing idea from 1:1 with jacob * feat: add d.cts types for cjs file Worth revisiting - it might be possible to make a *.cts file and skip the *.d.cts * fix: build d.cts and include link in generated package.json * feat: migrate to cts for commonjs-shim * fix: address typos in package setup * feat: add more robust tests for LibPath::as_switch_tokens_by * feat: run tests in github actions for each repo push * fix: remove --profile ci from github workflow * feat: migrate to GenerateNodeBindingsOptions struct for passing params to generate_node_bindings I have some further thoughts on how to make this nicer (a From<> implementation directly into the templates) but I will hold off on doing that until I clean those templates up. * fix: add missing import * fix: add missing options prefix * fix: ensure that break after case end is handled Previously, cases would fallthrough, and that was not what was intended. * fix: address import path typos
1 parent 5deee17 commit 621f8a7

File tree

15 files changed

+887
-175
lines changed

15 files changed

+887
-175
lines changed

.github/workflows/test.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Test
2+
on:
3+
workflow_dispatch:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
types:
9+
- opened
10+
- reopened
11+
- synchronize
12+
- ready_for_review
13+
jobs:
14+
test:
15+
name: Test
16+
runs-on: ubuntu-latest
17+
timeout-minutes: 10
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v6
21+
- name: Setup Rust Toolchain
22+
uses: actions-rust-lang/setup-rust-toolchain@v1
23+
- name: Test
24+
run: cargo test

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ cargo_metadata = "0.19.2" # NOTE: keep this version up to date with the version
1111
clap = { version = "4.5.51", features = ["derive"] }
1212
heck = "0.5.0"
1313
serde = "1.0.228"
14+
serde_json = "1.0.149"
1415
textwrap = "0.16.2"
1516
toml = "0.9.8"
1617
uniffi = "0.30.0"

src/bindings/generator.rs

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ use anyhow::{Context, Result};
88
use askama::Template;
99
use heck::ToKebabCase;
1010

11-
use crate::bindings::{filters, utils::{DirnameApi, ImportExtension}};
11+
use crate::bindings::{filters, utils::{DirnameApi, ImportExtension, LibPath, LibPathSwitchToken}};
1212

1313
pub struct Bindings {
1414
pub package_json_contents: String,
1515
pub sys_ts_template_contents: String,
16+
pub commonjs_shim_cts_template_contents: String,
1617
pub node_ts_file_contents: String,
1718
pub index_ts_file_contents: String,
1819
}
@@ -22,11 +23,12 @@ pub struct Bindings {
2223
struct PackageJsonTemplate<'ci> {
2324
ci: &'ci ComponentInterface,
2425
out_node_version: String,
26+
out_lib_path: LibPath,
2527
}
2628

2729
impl<'ci> PackageJsonTemplate<'ci> {
28-
pub fn new(ci: &'ci ComponentInterface, out_node_version: &str) -> Self {
29-
Self { ci, out_node_version: out_node_version.into() }
30+
pub fn new(ci: &'ci ComponentInterface, out_node_version: &str, out_lib_path: LibPath) -> Self {
31+
Self { ci, out_node_version: out_node_version.into(), out_lib_path }
3032
}
3133
}
3234

@@ -36,22 +38,46 @@ struct SysTemplate<'ci> {
3638
ci: &'ci ComponentInterface,
3739

3840
out_dirname_api: DirnameApi,
39-
out_disable_auto_loading_lib: bool,
41+
out_lib_disable_auto_loading: bool,
4042
out_verbose_logs: bool,
43+
out_lib_path: LibPath,
44+
commonjs_shim_cjs_main_file_name: String,
4145
}
4246

4347
impl<'ci> SysTemplate<'ci> {
4448
pub fn new(
4549
ci: &'ci ComponentInterface,
4650
out_dirname_api: DirnameApi,
47-
out_disable_auto_loading_lib: bool,
51+
out_lib_disable_auto_loading: bool,
4852
out_verbose_logs: bool,
53+
out_lib_path: LibPath,
54+
commonjs_shim_cjs_main_file_name: &str,
4955
) -> Self {
50-
Self { ci, out_dirname_api, out_disable_auto_loading_lib, out_verbose_logs }
56+
Self {
57+
ci,
58+
out_dirname_api,
59+
out_lib_disable_auto_loading,
60+
out_verbose_logs,
61+
out_lib_path,
62+
commonjs_shim_cjs_main_file_name: commonjs_shim_cjs_main_file_name.into(),
63+
}
64+
}
65+
}
66+
67+
#[derive(Template)]
68+
#[template(escape = "none", path = "commonjs-shim.cts")]
69+
struct CommonJsShimTemplate {
70+
out_lib_path: LibPath,
71+
}
72+
73+
impl CommonJsShimTemplate {
74+
pub fn new(out_lib_path: LibPath) -> Self {
75+
Self { out_lib_path }
5176
}
5277
}
5378

5479

80+
5581
#[derive(Template)]
5682
#[template(escape = "none", path = "node.ts")]
5783
struct NodeTsTemplate<'ci> {
@@ -83,43 +109,53 @@ struct IndexTsTemplate {
83109
node_ts_main_file_name: String,
84110
sys_ts_main_file_name: String,
85111
out_import_extension: ImportExtension,
86-
out_disable_auto_loading_lib: bool,
112+
out_lib_disable_auto_loading: bool,
87113
}
88114

89115
impl IndexTsTemplate {
90116
pub fn new(
91117
node_ts_main_file_name: &str,
92118
sys_ts_main_file_name: &str,
93119
out_import_extension: ImportExtension,
94-
out_disable_auto_loading_lib: bool,
120+
out_lib_disable_auto_loading: bool,
95121
) -> Self {
96122
Self {
97123
node_ts_main_file_name: node_ts_main_file_name.to_string(),
98124
sys_ts_main_file_name: sys_ts_main_file_name.to_string(),
99125
out_import_extension,
100-
out_disable_auto_loading_lib,
126+
out_lib_disable_auto_loading,
101127
}
102128
}
103129
}
104130

131+
/// Options required to pass to [generate_node_bindings] invocations.
132+
#[derive(Debug)]
133+
pub struct GenerateNodeBindingsOptions<'a> {
134+
pub sys_ts_main_file_name: &'a str,
135+
pub node_ts_main_file_name: &'a str,
136+
pub commonjs_shim_cts_main_file_name: &'a str,
137+
pub out_dirname_api: DirnameApi,
138+
pub out_lib_disable_auto_loading: bool,
139+
pub out_import_extension: ImportExtension,
140+
pub out_node_version: &'a str,
141+
pub out_verbose_logs: bool,
142+
pub out_lib_path: LibPath,
143+
}
144+
105145
pub fn generate_node_bindings(
106146
ci: &ComponentInterface,
107-
sys_ts_main_file_name: &str,
108-
node_ts_main_file_name: &str,
109-
out_dirname_api: DirnameApi,
110-
out_disable_auto_loading_lib: bool,
111-
out_import_extension: ImportExtension,
112-
out_node_version: &str,
113-
out_verbose_logs: bool,
147+
options: GenerateNodeBindingsOptions<'_>,
114148
) -> Result<Bindings> {
115-
let package_json_contents = PackageJsonTemplate::new(ci, out_node_version).render().context("failed to render package.json template")?;
116-
let sys_template_contents = SysTemplate::new(ci, out_dirname_api, out_disable_auto_loading_lib, out_verbose_logs).render().context("failed to render sys.ts template")?;
117-
let node_ts_file_contents = NodeTsTemplate::new(ci, sys_ts_main_file_name, out_import_extension.clone(), out_verbose_logs).render().context("failed to render node.ts template")?;
118-
let index_ts_file_contents = IndexTsTemplate::new(node_ts_main_file_name, sys_ts_main_file_name, out_import_extension, out_disable_auto_loading_lib).render().context("failed to render index.ts template")?;
149+
let package_json_contents = PackageJsonTemplate::new(ci, options.out_node_version, options.out_lib_path.clone()).render().context("failed to render package.json template")?;
150+
let sys_ts_template_contents = SysTemplate::new(ci, options.out_dirname_api, options.out_lib_disable_auto_loading, options.out_verbose_logs, options.out_lib_path.clone(), options.commonjs_shim_cts_main_file_name).render().context("failed to render sys.ts template")?;
151+
let commonjs_shim_cts_template_contents = CommonJsShimTemplate::new(options.out_lib_path.clone()).render().context("failed to render commonjs_shim.cjs template")?;
152+
let node_ts_file_contents = NodeTsTemplate::new(ci, options.sys_ts_main_file_name, options.out_import_extension.clone(), options.out_verbose_logs).render().context("failed to render node.ts template")?;
153+
let index_ts_file_contents = IndexTsTemplate::new(options.node_ts_main_file_name, options.sys_ts_main_file_name, options.out_import_extension, options.out_lib_disable_auto_loading).render().context("failed to render index.ts template")?;
119154

120155
Ok(Bindings {
121156
package_json_contents,
122-
sys_ts_template_contents: sys_template_contents,
157+
sys_ts_template_contents,
158+
commonjs_shim_cts_template_contents,
123159
node_ts_file_contents,
124160
index_ts_file_contents,
125161
})

src/bindings/mod.rs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,33 @@ mod generator;
1111
mod filters;
1212
pub mod utils;
1313

14-
use crate::{bindings::generator::{generate_node_bindings, Bindings}, utils::write_with_dirs};
14+
use crate::{bindings::generator::{generate_node_bindings, Bindings, GenerateNodeBindingsOptions}, utils::write_with_dirs};
1515

1616
pub struct NodeBindingGenerator {
1717
out_dirname_api: utils::DirnameApi,
18-
out_disable_auto_loading_lib: bool,
18+
out_lib_disable_auto_loading: bool,
1919
out_import_extension: utils::ImportExtension,
2020
out_node_version: String,
2121
out_verbose_logs: bool,
22+
out_lib_path: utils::LibPath,
2223
}
2324

2425
impl NodeBindingGenerator {
2526
pub fn new(
2627
out_dirname_api: utils::DirnameApi,
27-
out_disable_auto_loading_lib: bool,
28+
out_lib_disable_auto_loading: bool,
2829
out_import_extension: utils::ImportExtension,
2930
out_node_version: &str,
3031
out_verbose_logs: bool,
32+
out_lib_path: utils::LibPath,
3133
) -> Self {
3234
Self {
3335
out_dirname_api,
34-
out_disable_auto_loading_lib,
36+
out_lib_disable_auto_loading,
3537
out_import_extension,
3638
out_node_version: out_node_version.into(),
3739
out_verbose_logs,
40+
out_lib_path,
3841
}
3942
}
4043
}
@@ -70,21 +73,27 @@ impl BindingGenerator for NodeBindingGenerator {
7073
for uniffi_bindgen::Component { ci, config: _, .. } in components {
7174
let sys_ts_main_file_name = format!("{}-sys", ci.namespace().to_kebab_case());
7275
let node_ts_main_file_name = format!("{}-node", ci.namespace().to_kebab_case());
76+
let commonjs_shim_cts_main_file_name = format!("{}-commonjs-shim", ci.namespace().to_kebab_case());
7377

7478
let Bindings {
7579
package_json_contents,
7680
sys_ts_template_contents,
81+
commonjs_shim_cts_template_contents,
7782
node_ts_file_contents,
7883
index_ts_file_contents,
7984
} = generate_node_bindings(
8085
&ci,
81-
sys_ts_main_file_name.as_str(),
82-
node_ts_main_file_name.as_str(),
83-
self.out_dirname_api.clone(),
84-
self.out_disable_auto_loading_lib,
85-
self.out_import_extension.clone(),
86-
self.out_node_version.as_str(),
87-
self.out_verbose_logs,
86+
GenerateNodeBindingsOptions {
87+
sys_ts_main_file_name: sys_ts_main_file_name.as_str(),
88+
node_ts_main_file_name: node_ts_main_file_name.as_str(),
89+
commonjs_shim_cts_main_file_name: commonjs_shim_cts_main_file_name.as_str(),
90+
out_dirname_api: self.out_dirname_api.clone(),
91+
out_lib_disable_auto_loading: self.out_lib_disable_auto_loading,
92+
out_import_extension: self.out_import_extension.clone(),
93+
out_node_version: self.out_node_version.as_str(),
94+
out_verbose_logs: self.out_verbose_logs,
95+
out_lib_path: self.out_lib_path.clone(),
96+
}
8897
)?;
8998

9099
let package_json_path = settings.out_dir.join("package.json");
@@ -96,6 +105,11 @@ impl BindingGenerator for NodeBindingGenerator {
96105
let sys_template_path = settings.out_dir.join(format!("{sys_ts_main_file_name}.ts"));
97106
write_with_dirs(&sys_template_path, sys_ts_template_contents)?;
98107

108+
if !commonjs_shim_cts_template_contents.is_empty() {
109+
let commonjs_shim_template_path = settings.out_dir.join(format!("{commonjs_shim_cts_main_file_name}.cts"));
110+
write_with_dirs(&commonjs_shim_template_path, commonjs_shim_cts_template_contents)?;
111+
}
112+
99113
let index_template_path = settings.out_dir.join("index.ts");
100114
write_with_dirs(&index_template_path, index_ts_file_contents)?;
101115
}

0 commit comments

Comments
 (0)