diff --git a/Cargo.toml b/Cargo.toml index 23c5a16..ead00bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "pks" -version = "0.2.16" +version = "0.2.17" edition = "2021" description = "Welcome! Please see https://github.com/rubyatscale/pks for more information!" license = "MIT" diff --git a/src/packs.rs b/src/packs.rs index 3d6c23d..6b7420f 100644 --- a/src/packs.rs +++ b/src/packs.rs @@ -9,6 +9,7 @@ pub(crate) mod checker; pub(crate) mod checker_configuration; pub(crate) mod configuration; pub(crate) mod constant_resolver; +pub(crate) mod creator; pub(crate) mod dependencies; pub(crate) mod ignored; pub(crate) mod monkey_patch_detection; @@ -26,10 +27,10 @@ mod reference_extractor; use crate::packs; use crate::packs::pack::write_pack_to_disk; -use crate::packs::pack::Pack; // Internal imports pub(crate) use self::checker::Violation; +use self::creator::CreateResult; pub(crate) use self::pack_set::PackSet; pub(crate) use self::parsing::process_files_with_cache; pub(crate) use self::parsing::ruby::experimental::get_experimental_constant_resolver; @@ -50,47 +51,18 @@ pub fn greet() { println!("👋 Hello! Welcome to packs 📦 🔥 🎉 🌈. This tool is under construction.") } -fn create(configuration: &Configuration, name: String) -> anyhow::Result<()> { - let existing_pack = configuration.pack_set.for_pack(&name); - if existing_pack.is_ok() { - println!("`{}` already exists!", &name); - return Ok(()); +pub fn create( + configuration: &Configuration, + name: String, +) -> anyhow::Result<()> { + match creator::create(configuration, &name)? { + CreateResult::AlreadyExists => { + println!("`{}` already exists!", &name); + } + CreateResult::Success => { + println!("Successfully created `{}`!", &name); + } } - let new_pack_path = - configuration.absolute_root.join(&name).join("package.yml"); - - let new_pack = Pack::from_contents( - &new_pack_path, - &configuration.absolute_root, - "enforce_dependencies: true", - PackageTodo::default(), - )?; - - write_pack_to_disk(&new_pack)?; - - let readme = format!( -"Welcome to `{}`! - -If you're the author, please consider replacing this file with a README.md, which may contain: -- What your pack is and does -- How you expect people to use your pack -- Example usage of your pack's public API and where to find it -- Limitations, risks, and important considerations of usage -- How to get in touch with eng and other stakeholders for questions or issues pertaining to this pack -- What SLAs/SLOs (service level agreements/objectives), if any, your package provides -- When in doubt, keep it simple -- Anything else you may want to include! - -README.md should change as your public API changes. - -See https://github.com/rubyatscale/packs#readme for more info!", - new_pack.name -); - - let readme_path = configuration.absolute_root.join(&name).join("README.md"); - std::fs::write(readme_path, readme).context("Failed to write README.md")?; - - println!("Successfully created `{}`!", name); Ok(()) } diff --git a/src/packs/creator.rs b/src/packs/creator.rs new file mode 100644 index 0000000..ec89c76 --- /dev/null +++ b/src/packs/creator.rs @@ -0,0 +1,67 @@ +use anyhow::Context; + +use crate::packs::{ + pack::{write_pack_to_disk, Pack}, + PackageTodo, +}; + +use super::Configuration; + +pub enum CreateResult { + Success, + AlreadyExists, +} + +pub const NEW_PACKAGE_YML_CONTENTS: &str = "enforce_dependencies: true +enforce_privacy: true +enforce_layers: true"; + +pub fn create( + configuration: &Configuration, + name: &str, +) -> anyhow::Result { + let existing_pack = configuration.pack_set.for_pack(name); + if existing_pack.is_ok() { + return Ok(CreateResult::AlreadyExists); + } + + let new_pack_path = configuration.absolute_root.join(name); + + let new_pack = Pack::from_contents( + &new_pack_path.join("package.yml"), + &configuration.absolute_root, + NEW_PACKAGE_YML_CONTENTS, + PackageTodo::default(), + )?; + + write_pack_to_disk(&new_pack)?; + std::fs::create_dir_all(new_pack_path.join("app/public/")) + .context("failed to create app/public")?; + + let readme = readme(name); + let readme_path = &new_pack_path.join("README.md"); + std::fs::write(readme_path, readme).context("Failed to write README.md")?; + + Ok(CreateResult::Success) +} + +fn readme(pack_name: &str) -> String { + format!( +"Welcome to `{}`! + +If you're the author, please consider replacing this file with a README.md, which may contain: +- What your pack is and does +- How you expect people to use your pack +- Example usage of your pack's public API and where to find it +- Limitations, risks, and important considerations of usage +- How to get in touch with eng and other stakeholders for questions or issues pertaining to this pack +- What SLAs/SLOs (service level agreements/objectives), if any, your package provides +- When in doubt, keep it simple +- Anything else you may want to include! + +README.md should change as your public API changes. + +See https://github.com/rubyatscale/pks#readme for more info!", + pack_name +) +} diff --git a/tests/create_test.rs b/tests/create_test.rs index 9aa819c..37e1752 100644 --- a/tests/create_test.rs +++ b/tests/create_test.rs @@ -1,7 +1,7 @@ use assert_cmd::Command; use predicates::prelude::*; use pretty_assertions::assert_eq; -use std::{error::Error, fs}; +use std::{error::Error, fs, path::Path}; mod common; @@ -18,11 +18,15 @@ fn test_create() -> Result<(), Box> { "Successfully created `packs/foobar`!", )); - let expected = "enforce_dependencies: true\n"; let actual = fs::read_to_string( "tests/fixtures/simple_app/packs/foobar/package.yml", ).unwrap_or_else(|_| panic!("Could not read file tests/fixtures/simple_app/packs/foobar/package.yml")); - assert_eq!(expected, actual); + assert!(actual.contains("enforce_dependencies: true")); + assert!(actual.contains("enforce_privacy: true")); + assert!(actual.contains("enforce_layers: true")); + assert!( + Path::new("tests/fixtures/simple_app/packs/foobar/app/public").exists() + ); let expected_readme = String::from("\ Welcome to `packs/foobar`! @@ -39,7 +43,7 @@ If you're the author, please consider replacing this file with a README.md, whic README.md should change as your public API changes. -See https://github.com/rubyatscale/packs#readme for more info!"); +See https://github.com/rubyatscale/pks#readme for more info!"); let actual_readme = fs::read_to_string("tests/fixtures/simple_app/packs/foobar/README.md").unwrap_or_else(|e| { @@ -65,18 +69,6 @@ fn test_create_already_exists() -> Result<(), Box> { .success() .stdout(predicate::str::contains("`packs/foo` already exists!")); - let expected = String::from( - "\ -enforce_dependencies: true -enforce_privacy: true -dependencies: -- packs/baz -", - ); - - let actual = - fs::read_to_string("tests/fixtures/simple_app/packs/foo/package.yml")?; - assert_eq!(expected, actual); common::teardown(); Ok(()) }