Repository: cargo-generate/cargo-generate (rust)

Issue:
auto remove `.liquid` file extensions if present
For non-trivial templates I'm finding my eyes bleed trying to sort out false syntax errors from true syntax errors.  

Adding `.liquid` to files where templates are used helps. It also has the advantage of signalling files that contain template content and those that don't.

It'd be helpful to have a clear statement that cargo-generate will remove the `.liquid` extension when a file is rendered. 

If it won't remove `.liquid` extension, knowing that will also help.

Pull request:
auto remove `.liquid` file extensions if present
Fixes #608

Patch:
diff --git a/guide/src/README.md b/guide/src/README.md
index 918346a..5ddbf65 100644
--- a/guide/src/README.md
+++ b/guide/src/README.md
@@ -9,10 +9,18 @@
 `cargo-generate` is a developer tool to help you get up and running quickly with a new Rust
 project by leveraging a pre-existing git repository as a template.
 
-cargo-generate uses [Shopify's Liquid](http://liquidmarkup.org/) template language,
+cargo-generate uses [Shopify's Liquid] template language,
 [Rhai](https://docs.rs/rhai/latest/rhai/) for hook scripts and [regex](https://docs.rs/regex/latest/regex/) for placeholders.
 
+Due to the use of [Shopify's Liquid], `cargo-generate` special cases files with the file-ending
+`.liquid`, by simply removing the file-ending when processing the files. If you, as a template 
+author, truly wants the `.liquid` file-ending, you need to repeat it twice!
+
+An Example: the file `main.rs.liquid` will be renamed after templating to `main.rs`
+
 Here's an example of using `cargo-generate` with [this template]:
+
 ![demo.gif](./demo.gif)
 
 [this template]: https://github.com/ashleygwilliams/wasm-pack-template
+[Shopify's Liquid]: http://liquidmarkup.org/
\ No newline at end of file
diff --git a/src/lib.rs b/src/lib.rs
index deb7e50..4b483fc 100755
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -281,12 +281,15 @@ pub(crate) fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> Resu
 
         for src_entry in fs::read_dir(src)? {
             let src_entry = src_entry?;
-            let dst_path = dst.as_ref().join(src_entry.file_name());
+            let filename = src_entry.file_name().to_string_lossy().to_string();
             let entry_type = src_entry.file_type()?;
 
             if entry_type.is_dir() {
+                let dst_path = dst.as_ref().join(filename);
                 check_dir_all(src_entry.path(), dst_path)?;
             } else if entry_type.is_file() {
+                let filename = filename.strip_suffix(".liquid").unwrap_or(&filename);
+                let dst_path = dst.as_ref().join(filename);
                 if dst_path.exists() {
                     bail!(
                         "{} {} {}",
@@ -310,14 +313,17 @@ pub(crate) fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> Resu
         let git_file_name: OsString = ".git".into();
         for src_entry in fs::read_dir(src)? {
             let src_entry = src_entry?;
-            let dst_path = dst.as_ref().join(src_entry.file_name());
+            let filename = src_entry.file_name().to_string_lossy().to_string();
             let entry_type = src_entry.file_type()?;
             if entry_type.is_dir() {
+                let dst_path = dst.as_ref().join(filename);
                 if git_file_name == src_entry.file_name() {
                     continue;
                 }
                 copy_dir_all(src_entry.path(), dst_path)?;
             } else if entry_type.is_file() {
+                let filename = filename.strip_suffix(".liquid").unwrap_or(&filename);
+                let dst_path = dst.as_ref().join(filename);
                 fs::copy(src_entry.path(), dst_path)?;
             }
         }


Test patch:
diff --git a/tests/integration/filenames.rs b/tests/integration/filenames.rs
index bca56fa..6150ff9 100644
--- a/tests/integration/filenames.rs
+++ b/tests/integration/filenames.rs
@@ -13,7 +13,7 @@ fn it_substitutes_filename() {
             r#"println!("Welcome in {{project-name}}");"#,
         )
         .file(
-            "src/{{project-name}}/lib.rs",
+            "src/{{project-name}}/lib.rs.liquid",
             r#"println!("Welcome in {{project-name}}-lib");"#,
         )
         .init_git()
@@ -46,6 +46,6 @@ fn it_substitutes_filename() {
     );
     assert!(
         !dir.exists("foobar-project/src/{{project-name}}/lib.rs"),
-        "project should not contain foobar-project/src/foobar-project/lib.rs"
+        "project should not contain foobar-project/src/foobar-project/lib.rs.liquid"
     );
 }