blob: e683d82322b37ddea532cf5dc7b0db7a43f8308a [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![warn(missing_docs)]
// TODO(fxb/87635): Fix this.
// This crate doesn't comply with all 2018 idioms
#![allow(elided_lifetimes_in_paths)]
//! `cmc` is the Component Manifest Compiler.
use anyhow::{ensure, Error};
pub use cml::{self, error, one_or_many, translate, Document};
use reference_doc::MarkdownReferenceDocGenerator;
use std::fs;
use std::path::{Path, PathBuf};
use structopt::StructOpt;
#[allow(unused)] // A test-only macro is defined on all builds.
mod compile;
mod features;
mod format;
mod include;
mod merge;
mod opts;
mod reference;
mod util;
mod validate;
fn main() -> Result<(), Error> {
run_cmc()
}
fn path_exists(path: &Path) -> Result<(), Error> {
ensure!(path.exists(), "{:?} does not exist", path);
Ok(())
}
fn optional_path_exists(optional_path: Option<&PathBuf>) -> Result<(), Error> {
if let Some(path) = optional_path.as_ref() {
ensure!(path.exists(), "{:?} does not exist", path);
}
Ok(())
}
fn run_cmc() -> Result<(), Error> {
let opt = opts::Opt::from_args();
match opt.cmd {
opts::Commands::Validate { files, extra_schemas } => {
validate::validate(&files, &extra_schemas, &features::FeatureSet::empty())?
}
opts::Commands::ValidateReferences { component_manifest, package_manifest, gn_label } => {
reference::validate(&component_manifest, &package_manifest, gn_label.as_ref())?
}
opts::Commands::Merge { files, output, fromfile, depfile } => {
merge::merge(files, output, fromfile, depfile)?
}
opts::Commands::Include { file, output, depfile, includepath, includeroot } => {
path_exists(&file)?;
include::merge_includes(
&file,
output.as_ref(),
depfile.as_ref(),
&includepath,
&includeroot,
)?
}
opts::Commands::CheckIncludes {
file,
expected_includes,
fromfile,
depfile,
includepath,
includeroot,
} => {
path_exists(&file)?;
optional_path_exists(fromfile.as_ref())?;
include::check_includes(
&file,
expected_includes,
fromfile.as_ref(),
depfile.as_ref(),
opt.stamp.as_ref(),
&includepath,
&includeroot,
)?
}
opts::Commands::Format { file, pretty, cml, inplace, mut output } => {
path_exists(&file)?;
if inplace {
output = Some(file.clone());
}
format::format(&file, pretty, cml, output)?;
}
opts::Commands::Compile {
file,
output,
depfile,
includepath,
includeroot,
config_package_path,
features,
experimental_force_runner,
} => {
path_exists(&file)?;
compile::compile(
&file,
&output.unwrap(),
depfile,
&includepath,
&includeroot,
config_package_path.as_ref().map(String::as_str),
&features.into(),
&experimental_force_runner,
)?
}
opts::Commands::PrintReferenceDocs { output } => {
let docs = Document::get_reference_doc_markdown();
match &output {
None => println!("{}", docs),
Some(path) => fs::write(path, docs)?,
}
}
}
if let Some(stamp_path) = opt.stamp {
stamp(stamp_path)?;
}
Ok(())
}
fn stamp(stamp_path: PathBuf) -> Result<(), Error> {
fs::File::create(stamp_path)?;
Ok(())
}