diff --git a/Cargo.toml b/Cargo.toml index 818e157..c2e8a29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "pks" -version = "0.2.23" +version = "0.3.0" edition = "2021" description = "Welcome! Please see https://github.com/rubyatscale/pks for more information!" license = "MIT" diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 52b70ad..6b1db70 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.77.2" +channel = "1.83.0" components = ["clippy", "rustfmt"] targets = ["x86_64-apple-darwin", "aarch64-apple-darwin", "x86_64-unknown-linux-gnu"] diff --git a/src/packs/caching/mod.rs b/src/packs/caching/mod.rs index 20bc0f1..c3485f0 100644 --- a/src/packs/caching/mod.rs +++ b/src/packs/caching/mod.rs @@ -12,8 +12,10 @@ pub enum CacheResult { #[derive(Debug, Default)] pub struct EmptyCacheEntry { + #[allow(dead_code)] pub filepath: PathBuf, pub file_contents_digest: String, + #[allow(dead_code)] pub file_name_digest: String, pub cache_file_path: PathBuf, } diff --git a/src/packs/configuration.rs b/src/packs/configuration.rs index c1f11ad..c1f5e6f 100644 --- a/src/packs/configuration.rs +++ b/src/packs/configuration.rs @@ -32,6 +32,7 @@ pub struct Configuration { pub ignored_definitions: HashMap>, pub autoload_roots: HashMap, pub inflections_path: PathBuf, + pub readme_template_path: PathBuf, pub custom_associations: Vec, pub stdin_file_path: Option, // Note that it'd probably be better to use the logger library, `tracing` (see logger.rs) @@ -139,6 +140,12 @@ pub(crate) fn from_raw( .unwrap_or(PathBuf::from("config/initializers/inflections.rb")), ); + let readme_template_path = absolute_root.join( + raw_config + .readme_template_path + .unwrap_or(PathBuf::from("README_TEMPLATE.md")), + ); + let custom_associations = raw_config .custom_associations .iter() @@ -162,6 +169,7 @@ pub(crate) fn from_raw( ignored_definitions, autoload_roots, inflections_path, + readme_template_path, custom_associations, stdin_file_path: None, print_files: false, @@ -370,7 +378,11 @@ mod tests { assert_eq!(expected_packs, actual.pack_set.packs); - assert!(!actual.cache_enabled) + assert!(!actual.cache_enabled); + + let expected_readme_template_path = + absolute_root.join("README_TEMPLATE.md"); + assert_eq!(actual.readme_template_path, expected_readme_template_path); } #[test] @@ -456,4 +468,16 @@ mod tests { assert_eq!(actual_associations, expected_paths); } + + #[test] + fn with_readme_template_path() { + let absolute_root = + PathBuf::from("tests/fixtures/app_with_custom_readme"); + let actual = configuration::get(&absolute_root).unwrap(); + + let actual_readme_template_path = actual.readme_template_path; + let expected_readme_template_path = + absolute_root.join("config/packs/README_EXAMPLE.md"); + assert_eq!(actual_readme_template_path, expected_readme_template_path); + } } diff --git a/src/packs/creator.rs b/src/packs/creator.rs index 472b668..cd4e39c 100644 --- a/src/packs/creator.rs +++ b/src/packs/creator.rs @@ -52,15 +52,20 @@ pub fn create( .context("failed to create spec")?; } - let readme = readme(name); + let readme = readme(configuration, 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!( +fn readme(configuration: &Configuration, pack_name: &str) -> String { + let readme_template_path = configuration.readme_template_path.clone(); + + if readme_template_path.exists() { + std::fs::read_to_string(readme_template_path).unwrap() + } else { + format!( "Welcome to `{}`! If you're the author, please consider replacing this file with a README.md, which may contain: @@ -76,8 +81,9 @@ 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/pks#readme for more info!", - pack_name -) + pack_name + ) + } } fn is_rails(configuration: &Configuration) -> bool { diff --git a/src/packs/pack_set.rs b/src/packs/pack_set.rs index 57f62f4..0a24b5d 100644 --- a/src/packs/pack_set.rs +++ b/src/packs/pack_set.rs @@ -108,8 +108,8 @@ impl PackSet { pub fn all_pack_dependencies<'a>( &'a self, configuration: &'a Configuration, - ) -> Result> { - let mut pack_refs: Vec = Vec::new(); + ) -> Result>> { + let mut pack_refs: Vec> = Vec::new(); for from_pack in &configuration.pack_set.packs { for dependency_pack_name in &from_pack.dependencies { match configuration.pack_set.for_pack(dependency_pack_name) { diff --git a/src/packs/parsing/ruby/experimental/parser.rs b/src/packs/parsing/ruby/experimental/parser.rs index 4a22e87..a72d4e6 100644 --- a/src/packs/parsing/ruby/experimental/parser.rs +++ b/src/packs/parsing/ruby/experimental/parser.rs @@ -25,7 +25,7 @@ struct ReferenceCollector<'a> { pub custom_associations: Vec, } -impl<'a> Visitor for ReferenceCollector<'a> { +impl Visitor for ReferenceCollector<'_> { fn on_class(&mut self, node: &nodes::Class) { // We're not collecting definitions, so no need to visit the class definitioname); let namespace_result = fetch_const_name(&node.name); diff --git a/src/packs/parsing/ruby/packwerk/parser.rs b/src/packs/parsing/ruby/packwerk/parser.rs index 7e271d2..01c64f3 100644 --- a/src/packs/parsing/ruby/packwerk/parser.rs +++ b/src/packs/parsing/ruby/packwerk/parser.rs @@ -36,7 +36,7 @@ struct ReferenceCollector<'a> { pub custom_associations: Vec, } -impl<'a> Visitor for ReferenceCollector<'a> { +impl Visitor for ReferenceCollector<'_> { fn on_class(&mut self, node: &nodes::Class) { // We're not collecting definitions, so no need to visit the class definitioname); let namespace_result = fetch_const_name(&node.name); diff --git a/src/packs/raw_configuration.rs b/src/packs/raw_configuration.rs index 5f1b3f2..2bcc14a 100644 --- a/src/packs/raw_configuration.rs +++ b/src/packs/raw_configuration.rs @@ -52,6 +52,10 @@ pub(crate) struct RawConfiguration { #[serde(default)] pub layers: Vec, + // Path to the README template + #[serde(default)] + pub readme_template_path: Option, + // Experimental parser #[serde(default)] pub experimental_parser: bool, diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 448f748..eb09c23 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -31,6 +31,30 @@ pub fn delete_foobar() { } } +#[allow(dead_code)] +pub fn delete_foobaz() { + let directory = + PathBuf::from("tests/fixtures/simple_packs_first_app/packs/foobaz"); + if let Err(err) = fs::remove_dir_all(directory) { + eprintln!( + "Failed to remove tests/fixtures/simple_packs_first_app/packs/foobaz during test teardown: {}", + err + ); + } +} + +#[allow(dead_code)] +pub fn delete_foobar_app_with_custom_readme() { + let directory = + PathBuf::from("tests/fixtures/app_with_custom_readme/packs/foobar"); + if let Err(err) = fs::remove_dir_all(directory) { + eprintln!( + "Failed to remove tests/fixtures/app_with_custom_readme/packs/foobar during test teardown: {}", + err + ); + } +} + // In case we want our tests to call `update` or otherwise mutate the file system #[allow(dead_code)] pub fn set_up_fixtures() { diff --git a/tests/create_test.rs b/tests/create_test.rs index a2f2f71..42c2d94 100644 --- a/tests/create_test.rs +++ b/tests/create_test.rs @@ -66,6 +66,69 @@ See https://github.com/rubyatscale/pks#readme for more info!"); Ok(()) } +#[test] +fn test_create_with_readme_template_default_path() -> Result<(), Box> +{ + common::delete_foobaz(); + + fs::write( + "tests/fixtures/simple_packs_first_app/README_TEMPLATE.md", + "This is a test custom README template", + )?; + + Command::cargo_bin("pks")? + .arg("--project-root") + .arg("tests/fixtures/simple_packs_first_app") + .arg("create") + .arg("packs/foobaz") + .assert() + .success(); + + let expected_readme = String::from("This is a test custom README template"); + let actual_readme = + fs::read_to_string("tests/fixtures/simple_packs_first_app/packs/foobaz/README.md").unwrap_or_else(|e| { + panic!("Could not read file tests/fixtures/simple_packs_first_app/packs/foobaz/README.md: {}", e) + }); + + assert_eq!(expected_readme, actual_readme); + + common::teardown(); + common::delete_foobaz(); + fs::remove_file( + "tests/fixtures/simple_packs_first_app/README_TEMPLATE.md", + )?; + + Ok(()) +} + +#[test] +fn test_create_with_readme_template_custom_path() -> Result<(), Box> +{ + common::delete_foobar_app_with_custom_readme(); + + Command::cargo_bin("pks")? + .arg("--project-root") + .arg("tests/fixtures/app_with_custom_readme") + .arg("create") + .arg("packs/foobar") + .assert() + .success(); + + let expected_readme = String::from("README template\n\nThis is a test\n"); + + let actual_readme = + fs::read_to_string("tests/fixtures/app_with_custom_readme/packs/foobar/README.md").unwrap_or_else(|e| { + panic!("Could not read file tests/fixtures/app_with_custom_readme/packs/foobar/README.md: {}", e) + }); + + assert_eq!(expected_readme, actual_readme); + + common::teardown(); + common::delete_foobar_app_with_custom_readme(); + + Ok(()) +} + #[test] fn test_create_already_exists() -> Result<(), Box> { Command::cargo_bin("pks")? diff --git a/tests/fixtures/app_with_custom_readme/app/services/some_root_class.rb b/tests/fixtures/app_with_custom_readme/app/services/some_root_class.rb new file mode 100644 index 0000000..5bce9a9 --- /dev/null +++ b/tests/fixtures/app_with_custom_readme/app/services/some_root_class.rb @@ -0,0 +1 @@ +class SomeRootClass; end diff --git a/tests/fixtures/app_with_custom_readme/config/packs/README_EXAMPLE.md b/tests/fixtures/app_with_custom_readme/config/packs/README_EXAMPLE.md new file mode 100644 index 0000000..3b98fcb --- /dev/null +++ b/tests/fixtures/app_with_custom_readme/config/packs/README_EXAMPLE.md @@ -0,0 +1,3 @@ +README template + +This is a test diff --git a/tests/fixtures/app_with_custom_readme/package.yml b/tests/fixtures/app_with_custom_readme/package.yml new file mode 100644 index 0000000..e69de29 diff --git a/tests/fixtures/app_with_custom_readme/packs.yml b/tests/fixtures/app_with_custom_readme/packs.yml new file mode 100644 index 0000000..1f08e2a --- /dev/null +++ b/tests/fixtures/app_with_custom_readme/packs.yml @@ -0,0 +1,25 @@ +# See: Setting up the configuration file +# https://github.com/Shopify/packwerk/blob/main/USAGE.md#setting-up-the-configuration-file + +# List of patterns for folder paths to include +# include: +# - "**/*.{rb,rake,erb}" + +# List of patterns for folder paths to exclude +# exclude: +# - "{bin,node_modules,script,tmp,vendor}/**/*" + +# Patterns to find package configuration files +# package_paths: "**/" + +# List of custom associations, if any +# custom_associations: +# - "cache_belongs_to" + +# Whether or not you want the cache enabled (disabled by default) +cache: false + +# Where you want the cache to be stored (default below) +# cache_directory: 'tmp/cache/packwerk' + +readme_template_path: config/packs/README_EXAMPLE.md diff --git a/tests/fixtures/app_with_custom_readme/packs/bar/app/models/concerns/some_concern.rb b/tests/fixtures/app_with_custom_readme/packs/bar/app/models/concerns/some_concern.rb new file mode 100644 index 0000000..f2e00d0 --- /dev/null +++ b/tests/fixtures/app_with_custom_readme/packs/bar/app/models/concerns/some_concern.rb @@ -0,0 +1 @@ +module SomeConcern; end diff --git a/tests/fixtures/app_with_custom_readme/packs/bar/app/services/bar.rb b/tests/fixtures/app_with_custom_readme/packs/bar/app/services/bar.rb new file mode 100644 index 0000000..227e5ab --- /dev/null +++ b/tests/fixtures/app_with_custom_readme/packs/bar/app/services/bar.rb @@ -0,0 +1,3 @@ +module Bar + def bar; end +end diff --git a/tests/fixtures/app_with_custom_readme/packs/bar/package.yml b/tests/fixtures/app_with_custom_readme/packs/bar/package.yml new file mode 100644 index 0000000..a473d63 --- /dev/null +++ b/tests/fixtures/app_with_custom_readme/packs/bar/package.yml @@ -0,0 +1 @@ +enforce_privacy: true diff --git a/tests/fixtures/app_with_custom_readme/packs/baz/app/services/baz.rb b/tests/fixtures/app_with_custom_readme/packs/baz/app/services/baz.rb new file mode 100644 index 0000000..e69de29 diff --git a/tests/fixtures/app_with_custom_readme/packs/baz/package.yml b/tests/fixtures/app_with_custom_readme/packs/baz/package.yml new file mode 100644 index 0000000..e69de29 diff --git a/tests/fixtures/app_with_custom_readme/packs/foo/app/services/foo.rb b/tests/fixtures/app_with_custom_readme/packs/foo/app/services/foo.rb new file mode 100644 index 0000000..c815fb9 --- /dev/null +++ b/tests/fixtures/app_with_custom_readme/packs/foo/app/services/foo.rb @@ -0,0 +1,9 @@ +module Foo + def calls_bar_without_a_stated_dependency + ::Bar + end + + def calls_baz_with_a_stated_dependency + Baz + end +end diff --git a/tests/fixtures/app_with_custom_readme/packs/foo/app/services/foo/bar.rb b/tests/fixtures/app_with_custom_readme/packs/foo/app/services/foo/bar.rb new file mode 100644 index 0000000..2c7d20a --- /dev/null +++ b/tests/fixtures/app_with_custom_readme/packs/foo/app/services/foo/bar.rb @@ -0,0 +1,5 @@ +# This defines ::Foo::Bar, which is different than ::Bar +module Foo + module Bar + end +end diff --git a/tests/fixtures/app_with_custom_readme/packs/foo/app/views/foo.erb b/tests/fixtures/app_with_custom_readme/packs/foo/app/views/foo.erb new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tests/fixtures/app_with_custom_readme/packs/foo/app/views/foo.erb @@ -0,0 +1 @@ + diff --git a/tests/fixtures/app_with_custom_readme/packs/foo/package.yml b/tests/fixtures/app_with_custom_readme/packs/foo/package.yml new file mode 100644 index 0000000..1922c4d --- /dev/null +++ b/tests/fixtures/app_with_custom_readme/packs/foo/package.yml @@ -0,0 +1,4 @@ +enforce_dependencies: true +enforce_privacy: true +dependencies: +- packs/baz