Skip to content

Commit 478d6a2

Browse files
committed
Lints
Signed-off-by: itowlson <[email protected]>
1 parent 20ac32f commit 478d6a2

File tree

2 files changed

+124
-48
lines changed

2 files changed

+124
-48
lines changed

src/commands/add.rs

Lines changed: 118 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,21 @@ use spin_manifest::{
99
schema::v2::{AppManifest, ComponentDependency},
1010
};
1111
use spin_serde::{DependencyName, DependencyPackageName, KebabId};
12-
use std::{collections::HashMap, path::{Path, PathBuf}};
12+
use std::{
13+
collections::HashMap,
14+
path::{Path, PathBuf},
15+
};
1316
use tokio::fs;
1417
use url::Url;
1518
use wasm_pkg_client::{PackageRef, Registry};
1619
use wit_parser::{PackageId, Resolve};
1720

1821
use crate::common::{
19-
constants::SPIN_WIT_DIRECTORY, interact::{select_multiple_prompt, select_prompt}, manifest::{edit_component_deps_in_manifest, get_component_ids}, paths::fs_safe_segment, wit::{
20-
get_exported_interfaces, parse_component_bytes, resolve_to_wit,
21-
}
22+
constants::SPIN_WIT_DIRECTORY,
23+
interact::{select_multiple_prompt, select_prompt},
24+
manifest::{edit_component_deps_in_manifest, get_component_ids},
25+
paths::fs_safe_segment,
26+
wit::{get_exported_interfaces, parse_component_bytes, resolve_to_wit},
2227
};
2328

2429
mod http;
@@ -94,7 +99,8 @@ impl ComponentSource {
9499

95100
impl AddCommand {
96101
pub async fn run(&self) -> Result<()> {
97-
let (manifest_file, distance) = spin_common::paths::find_manifest_file_path(self.manifest_path.as_ref())?;
102+
let (manifest_file, distance) =
103+
spin_common::paths::find_manifest_file_path(self.manifest_path.as_ref())?;
98104
if distance > 0 {
99105
anyhow::bail!(
100106
"No spin.toml in current directory - did you mean '-f {}'?",
@@ -131,48 +137,78 @@ impl AddCommand {
131137
// };
132138
// }
133139

134-
let target_component_id = KebabId::try_from(selected_component.clone()).map_err(|e| anyhow!("{e}"))?;
135-
let target_component = manifest.components.get(&target_component_id).ok_or_else(|| anyhow!("component does not exist"))?;
140+
let target_component_id =
141+
KebabId::try_from(selected_component.clone()).map_err(|e| anyhow!("{e}"))?;
142+
let target_component = manifest
143+
.components
144+
.get(&target_component_id)
145+
.ok_or_else(|| anyhow!("component does not exist"))?;
146+
147+
let root_dir = manifest_file
148+
.parent()
149+
.ok_or_else(|| anyhow!("Manifest cannot be the root directory"))?;
136150

137-
let root_dir = manifest_file.parent().ok_or_else(|| anyhow!("Manifest cannot be the root directory"))?;
138-
139151
// gen bindings
140152
for package in selected_interface_map.keys() {
141153
// if id != main {
142154
// continue; // TODO: yes, this is a silly way to just do main
143155
// }
144-
let id = resolve.packages.iter().find(|(_, p)| &p.name == package).unwrap().0;
156+
let id = resolve
157+
.packages
158+
.iter()
159+
.find(|(_, p)| &p.name == package)
160+
.unwrap()
161+
.0;
145162

146163
let fs_name = fs_safe_segment(package.name.to_string());
147164

148-
let dep_dir = PathBuf::from(SPIN_WIT_DIRECTORY).join("deps").join(&fs_name);
165+
let dep_dir = PathBuf::from(SPIN_WIT_DIRECTORY)
166+
.join("deps")
167+
.join(&fs_name);
149168
std::fs::create_dir_all(&dep_dir)?;
150169

151-
let output_wit_file = format!("{ns}-{name}.wit", ns = package.namespace, name = package.name);
170+
let output_wit_file = format!(
171+
"{ns}-{name}.wit",
172+
ns = package.namespace,
173+
name = package.name
174+
);
152175
let output_wit_path = dep_dir.join(output_wit_file);
153-
154-
let output_wit_text = resolve_to_wit(&resolve, id).context("failed to resolve to wit")?;
155176

156-
fs::write(&output_wit_path, output_wit_text).await.context("failed to write wit")?;
177+
let output_wit_text =
178+
resolve_to_wit(&resolve, id).context("failed to resolve to wit")?;
179+
180+
fs::write(&output_wit_path, output_wit_text)
181+
.await
182+
.context("failed to write wit")?;
157183

158184
// I _think_ we have to generate bindings for *all* the interfaces
159185
// because of the possibility of dependencies
160-
let interfaces = resolve.packages.iter().flat_map(|(_, p)|
161-
p.interfaces.keys().map(|itf_name| qualified_itf_name(&p.name, itf_name))
162-
).collect::<Vec<_>>();
186+
let interfaces = resolve
187+
.packages
188+
.iter()
189+
.flat_map(|(_, p)| {
190+
p.interfaces
191+
.keys()
192+
.map(|itf_name| qualified_itf_name(&p.name, itf_name))
193+
})
194+
.collect::<Vec<_>>();
163195

164196
let target = BindOMatic {
165197
// manifest: &manifest,
166198
root_dir,
167199
target_component,
168-
package_name: &package,
200+
package_name: package,
169201
interfaces: &interfaces,
170-
rel_wit_path: &output_wit_path
202+
rel_wit_path: &output_wit_path,
171203
};
172204
try_generate_bindings(&target).await?;
173205
}
174206

175-
let selected_interfaces = selected_interface_map.values().flatten().cloned().collect::<Vec<_>>();
207+
let selected_interfaces = selected_interface_map
208+
.values()
209+
.flatten()
210+
.cloned()
211+
.collect::<Vec<_>>();
176212
self.update_manifest(
177213
source,
178214
&manifest_file,
@@ -199,10 +235,10 @@ impl AddCommand {
199235

200236
fn target_component(&self, manifest: &AppManifest) -> anyhow::Result<String> {
201237
if let Some(id) = &self.add_to_component {
202-
return Ok(id.to_owned())
238+
return Ok(id.to_owned());
203239
}
204240

205-
let component_ids = get_component_ids(&manifest);
241+
let component_ids = get_component_ids(manifest);
206242
let selected_component_index = select_prompt(
207243
"Select a component to add the dependency to",
208244
&component_ids,
@@ -214,7 +250,11 @@ impl AddCommand {
214250
}
215251

216252
/// Prompts the user to select an interface to import.
217-
fn select_interfaces(&self, resolve: &mut Resolve, main: PackageId) -> Result<HashMap<wit_parser::PackageName, Vec<String>>> {
253+
fn select_interfaces(
254+
&self,
255+
resolve: &mut Resolve,
256+
main: PackageId,
257+
) -> Result<HashMap<wit_parser::PackageName, Vec<String>>> {
218258
let world_id = resolve.select_world(main, None)?;
219259
let exported_interfaces = get_exported_interfaces(resolve, world_id);
220260

@@ -319,8 +359,12 @@ impl AddCommand {
319359
);
320360
}
321361

322-
let doc =
323-
edit_component_deps_in_manifest(manifest_file, selected_component, &component.dependencies).await?;
362+
let doc = edit_component_deps_in_manifest(
363+
manifest_file,
364+
selected_component,
365+
&component.dependencies,
366+
)
367+
.await?;
324368

325369
fs::write(manifest_file, doc).await?;
326370

@@ -364,20 +408,28 @@ struct BindOMatic<'a> {
364408

365409
enum Language {
366410
Rust,
367-
#[allow(dead_code)] // for now
368-
TypeScript { package_json: PathBuf },
411+
#[allow(dead_code)] // for now
412+
TypeScript {
413+
package_json: PathBuf,
414+
},
369415
}
370416

371-
impl<'a> BindOMatic<'a> {
417+
impl BindOMatic<'_> {
372418
fn try_infer_language(&self) -> anyhow::Result<Language> {
373-
let workdir = self.target_component.build.as_ref().and_then(|b| b.workdir.as_ref());
419+
let workdir = self
420+
.target_component
421+
.build
422+
.as_ref()
423+
.and_then(|b| b.workdir.as_ref());
374424
let build_dir = match workdir {
375425
None => self.root_dir.to_owned(),
376426
Some(d) => self.root_dir.join(d),
377427
};
378428

379429
if !build_dir.is_dir() {
380-
bail!("unable to establish build directory for component (thought it was {build_dir:?})");
430+
bail!(
431+
"unable to establish build directory for component (thought it was {build_dir:?})"
432+
);
381433
}
382434

383435
let cargo_toml = build_dir.join("Cargo.toml");
@@ -396,39 +448,63 @@ impl<'a> BindOMatic<'a> {
396448

397449
async fn try_generate_bindings<'a>(target: &'a BindOMatic<'a>) -> anyhow::Result<()> {
398450
match target.try_infer_language()? {
399-
Language::Rust => generate_rust_bindings(target.root_dir, target.package_name, target.interfaces, target.rel_wit_path).await,
451+
Language::Rust => {
452+
generate_rust_bindings(
453+
target.root_dir,
454+
target.package_name,
455+
target.interfaces,
456+
target.rel_wit_path,
457+
)
458+
.await
459+
}
400460
Language::TypeScript { package_json: _ } => todo!(),
401461
}
402462
}
403463

404-
async fn generate_rust_bindings(root_dir: &Path, package_name: &wit_parser::PackageName, interfaces: &[String], rel_wit_path: &Path) -> anyhow::Result<()> {
464+
async fn generate_rust_bindings(
465+
root_dir: &Path,
466+
package_name: &wit_parser::PackageName,
467+
interfaces: &[String],
468+
rel_wit_path: &Path,
469+
) -> anyhow::Result<()> {
405470
// now set up the bindings
406471
let deps_rs_dir = root_dir.join("src/deps");
407472
fs::create_dir_all(&deps_rs_dir).await?;
408473
let dep_module_name = crate::language::rust::identifier_safe(package_name);
409474

410475
// step 1: create a module with the generate! macro
411-
let imps = interfaces.iter()
476+
let imps = interfaces
477+
.iter()
412478
.filter(|itf| !crate::language::rust::is_stdlib_known(itf))
413-
.map(|i| format!(r#" import {i};"#)).collect::<Vec<_>>();
479+
.map(|i| format!(r#" import {i};"#))
480+
.collect::<Vec<_>>();
414481
let imps = imps.join("\n");
415-
let gens = interfaces.iter()
482+
let gens = interfaces
483+
.iter()
416484
.filter(|itf| !crate::language::rust::is_stdlib_known(itf))
417-
.map(|i| if crate::language::rust::is_sdk_known(i) {
485+
.map(|i| {
486+
if crate::language::rust::is_sdk_known(i) {
418487
let (qname, _) = i.split_once("@").unwrap(); // foo:bar/baz
419-
let rust_qname = qname.replace(":", "::").replace("/", "::").replace("-", "_");
420-
let sdk_form = format!("spin_sdk::wit::{rust_qname}"); // TODO: this doesn't allow for when multiple versions are present! when that happens, but ONLY when that happens, bindgen version-mangles the name
488+
let rust_qname = qname
489+
.replace(":", "::")
490+
.replace("/", "::")
491+
.replace("-", "_");
492+
let sdk_form = format!("spin_sdk::wit::{rust_qname}"); // TODO: this doesn't allow for when multiple versions are present! when that happens, but ONLY when that happens, bindgen version-mangles the name
421493
format!(r#" "{i}": {sdk_form},"#)
422494
} else {
423495
format!(r#" "{i}": generate,"#)
424496
}
425-
).collect::<Vec<_>>();
497+
})
498+
.collect::<Vec<_>>();
426499
let gens = gens.join("\n");
427500
let gen_name = format!("{}-{}", package_name.namespace, package_name.name);
428501

429502
let binding_file = deps_rs_dir.join(format!("{dep_module_name}.rs"));
430503
let gen_macro = include_str!("gen.txt")
431-
.replace("{!dep_path!}", format!("{}", rel_wit_path.display()).as_str())
504+
.replace(
505+
"{!dep_path!}",
506+
format!("{}", rel_wit_path.display()).as_str(),
507+
)
432508
.replace("{!imps!}", &imps)
433509
.replace("{!gens!}", &gens)
434510
.replace("{!gen_name!}", &gen_name);
@@ -447,11 +523,7 @@ async fn generate_rust_bindings(root_dir: &Path, package_name: &wit_parser::Pack
447523
if existing.contains(&dep_module_decl) {
448524
// nothing to do. No I am not going to worry about if it is commented out, who do you think I am rust-analyzer
449525
} else {
450-
let separator = if existing.ends_with('\n') {
451-
""
452-
} else {
453-
""
454-
};
526+
let separator = "";
455527
let new_mod_rs = format!("{existing}{separator}pub {dep_module_decl}\n");
456528
fs::write(mod_rs_file, new_mod_rs).await?;
457529
}

src/language/rust.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
pub fn identifier_safe(package_name: &wit_parser::PackageName) -> String {
2-
format!("{ns}_{name}", ns = package_name.namespace, name = package_name.name)
2+
format!(
3+
"{ns}_{name}",
4+
ns = package_name.namespace,
5+
name = package_name.name
6+
)
37
}
48

59
// TODO: moar
@@ -18,7 +22,7 @@ const STDLIB_INTERFACES: &[&str] = &[
1822
];
1923

2024
const SPIN_SDK_INTERFACES: &[&str] = &[
21-
"wasi:http/[email protected]", // TODO: or maybe this is different again
25+
"wasi:http/[email protected]", // TODO: or maybe this is different again
2226
"wasi:keyvalue/[email protected]",
2327
"wasi:keyvalue/[email protected]",
2428
"wasi:keyvalue/[email protected]",

0 commit comments

Comments
 (0)