Skip to content

Commit

Permalink
Merge pull request #1344 from MartinKavik/model_new
Browse files Browse the repository at this point in the history
Command to create a new model
  • Loading branch information
hannobraun authored Nov 14, 2022
2 parents 517cbcc + e048222 commit 8f0c062
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 1 deletion.
52 changes: 52 additions & 0 deletions Cargo.lock

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

11 changes: 11 additions & 0 deletions crates/fj-app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ license.workspace = true
keywords.workspace = true
categories.workspace = true

[build-dependencies.ignore]
version = "0.4.18"
default-features = false

[build-dependencies.tar]
version = "0.4.35"
default-features = false

[dependencies]
anyhow = "1.0.66"
Expand Down Expand Up @@ -38,3 +45,7 @@ features = ["derive"]
[dependencies.tracing-subscriber]
version = "0.3.16"
features = ["env-filter", "fmt"]

[dependencies.tar]
version = "0.4.35"
default-features = false
43 changes: 43 additions & 0 deletions crates/fj-app/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use ignore::WalkBuilder;
use std::{collections::HashSet, env, ffi::OsStr, fs::File, path::Path};

static NEW_MODEL_TEMPLATE: &str = "star";
static EXTRA_IGNORED_FILES: &[&str] = &["star.png", "README.md"];

fn main() {
create_new_model_tar();
}

fn create_new_model_tar() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let file = File::create(Path::new(&out_dir).join("new_model.tar")).unwrap();
let mut tar_builder = tar::Builder::new(file);

let manifest_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap();
let fornjot_root_path = Path::new(&manifest_dir)
.ancestors()
.nth(2)
.expect("Failed to get 'fornjot_root_path' path");

let new_model_path =
fornjot_root_path.join("models").join(NEW_MODEL_TEMPLATE);

let extra_ignored_files = EXTRA_IGNORED_FILES
.iter()
.map(OsStr::new)
.collect::<HashSet<_>>();

for entry in WalkBuilder::new(&new_model_path).hidden(false).build() {
let path = entry.unwrap().into_path();
if path.is_dir()
|| extra_ignored_files.contains(&path.file_name().unwrap())
{
continue;
}
let tar_path = path.strip_prefix(&new_model_path).unwrap();
tar_builder
.append_file(tar_path, &mut File::open(&path).unwrap())
.unwrap();
}
tar_builder.finish().unwrap();
}
6 changes: 5 additions & 1 deletion crates/fj-app/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ pub struct Args {
/// The model to open
pub model: Option<PathBuf>,

/// Create a new model with this name
#[arg(short, long, value_name = "MODEL_NAME")]
pub new: Option<String>,

/// Export model to this path
#[arg(short, long)]
#[arg(short, long, value_name = "PATH")]
pub export: Option<PathBuf>,

/// Parameters for the model, each in the form `key=value`
Expand Down
5 changes: 5 additions & 0 deletions crates/fj-app/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
mod args;
mod config;
mod model_crate;
mod path;

use anyhow::{anyhow, Context};
Expand Down Expand Up @@ -49,6 +50,10 @@ fn main() -> anyhow::Result<()> {
tolerance: args.tolerance,
};

if let Some(model_name) = args.new {
return model_crate::create(&model_name);
}

let model = model_path.map(|m| m.load_model(parameters)).transpose()?;

if let Some(export_path) = args.export {
Expand Down
48 changes: 48 additions & 0 deletions crates/fj-app/src/model_crate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use std::{fs, path::Path};
use tar::Archive;

static NEW_MODEL_TEMPLATE: &str = "star";

static NEW_MODEL_TAR: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/new_model.tar"));

pub fn create(model_name: &str) -> anyhow::Result<()> {
let path = Path::new(model_name);
Archive::new(NEW_MODEL_TAR).unpack(path)?;
postprocess_model_files(path, model_name)?;
println!("Model '{model_name}' created");
Ok(())
}

fn postprocess_model_files(
path: &Path,
model_name: &str,
) -> anyhow::Result<()> {
replace_in_file(
&path.join("Cargo.toml"),
[
(
format!("name = \"{NEW_MODEL_TEMPLATE}\""),
format!("name = \"{model_name}\""),
),
(
r#"path = "../../crates/fj""#.to_owned(),
["version = \"", fj::version::VERSION_PKG, "\""].concat(),
),
],
)?;
fs::write(path.join("README.md"), format!("# {model_name}\n"))?;
Ok(())
}

fn replace_in_file(
path: &Path,
replacements: impl IntoIterator<Item = (String, String)>,
) -> anyhow::Result<()> {
let mut content = fs::read_to_string(path)?;
for (from, to) in replacements {
content = content.replace(&from, &to);
}
fs::write(path, content)?;
Ok(())
}

0 comments on commit 8f0c062

Please sign in to comment.