Skip to content
This repository was archived by the owner on Mar 25, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ intl-memoizer = "0.5.1"
sha2 = "0.10"
itertools = "0.10.3"
mime_guess = "2"
semver = "1.0.7"

[dev-dependencies]
fbt-lib = "0.1.17"
Expand Down
5 changes: 5 additions & 0 deletions ftd/fpm.ftd
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
-- record package-data:
caption name:
boolean versioned: false
optional body about:
optional string zip:
optional string language:
Expand Down Expand Up @@ -157,6 +158,10 @@ toc-item list children:



-- toc-item list versions:



-- toc-item list language-toc:


Expand Down
87 changes: 53 additions & 34 deletions src/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,33 +46,39 @@ pub async fn build(
);
}

match (
config.package.translation_of.as_ref(),
config.package.translations.has_elements(),
) {
(Some(_), true) => {
// No package can be both a translation of something and has its own
// translations, when building `config` we ensured this was rejected
unreachable!()
}
(Some(original), false) => {
build_with_original(
config,
original,
file,
base_url,
ignore_failed,
&asset_documents,
)
.await
}
(None, false) => {
build_simple(config, file, base_url, ignore_failed, &asset_documents).await
}
(None, true) => {
build_with_translations(config, file, base_url, ignore_failed, &asset_documents).await
}
}?;
if config.package.versioned {
fpm::version::build_version(config, file, base_url, ignore_failed, &asset_documents)
.await?;
} else {
match (
config.package.translation_of.as_ref(),
config.package.translations.has_elements(),
) {
(Some(_), true) => {
// No package can be both a translation of something and has its own
// translations, when building `config` we ensured this was rejected
unreachable!()
}
(Some(original), false) => {
build_with_original(
config,
original,
file,
base_url,
ignore_failed,
&asset_documents,
)
.await
}
(None, false) => {
build_simple(config, file, base_url, ignore_failed, &asset_documents).await
}
(None, true) => {
build_with_translations(config, file, base_url, ignore_failed, &asset_documents)
.await
}
}?;
}

for dep in dependencies {
let static_files = std::collections::BTreeMap::from_iter(
Expand Down Expand Up @@ -162,6 +168,7 @@ async fn build_with_translations(
base_url,
skip_failed,
asset_documents,
None,
)
.await?;
}
Expand Down Expand Up @@ -316,6 +323,7 @@ async fn process_files(
base_url,
skip_failed,
asset_documents,
None,
)
.await?
}
Expand All @@ -333,6 +341,7 @@ pub(crate) async fn process_file(
base_url: &str,
skip_failed: bool,
asset_documents: &std::collections::HashMap<String, String>,
original_id: Option<String>,
) -> fpm::Result<()> {
use std::io::Write;

Expand Down Expand Up @@ -368,7 +377,7 @@ pub(crate) async fn process_file(
}
}
(fpm::File::Static(main_sa), fpm::File::Static(_)) => {
process_static(main_sa, &config.root, package).await?
process_static(main_sa, &config.root, package, original_id).await?
}
(fpm::File::Code(main_doc), fpm::File::Code(fallback_doc)) => {
process_static(
Expand All @@ -378,6 +387,7 @@ pub(crate) async fn process_file(
},
&config.root,
package,
original_id,
)
.await?;
let resp = process_code(
Expand All @@ -402,7 +412,7 @@ pub(crate) async fn process_file(
}
}
(fpm::File::Image(main_doc), fpm::File::Image(fallback_doc)) => {
process_static(main_doc, &config.root, package).await?;
process_static(main_doc, &config.root, package, original_id).await?;
let resp = process_image(
config,
main_doc,
Expand Down Expand Up @@ -491,7 +501,7 @@ pub(crate) async fn process_file(
}
}
}
fpm::File::Static(sa) => process_static(sa, &config.root, package).await?,
fpm::File::Static(sa) => process_static(sa, &config.root, package, original_id).await?,
fpm::File::Markdown(doc) => {
let resp = process_markdown(
config,
Expand All @@ -515,7 +525,7 @@ pub(crate) async fn process_file(
}
}
fpm::File::Image(main_doc) => {
process_static(main_doc, &config.root, package).await?;
process_static(main_doc, &config.root, package, original_id).await?;
let resp = process_image(
config,
main_doc,
Expand Down Expand Up @@ -546,6 +556,7 @@ pub(crate) async fn process_file(
},
&config.root,
package,
original_id,
)
.await?;
let resp = process_code(
Expand Down Expand Up @@ -1218,28 +1229,36 @@ async fn process_static(
sa: &fpm::Static,
base_path: &camino::Utf8Path,
package: &fpm::Package,
original_id: Option<String>,
) -> fpm::Result<()> {
copy_to_build(sa, base_path, package)?;
copy_to_build(sa, base_path, package, &original_id)?;
if let Some(original_package) = package.translation_of.as_ref() {
copy_to_build(sa, base_path, original_package)?;
copy_to_build(sa, base_path, original_package, &original_id)?;
}
return Ok(());

fn copy_to_build(
sa: &fpm::Static,
base_path: &camino::Utf8Path,
package: &fpm::Package,
original_id: &Option<String>,
) -> fpm::Result<()> {
let build_path = base_path
.join(".build")
.join("-")
.join(package.name.as_str());
let original_id = if let Some(id) = original_id {
id.as_str()
} else {
sa.id.as_str()
};

std::fs::create_dir_all(&build_path)?;
if let Some((dir, _)) = sa.id.rsplit_once(std::path::MAIN_SEPARATOR) {
std::fs::create_dir_all(&build_path.join(dir))?;
}
std::fs::copy(
sa.base_path.join(sa.id.as_str()),
sa.base_path.join(original_id),
build_path.join(sa.id.as_str()),
)?;

Expand Down
83 changes: 79 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,15 +334,87 @@ impl Config {
Ok(())
}

pub(crate) async fn get_files(&self, package: &fpm::Package) -> fpm::Result<Vec<fpm::File>> {
let path = if let Some(package_fpm_path) = &package.fpm_path {
pub(crate) async fn get_versions(
&self,
package: &fpm::Package,
) -> fpm::Result<std::collections::HashMap<fpm::Version, Vec<fpm::File>>> {
let path = self.get_root_for_package(package);
let mut ignore_paths = ignore::WalkBuilder::new(&path);
ignore_paths.overrides(fpm::file::package_ignores(package, &path)?);

let mut hash: std::collections::HashMap<fpm::Version, Vec<fpm::File>> =
std::collections::HashMap::new();

let all_files = ignore_paths
.build()
.into_iter()
.flatten()
.map(|x| camino::Utf8PathBuf::from_path_buf(x.into_path()).unwrap()) //todo: improve error message
.collect::<Vec<camino::Utf8PathBuf>>();

for file in all_files {
if file.is_dir() {
continue;
}
let version = get_version(&file, &path)?;
let file = fpm::get_file(
package.name.to_string(),
&file,
&(if version.original.eq("BASE_VERSION") {
path.to_owned()
} else {
path.join(&version.original)
}),
)
.await?;
if let Some(files) = hash.get_mut(&version) {
files.push(file)
} else {
hash.insert(version, vec![file]);
}
}
return Ok(hash);

fn get_version(
x: &camino::Utf8PathBuf,
path: &camino::Utf8PathBuf,
) -> fpm::Result<fpm::Version> {
let id = match std::fs::canonicalize(x)?.to_str().unwrap().rsplit_once(
if path.as_str().ends_with(std::path::MAIN_SEPARATOR) {
path.as_str().to_string()
} else {
format!("{}{}", path, std::path::MAIN_SEPARATOR)
}
.as_str(),
) {
Some((_, id)) => id.to_string(),
None => {
return Err(fpm::Error::UsageError {
message: format!("{:?} should be a file", x),
});
}
};
if let Some((v, _)) = id.split_once('/') {
fpm::Version::parse(v)
} else {
Ok(fpm::Version::base())
}
}
}

pub(crate) fn get_root_for_package(&self, package: &fpm::Package) -> camino::Utf8PathBuf {
if let Some(package_fpm_path) = &package.fpm_path {
// TODO: Unwrap?
package_fpm_path.parent().unwrap().to_owned()
} else if package.name.eq(&self.package.name) {
self.root.clone()
} else {
self.packages_root.clone().join(package.name.as_str())
};
}
}

pub(crate) async fn get_files(&self, package: &fpm::Package) -> fpm::Result<Vec<fpm::File>> {
let path = self.get_root_for_package(package);
let mut ignore_paths = ignore::WalkBuilder::new(&path);
// ignore_paths.hidden(false); // Allow the linux hidden files to be evaluated
ignore_paths.overrides(fpm::file::package_ignores(package, &path)?);
Expand Down Expand Up @@ -473,6 +545,7 @@ pub(crate) fn find_root_for_file(
#[derive(serde::Deserialize, Debug, Clone)]
pub(crate) struct PackageTemp {
pub name: String,
pub versioned: bool,
#[serde(rename = "translation-of")]
pub translation_of: Option<String>,
#[serde(rename = "translation")]
Expand Down Expand Up @@ -502,6 +575,7 @@ impl PackageTemp {

fpm::Package {
name: self.name,
versioned: self.versioned,
translation_of: Box::new(translation_of),
translations,
language: self.language,
Expand All @@ -522,6 +596,7 @@ impl PackageTemp {
#[derive(Debug, Clone)]
pub struct Package {
pub name: String,
pub versioned: bool,
pub translation_of: Box<Option<Package>>,
pub translations: Vec<Package>,
pub language: Option<String>,
Expand All @@ -541,14 +616,14 @@ pub struct Package {
///
/// Note that this too is kind of bad design, we will move fonts to `fpm::Package` struct soon.
pub fonts: Vec<fpm::Font>,

pub import_auto_imports_from_original: bool,
}

impl Package {
pub fn new(name: &str) -> fpm::Package {
fpm::Package {
name: name.to_string(),
versioned: false,
translation_of: Box::new(None),
translations: vec![],
language: None,
Expand Down
9 changes: 9 additions & 0 deletions src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ impl File {
Self::Image(a) => a.id.clone(),
}
}
pub fn set_id(&mut self, new_id: &str) {
*(match self {
Self::Ftd(a) => &mut a.id,
Self::Static(a) => &mut a.id,
Self::Markdown(a) => &mut a.id,
Self::Code(a) => &mut a.id,
Self::Image(a) => &mut a.id,
}) = new_id.to_string();
}
pub fn get_base_path(&self) -> String {
match self {
Self::Ftd(a) => a.parent_path.to_string(),
Expand Down
Loading