#![allow(clippy::derivable_impls)]
pub mod layer;
pub mod artifacts;
pub mod builds;
pub mod ci;
pub mod hosts;
pub mod installers;
pub mod publishers;
use axoproject::{PackageIdx, WorkspaceGraph};
use semver::Version;
use v0::CargoDistUrlOverride;
use super::*;
use layer::*;
use artifacts::*;
use builds::*;
use ci::*;
use hosts::*;
use installers::*;
use publishers::*;
pub fn workspace_config(
workspaces: &WorkspaceGraph,
mut global_config: TomlLayer,
) -> WorkspaceConfig {
global_config.make_relative_to(&workspaces.root_workspace().workspace_dir);
let mut config = WorkspaceConfigInheritable::defaults_for_workspace(workspaces);
config.apply_layer(global_config);
config.apply_inheritance_for_workspace(workspaces)
}
pub fn app_config(
workspaces: &WorkspaceGraph,
pkg_idx: PackageIdx,
mut global_config: TomlLayer,
mut local_config: TomlLayer,
) -> AppConfig {
let package = workspaces.package(pkg_idx);
global_config.make_relative_to(&workspaces.root_workspace().workspace_dir);
local_config.make_relative_to(&package.package_root);
let mut config = AppConfigInheritable::defaults_for_package(workspaces, pkg_idx);
config.apply_layer(global_config);
config.apply_layer(local_config);
config.apply_inheritance_for_package(workspaces, pkg_idx)
}
#[derive(Debug, Clone)]
pub struct WorkspaceConfig {
pub dist_version: Option<Version>,
pub dist_url_override: Option<CargoDistUrlOverride>,
pub allow_dirty: Vec<GenerateMode>,
pub ci: CiConfig,
pub artifacts: WorkspaceArtifactConfig,
pub hosts: WorkspaceHostConfig,
pub builds: WorkspaceBuildConfig,
pub installers: WorkspaceInstallerConfig,
}
#[derive(Debug, Clone)]
pub struct WorkspaceConfigInheritable {
pub dist_version: Option<Version>,
pub dist_url_override: Option<CargoDistUrlOverride>,
pub allow_dirty: Vec<GenerateMode>,
pub artifacts: WorkspaceArtifactConfig,
pub ci: CiConfigInheritable,
pub hosts: HostConfigInheritable,
pub builds: BuildConfigInheritable,
pub installers: InstallerConfigInheritable,
}
impl WorkspaceConfigInheritable {
pub fn defaults_for_workspace(workspaces: &WorkspaceGraph) -> Self {
Self {
artifacts: WorkspaceArtifactConfig::defaults_for_workspace(workspaces),
ci: CiConfigInheritable::defaults_for_workspace(workspaces),
hosts: HostConfigInheritable::defaults_for_workspace(workspaces),
builds: BuildConfigInheritable::defaults_for_workspace(workspaces),
installers: InstallerConfigInheritable::defaults_for_workspace(workspaces),
dist_version: None,
dist_url_override: None,
allow_dirty: vec![],
}
}
pub fn apply_inheritance_for_workspace(self, workspaces: &WorkspaceGraph) -> WorkspaceConfig {
let Self {
artifacts,
ci,
hosts,
builds,
installers,
dist_version,
dist_url_override,
allow_dirty,
} = self;
WorkspaceConfig {
artifacts,
ci: ci.apply_inheritance_for_workspace(workspaces),
hosts: hosts.apply_inheritance_for_workspace(workspaces),
builds: builds.apply_inheritance_for_workspace(workspaces),
installers: installers.apply_inheritance_for_workspace(workspaces),
dist_version,
dist_url_override,
allow_dirty,
}
}
}
impl ApplyLayer for WorkspaceConfigInheritable {
type Layer = TomlLayer;
fn apply_layer(
&mut self,
Self::Layer {
artifacts,
builds,
hosts,
installers,
ci,
allow_dirty,
dist_version,
dist_url_override,
dist: _,
targets: _,
publishers: _,
}: Self::Layer,
) {
self.artifacts.apply_val_layer(artifacts);
self.builds.apply_val_layer(builds);
self.hosts.apply_val_layer(hosts);
self.installers.apply_val_layer(installers);
self.ci.apply_val_layer(ci);
self.dist_version.apply_opt(dist_version);
self.dist_url_override.apply_opt(dist_url_override);
self.allow_dirty.apply_val(allow_dirty);
}
}
#[derive(Debug, Clone)]
pub struct AppConfig {
pub artifacts: AppArtifactConfig,
pub builds: AppBuildConfig,
pub hosts: AppHostConfig,
pub installers: AppInstallerConfig,
pub publishers: PublisherConfig,
pub dist: Option<bool>,
pub targets: Vec<TripleName>,
}
#[derive(Debug, Clone)]
pub struct AppConfigInheritable {
pub artifacts: AppArtifactConfig,
pub builds: BuildConfigInheritable,
pub hosts: HostConfigInheritable,
pub installers: InstallerConfigInheritable,
pub publishers: PublisherConfigInheritable,
pub dist: Option<bool>,
pub targets: Vec<TripleName>,
}
impl AppConfigInheritable {
pub fn defaults_for_package(workspaces: &WorkspaceGraph, pkg_idx: PackageIdx) -> Self {
Self {
artifacts: AppArtifactConfig::defaults_for_package(workspaces, pkg_idx),
builds: BuildConfigInheritable::defaults_for_package(workspaces, pkg_idx),
hosts: HostConfigInheritable::defaults_for_package(workspaces, pkg_idx),
installers: InstallerConfigInheritable::defaults_for_package(workspaces, pkg_idx),
publishers: PublisherConfigInheritable::defaults_for_package(workspaces, pkg_idx),
dist: None,
targets: vec![],
}
}
pub fn apply_inheritance_for_package(
self,
workspaces: &WorkspaceGraph,
pkg_idx: PackageIdx,
) -> AppConfig {
let Self {
artifacts,
builds,
hosts,
installers,
publishers,
dist: do_dist,
targets,
} = self;
AppConfig {
artifacts,
builds: builds.apply_inheritance_for_package(workspaces, pkg_idx),
hosts: hosts.apply_inheritance_for_package(workspaces, pkg_idx),
installers: installers.apply_inheritance_for_package(workspaces, pkg_idx),
publishers: publishers.apply_inheritance_for_package(workspaces, pkg_idx),
dist: do_dist,
targets,
}
}
}
impl ApplyLayer for AppConfigInheritable {
type Layer = TomlLayer;
fn apply_layer(
&mut self,
Self::Layer {
artifacts,
builds,
hosts,
installers,
publishers,
dist,
targets,
ci: _,
allow_dirty: _,
dist_version: _,
dist_url_override: _,
}: Self::Layer,
) {
self.artifacts.apply_val_layer(artifacts);
self.builds.apply_val_layer(builds);
self.hosts.apply_val_layer(hosts);
self.installers.apply_val_layer(installers);
self.publishers.apply_val_layer(publishers);
self.dist.apply_opt(dist);
self.targets.apply_val(targets);
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct TomlLayer {
#[serde(skip_serializing_if = "Option::is_none")]
pub dist_version: Option<Version>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dist_url_override: Option<CargoDistUrlOverride>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dist: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub allow_dirty: Option<Vec<GenerateMode>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub targets: Option<Vec<TripleName>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub artifacts: Option<ArtifactLayer>,
#[serde(skip_serializing_if = "Option::is_none")]
pub builds: Option<BuildLayer>,
#[serde(skip_serializing_if = "Option::is_none")]
pub ci: Option<CiLayer>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hosts: Option<HostLayer>,
#[serde(skip_serializing_if = "Option::is_none")]
pub installers: Option<InstallerLayer>,
#[serde(skip_serializing_if = "Option::is_none")]
pub publishers: Option<PublisherLayer>,
}
impl TomlLayer {
fn make_relative_to(&mut self, base_path: &Utf8Path) {
if let Some(artifacts) = &mut self.artifacts {
if let Some(archives) = &mut artifacts.archives {
if let Some(include) = &mut archives.include {
for path in include {
make_path_relative_to(path, base_path);
}
}
}
if let Some(extras) = &mut artifacts.extra {
for extra in extras {
make_path_relative_to(&mut extra.working_dir, base_path);
}
}
}
if let Some(hosts) = &mut self.hosts {
if let Some(BoolOr::Val(github)) = &mut hosts.github {
if let Some(path) = &mut github.submodule_path {
make_path_relative_to(path, base_path);
}
}
}
}
}
fn make_path_relative_to(path: &mut Utf8PathBuf, base_path: &Utf8Path) {
if !path.is_absolute() {
*path = base_path.join(&path);
}
}