Repository: wafflespeanut/paperclip
Pull request #281 (2020-12-22 16:15:41)

Provide the --no-root flag to the CLI which allows the crate to be embedded
This omits the workspace definition, allowing it to be embedded in other
repositories.

hope this patch is welcome. seems to be doing what i need locally, but I may have missed something.

Signed-off-by: Erik Hollensbe <github@hollensbe.org>

wafflespeanut: I see that the tests have failed. Feel free to add/modify them accordingly.
erikh: Sorry about that. I've provided a version now that should pass tests, I'll keep an eye on it.

I'll also add a test that omits the workspace, assuming I can figure this out -- still new to rust.
erikh: Here's some tests. Thanks for letting me poke in your pie!

Patch:
diff --git a/src/bin/main.rs b/src/bin/main.rs
index 934f640d..9e1c37f3 100644
--- a/src/bin/main.rs
+++ b/src/bin/main.rs
@@ -47,6 +47,9 @@ struct Opt {
     /// Emit CLI target instead.
     #[structopt(long = "cli")]
     cli: bool,
+    /// Do not make the crate a root crate.
+    #[structopt(long = "no-root")]
+    no_root: bool,
     /// Name of the crate. If this is not specified, then the name of the
     /// working directory is assumed to be crate name.
     #[structopt(long = "name")]
@@ -83,6 +86,8 @@ fn parse_args_and_run() -> Result<(), Error> {
         meta.version = opt.version;
     }
 
+    meta.no_root = opt.no_root;
+
     state.set_meta(meta);
     let emitter = DefaultEmitter::from(state);
     emitter.generate(&spec)
diff --git a/src/build/manifest.hbs b/src/build/manifest.hbs
index 266c846f..df1348cb 100644
--- a/src/build/manifest.hbs
+++ b/src/build/manifest.hbs
@@ -39,4 +39,6 @@ reqwest = \{ version = "0.10", features = ["stream", "json", "native-tls"] }
 tokio = \{ version = "0.3", features = ["fs", "io-util"] }
 reqwest = \{ version = "0.10", features = ["stream", "json"] }
 {{ endif }}
+{{ if not no_root -}}
 [workspace]
+{{- endif }}
diff --git a/src/v2/codegen/mod.rs b/src/v2/codegen/mod.rs
index affd684d..fec431d8 100644
--- a/src/v2/codegen/mod.rs
+++ b/src/v2/codegen/mod.rs
@@ -64,6 +64,8 @@ pub struct CrateMeta {
     pub authors: Option<Vec<String>>,
     /// Whether we're planning to emit a lib, app or module.
     pub mode: EmitMode,
+    /// Whether or not to make this a root crate.
+    pub no_root: bool,
     // Marker to avoid potential breakage when more public fields come in.
     _marker: (),
 }
diff --git a/src/v2/codegen/state.rs b/src/v2/codegen/state.rs
index 20599b35..fe064721 100644
--- a/src/v2/codegen/state.rs
+++ b/src/v2/codegen/state.rs
@@ -374,6 +374,15 @@ pub mod util {
             .unwrap_or(false))
     }
 
+    fn no_root(&self) -> Result<bool, Error> {
+        Ok(self
+            .infer_crate_meta()?
+            .borrow()
+            .as_ref()
+            .map(|m| m.no_root)
+            .unwrap_or(true))
+    }
+
     /// Normalized module prefix used by codegen.
     fn normalized_mod_prefix(&self) -> String {
         format!("{}::", self.mod_prefix.trim_matches(':'))
@@ -420,6 +429,7 @@ impl EmitterState {
     fn create_manifest(&self) -> Result<(), Error> {
         let mut man_path = self.root_module_path();
         let is_cli = self.is_cli()?;
+        let no_root = self.no_root()?;
         man_path.set_file_name("Cargo.toml");
 
         let cm = self.infer_crate_meta()?;
@@ -437,6 +447,7 @@ impl EmitterState {
                     version: &format!("{:?}", meta.version.as_ref().unwrap()),
                     authors: &format!("{:?}", meta.authors.as_ref().unwrap()),
                     is_cli,
+                    no_root,
                 },
             )?;
 
@@ -572,6 +583,7 @@ struct ManifestContext<'a> {
     version: &'a str,
     authors: &'a str,
     is_cli: bool,
+    no_root: bool,
 }
 
 #[derive(serde::Serialize)]


Test patch:
diff --git a/tests/snapshots/test_codegen__tests__test_pet__no_root__Cargo.toml.snap b/tests/snapshots/test_codegen__tests__test_pet__no_root__Cargo.toml.snap
new file mode 100644
index 00000000..e8f542cf
--- /dev/null
+++ b/tests/snapshots/test_codegen__tests__test_pet__no_root__Cargo.toml.snap
@@ -0,0 +1,35 @@
+---
+source: tests/test_codegen.rs
+expression: data
+---
+[package]
+name = "no_root"
+version = "0.1.0"
+authors = ["Me <me@example.com>"]
+edition = "2018"
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+async-trait = "0.1"
+bytes = "0.5"
+thiserror = "1.0"
+futures = "0.3"
+http = "0.2"
+lazy_static = "1.4"
+log = "0.4"
+mime = { git = "https://github.com/hyperium/mime" }
+mime_guess = "2.0"
+parking_lot = "0.11"
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
+serde_yaml = "0.8"
+tokio-util = { version = "0.4", features = ["codec"] }
+url = "2.1"
+
+tokio = { version = "0.3", features = ["fs", "io-util"] }
+reqwest = { version = "0.10", features = ["stream", "json"] }
+
+
+
diff --git a/tests/test_codegen.rs b/tests/test_codegen.rs
index 0e34429b..ad6c423b 100644
--- a/tests/test_codegen.rs
+++ b/tests/test_codegen.rs
@@ -30,6 +30,19 @@ static CODEGEN_PET_LIB: Lazy<()> = Lazy::new(|| {
     let emitter = DefaultEmitter::from(state);
     emitter.generate(&PET_SCHEMA).expect("codegen");
 });
+static CODEGEN_PET_LIB_NO_ROOT: Lazy<()> = Lazy::new(|| {
+    let mut state = EmitterState::default();
+    state.working_dir = ROOT.clone();
+    state.working_dir.push("tests/test_pet/no_root");
+    let mut meta = CrateMeta::default();
+    meta.authors = Some(vec!["Me <me@example.com>".into()]);
+    meta.mode = EmitMode::Crate;
+    meta.no_root = true;
+    state.set_meta(meta);
+
+    let emitter = DefaultEmitter::from(state);
+    emitter.generate(&PET_SCHEMA).expect("codegen");
+});
 static CODEGEN_PET_CLI: Lazy<()> = Lazy::new(|| {
     let mut state = EmitterState::default();
     state.working_dir = (&*ROOT).into();
@@ -91,6 +104,7 @@ static CODEGEN: Lazy<()> = Lazy::new(|| {
         .filter(Some("paperclip"), log::LevelFilter::Info)
         .init();
     Lazy::force(&CODEGEN_PET_LIB);
+    Lazy::force(&CODEGEN_PET_LIB_NO_ROOT);
     Lazy::force(&CODEGEN_PET_CLI);
     Lazy::force(&CODEGEN_K8S_LIB);
     Lazy::force(&CODEGEN_K8S_CLI);
@@ -112,6 +126,11 @@ mod tests_pet {
         assert_file("tests/test_pet/lib.rs");
     }
 
+    #[test]
+    fn test_no_root_manifest() {
+        assert_file("tests/test_pet/no_root/Cargo.toml");
+    }
+
     #[test]
     fn test_manifest() {
         assert_file("tests/test_pet/Cargo.toml");