Skip to content

Commit

Permalink
fix: Support binary/asset files in codegen templates. (#1036)
Browse files Browse the repository at this point in the history
* Load assets.

* Add asset files.

* Fix raw templates.

* Add tests.

* Update changelog.

* Bump version.

* Bump

* Fix moon upgrade.

* Fix changelog.
  • Loading branch information
milesj authored Sep 4, 2023
1 parent 6afdac1 commit a6a9ca5
Show file tree
Hide file tree
Showing 15 changed files with 118 additions and 11 deletions.
9 changes: 9 additions & 0 deletions .yarn/versions/d4354572.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
releases:
"@moonrepo/cli": patch
"@moonrepo/core-linux-arm64-gnu": patch
"@moonrepo/core-linux-arm64-musl": patch
"@moonrepo/core-linux-x64-gnu": patch
"@moonrepo/core-linux-x64-musl": patch
"@moonrepo/core-macos-arm64": patch
"@moonrepo/core-macos-x64": patch
"@moonrepo/core-windows-x64-msvc": patch
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/cli/src/systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use tracing::debug;
#[system]
pub async fn load_workspace(cli: StateRef<CLI>, resources: ResourcesMut) {
match &cli.command {
Commands::Completions(_) | Commands::Init(_) | Commands::Setup => {
Commands::Completions(_) | Commands::Init(_) | Commands::Setup | Commands::Upgrade => {
// Do nothing
}
Commands::Bin(_) | Commands::Docker { .. } | Commands::Node { .. } | Commands::Teardown => {
Expand Down
1 change: 1 addition & 0 deletions crates/cli/tests/generate_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ fn generates_files_from_template() {
assert!(sandbox.path().join("test").exists());
assert!(sandbox.path().join("test/file.ts").exists());
assert!(sandbox.path().join("test/folder/nested-file.ts").exists());
assert!(sandbox.path().join("test/image.jpg").exists());
assert!(!sandbox.path().join("test/template.yml").exists());
}

Expand Down
1 change: 1 addition & 0 deletions nextgen/codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ repository = "https://github.com/moonrepo/moon"
[dependencies]
moon_common = { version = "0.1.0", path = "../common" }
moon_config = { version = "0.1.0", path = "../config" }
content_inspector = "0.2.4"
convert_case = "0.6.0"
miette = { workspace = true }
once_cell = { workspace = true }
Expand Down
17 changes: 17 additions & 0 deletions nextgen/codegen/src/asset_file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use moon_common::path::RelativePathBuf;
use std::path::PathBuf;

#[derive(Debug, Eq, PartialEq)]
pub struct AssetFile {
/// Binary content.
pub content: Vec<u8>,

/// Absolute path to destination.
pub dest_path: PathBuf,

/// Relative path from templates dir. Also acts as the Tera engine name.
pub name: RelativePathBuf,

/// Absolute path to source (in templates dir).
pub source_path: PathBuf,
}
4 changes: 4 additions & 0 deletions nextgen/codegen/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ impl<'app> CodeGenerator<'app> {
}
}

for asset in &template.assets {
template.copy_asset(asset)?;
}

debug!(template = template.id.as_str(), "Code generation complete!");

Ok(())
Expand Down
2 changes: 2 additions & 0 deletions nextgen/codegen/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
mod asset_file;
mod codegen;
mod codegen_error;
mod filters;
mod template;
mod template_file;

pub use asset_file::*;
pub use codegen::*;
pub use codegen_error::*;
pub use template::*;
Expand Down
64 changes: 54 additions & 10 deletions nextgen/codegen/src/template.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::asset_file::AssetFile;
use crate::template_file::{FileState, TemplateFile};
use crate::{filters, CodegenError};
use moon_common::consts::CONFIG_TEMPLATE_FILENAME;
Expand All @@ -15,6 +16,7 @@ static PATH_VAR: Lazy<Regex> = Lazy::new(|| Regex::new(r"\[([A-Za-z0-9_]+)\]").u

#[derive(Debug)]
pub struct Template {
pub assets: Vec<AssetFile>,
pub config: TemplateConfig,
pub engine: Tera,
pub files: Vec<TemplateFile>,
Expand All @@ -39,6 +41,7 @@ impl Template {
engine.register_filter("path_relative", filters::path_relative);

Ok(Template {
assets: vec![],
config: TemplateConfig::load_from(&root)?,
engine,
files: vec![],
Expand All @@ -65,11 +68,33 @@ impl Template {
}

let source_path = entry.path();
let source_content = fs::read_file_bytes(&source_path)?;
let name =
self.interpolate_path(source_path.strip_prefix(&self.root).unwrap(), context)?;

// Images, etc
if content_inspector::inspect(&source_content).is_binary() {
debug!(
template = self.id.as_str(),
file = name.as_str(),
source = ?source_path,
"Loading asset file",
);

self.assets.push(AssetFile {
content: source_content,
dest_path: name.to_logical_path(dest),
name,
source_path,
});

continue;
}

let content = unsafe { String::from_utf8_unchecked(source_content) };

self.engine
.add_template_file(&source_path, Some(name.as_str()))
.add_raw_template(name.as_str(), &content)
.map_err(|error| CodegenError::LoadTemplateFileFailed {
path: source_path.clone(),
error,
Expand All @@ -94,24 +119,30 @@ impl Template {
"Loading template file",
);

files.push(TemplateFile::new(name, source_path));
let mut file = TemplateFile::new(name, source_path);

if file.raw {
file.content = content;
}

files.push(file);
}

// Do a second pass and render the content
for file in &mut files {
file.set_content(
if file.raw {
fs::read_file(&file.source_path)?
} else {
if file.raw {
file.set_raw_content(dest)?;
} else {
file.set_content(
self.engine
.render(file.name.as_str(), context)
.map_err(|error| CodegenError::RenderTemplateFileFailed {
path: file.source_path.clone(),
error,
})?
},
dest,
)?;
})?,
dest,
)?;
}
}

// Sort so files are deterministic
Expand Down Expand Up @@ -167,6 +198,19 @@ impl Template {
Ok(RelativePathBuf::from(path))
}

/// Copy the asset file to the defined destination path.
pub fn copy_asset(&self, file: &AssetFile) -> miette::Result<()> {
debug!(
file = file.name.as_str(),
to = ?file.dest_path,
"Copying asset file",
);

fs::write_file(&file.dest_path, &file.content)?;

Ok(())
}

/// Write the template file to the defined destination path.
pub fn write_file(&self, file: &TemplateFile) -> miette::Result<()> {
match file.state {
Expand Down
7 changes: 7 additions & 0 deletions nextgen/codegen/src/template_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@ impl TemplateFile {
Ok(())
}

pub fn set_raw_content(&mut self, dest: &Path) -> miette::Result<()> {
// Content already loaded during first pass, so re-use
let content = std::mem::take(&mut self.content);

self.set_content(content, dest)
}

pub fn should_write(&self) -> bool {
!matches!(self.state, FileState::Skip)
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions nextgen/codegen/tests/template_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ mod template {
fixture.join("folder/nested-file.ts")
]
);

assert_eq!(
template
.assets
.into_iter()
.map(|f| f.source_path)
.collect::<Vec<_>>(),
vec![fixture.join("image.jpg")]
);
}

#[test]
Expand Down
7 changes: 7 additions & 0 deletions packages/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## Unreleased

#### 🐞 Fixes

- Fixed an issue with asset/binary files not working correctly with codegen templates.
- Fixed an issue where `moon upgrade` would require a workspace.

## 1.13.0

#### 🚀 Updates
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions website/docs/guides/codegen.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ export function {{ component_name }}() {
}
```

#### Assets

Assets are binary files that are copied as-is to the destination, without any rendering, and no
support for frontmatter. This applies to all non-text based files, like images, audio, video, etc.

### Template engine & syntax

Rendering templates is powered by [Tera](https://keats.github.io/tera/), a Rust based template
Expand Down

0 comments on commit a6a9ca5

Please sign in to comment.