Skip to content

Commit

Permalink
Merge pull request #896 from etehtsea/859-app-dir
Browse files Browse the repository at this point in the history
Introduce spin_loader::local::{absolutize, parent_dir}
  • Loading branch information
itowlson authored Nov 14, 2022
2 parents 1758148 + 33a7213 commit aab59be
Show file tree
Hide file tree
Showing 15 changed files with 56 additions and 87 deletions.
3 changes: 0 additions & 3 deletions Cargo.lock

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

1 change: 0 additions & 1 deletion crates/build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ edition = { workspace = true }
[dependencies]
anyhow = "1.0.57"
futures = "0.3.21"
path-absolutize = "3.0.11"
spin-loader = { path = "../loader" }
subprocess = "0.2.8"
tracing = { version = "0.1", features = [ "log" ] }
26 changes: 12 additions & 14 deletions crates/build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@
//! A library for building Spin components.
use anyhow::{bail, Context, Result};
use path_absolutize::Absolutize;
use spin_loader::local::config::{RawAppManifest, RawComponentManifest};
use spin_loader::local::{
config::{RawAppManifestAnyVersion, RawComponentManifest},
parent_dir, raw_manifest_from_file,
};
use std::path::{Path, PathBuf};
use subprocess::{Exec, Redirection};
use tracing::log;

/// If present, run the build command of each component.
pub async fn build(app: RawAppManifest, src: &Path) -> Result<()> {
let src = src.absolutize()?;
pub async fn build(manifest_file: &Path) -> Result<()> {
let RawAppManifestAnyVersion::V1(app) = raw_manifest_from_file(&manifest_file).await?;
let app_dir = parent_dir(manifest_file)?;

if app.components.iter().all(|c| c.build.is_none()) {
println!("No build command found!");
Expand All @@ -21,7 +24,7 @@ pub async fn build(app: RawAppManifest, src: &Path) -> Result<()> {
let results = futures::future::join_all(
app.components
.into_iter()
.map(|c| build_component(c, &src))
.map(|c| build_component(c, &app_dir))
.collect::<Vec<_>>(),
)
.await;
Expand All @@ -37,14 +40,14 @@ pub async fn build(app: RawAppManifest, src: &Path) -> Result<()> {
}

/// Run the build command of the component.
async fn build_component(raw: RawComponentManifest, src: impl AsRef<Path>) -> Result<()> {
async fn build_component(raw: RawComponentManifest, app_dir: &Path) -> Result<()> {
match raw.build {
Some(b) => {
println!(
"Executing the build command for component {}: {}",
raw.id, b.command
);
let workdir = construct_workdir(src.as_ref(), b.workdir.as_ref())?;
let workdir = construct_workdir(app_dir, b.workdir.as_ref())?;
if b.workdir.is_some() {
println!("Working directory: {:?}", workdir);
}
Expand Down Expand Up @@ -80,12 +83,8 @@ async fn build_component(raw: RawComponentManifest, src: impl AsRef<Path>) -> Re
}

/// Constructs the absolute working directory in which to run the build command.
fn construct_workdir(src: impl AsRef<Path>, workdir: Option<impl AsRef<Path>>) -> Result<PathBuf> {
let mut cwd = src
.as_ref()
.parent()
.context("The application file did not have a parent directory.")?
.to_path_buf();
fn construct_workdir(app_dir: &Path, workdir: Option<impl AsRef<Path>>) -> Result<PathBuf> {
let mut cwd = app_dir.to_owned();

if let Some(workdir) = workdir {
// Using `Path::has_root` as `is_relative` and `is_absolute` have
Expand All @@ -95,7 +94,6 @@ fn construct_workdir(src: impl AsRef<Path>, workdir: Option<impl AsRef<Path>>) -
bail!("The workdir specified in the application file must be relative.");
}
cwd.push(workdir);
cwd = cwd.absolutize()?.to_path_buf();
}

Ok(cwd)
Expand Down
1 change: 0 additions & 1 deletion crates/cloud/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ cloud-openapi = { git = "https://github.com/fermyon/cloud-openapi" }
itertools = "0.10.0"
log = "0.4"
mime_guess = { version = "2.0" }
path-absolutize = "3.0.11"
regex = "1.5"
reqwest = { version = "0.11", features = ["stream"] }
semver = "1.0"
Expand Down
3 changes: 2 additions & 1 deletion crates/loader/src/bindle/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::digest::file_sha256_string;
use crate::{
assets::{create_dir, ensure_under},
bindle::utils::BindleReader,
local::parent_dir,
};

pub(crate) async fn prepare_component(
Expand Down Expand Up @@ -88,7 +89,7 @@ impl Copier {
p.sha256,
to.display()
);
fs::create_dir_all(to.parent().expect("Cannot copy to file '/'")).await?;
fs::create_dir_all(parent_dir(&to).expect("Cannot copy to file '/'")).await?;
let mut stream = self
.reader
.get_parcel_stream(&p.sha256)
Expand Down
7 changes: 5 additions & 2 deletions crates/loader/src/local/assets.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#![deny(missing_docs)]

use crate::assets::{create_dir, ensure_all_under, ensure_under, to_relative};
use crate::{
assets::{create_dir, ensure_all_under, ensure_under, to_relative},
local::parent_dir,
};
use anyhow::{anyhow, bail, ensure, Context, Result};
use futures::{future, stream, StreamExt};
use spin_manifest::DirectoryMount;
Expand Down Expand Up @@ -206,7 +209,7 @@ async fn copy(file: &FileMount, dir: impl AsRef<Path>) -> Result<()> {

tracing::trace!("Copying asset file '{from:?}' -> '{to:?}'");

tokio::fs::create_dir_all(to.parent().context("Cannot copy to file '/'")?).await?;
tokio::fs::create_dir_all(parent_dir(&to).context("Cannot copy to file '/'")?).await?;

let _ = tokio::fs::copy(&from, &to)
.await
Expand Down
33 changes: 24 additions & 9 deletions crates/loader/src/local/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,7 @@ pub async fn from_file(
base_dst: impl AsRef<Path>,
bindle_connection: &Option<BindleConnectionInfo>,
) -> Result<Application> {
let app = app
.as_ref()
.absolutize()
.context("Failed to resolve absolute path to manifest file")?;
let app = absolutize(app)?;
let manifest = raw_manifest_from_file(&app).await?;
validate_raw_app_manifest(&manifest)?;

Expand All @@ -67,6 +64,28 @@ pub async fn raw_manifest_from_file(app: &impl AsRef<Path>) -> Result<RawAppMani
Ok(manifest)
}

/// Returns the absolute path to directory containing the file
pub fn parent_dir(file: impl AsRef<Path>) -> Result<PathBuf> {
let path_buf = file.as_ref().parent().ok_or_else(|| {
anyhow::anyhow!(
"Failed to get containing directory for file '{}'",
file.as_ref().display()
)
})?;

absolutize(path_buf)
}

/// Returns absolute path to the file
pub fn absolutize(path: impl AsRef<Path>) -> Result<PathBuf> {
let path = path.as_ref();

Ok(path
.absolutize()
.with_context(|| format!("Failed to resolve absolute path to: {}", path.display()))?
.to_path_buf())
}

/// Converts a raw application manifest into Spin configuration while handling
/// the Spin manifest and API version.
async fn prepare_any_version(
Expand Down Expand Up @@ -156,11 +175,7 @@ async fn core(
bindle_connection: &Option<BindleConnectionInfo>,
) -> Result<CoreComponent> {
let id = raw.id;

let src = src
.as_ref()
.parent()
.expect("The application file did not have a parent directory.");
let src = parent_dir(src)?;
let source = match raw.source {
config::RawModuleSource::FileReference(p) => {
let p = match p.is_absolute() {
Expand Down
1 change: 0 additions & 1 deletion crates/publish/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ dunce = "1.0"
futures = "0.3.14"
itertools = "0.10.3"
mime_guess = { version = "2.0" }
path-absolutize = "3.0.11"
reqwest = "0.11"
semver = "1.0"
serde = { version = "1.0", features = [ "derive" ] }
Expand Down
3 changes: 2 additions & 1 deletion crates/publish/src/bindle_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use crate::expander::expand_manifest;
use anyhow::{Context, Result};
use bindle::{Invoice, Parcel};
use spin_loader::local::parent_dir;
use std::{
collections::BTreeMap,
path::{Path, PathBuf},
Expand All @@ -24,7 +25,7 @@ pub async fn prepare_bindle(
)
})?;

let source_dir = crate::app_dir(&app_file)?;
let source_dir = parent_dir(&app_file)?;

write(&source_dir, &dest_dir, &invoice, &sources)
.await
Expand Down
10 changes: 3 additions & 7 deletions crates/publish/src/expander.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
use crate::bindle_writer::{self, ParcelSources};
use anyhow::{Context, Result};
use bindle::{BindleSpec, Condition, Group, Invoice, Label, Parcel};
use path_absolutize::Absolutize;
use semver::BuildMetadata;
use spin_loader::{
bindle::config as bindle_schema,
digest::{bytes_sha256_string, file_sha256_string},
local::{config as local_schema, validate_raw_app_manifest, UrlSource},
local::{absolutize, config as local_schema, parent_dir, validate_raw_app_manifest, UrlSource},
};
use std::path::{Path, PathBuf};

Expand All @@ -18,14 +17,11 @@ pub(crate) async fn expand_manifest(
buildinfo: Option<BuildMetadata>,
scratch_dir: impl AsRef<Path>,
) -> Result<(Invoice, ParcelSources)> {
let app_file = app_file
.as_ref()
.absolutize()
.context("Failed to resolve absolute path to manifest file")?;
let app_file = absolutize(app_file)?;
let manifest = spin_loader::local::raw_manifest_from_file(&app_file).await?;
validate_raw_app_manifest(&manifest)?;
let local_schema::RawAppManifestAnyVersion::V1(manifest) = manifest;
let app_dir = crate::app_dir(&app_file)?;
let app_dir = parent_dir(&app_file)?;

// * create a new spin.toml-like document where
// - each component changes its `files` entry to a group name
Expand Down
17 changes: 0 additions & 17 deletions crates/publish/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,3 @@ mod expander;

pub use bindle_pusher::push_all;
pub use bindle_writer::prepare_bindle;

use anyhow::Result;
use std::path::{Path, PathBuf};

pub(crate) fn app_dir(app_file: impl AsRef<Path>) -> Result<PathBuf> {
let path_buf = app_file
.as_ref()
.parent()
.ok_or_else(|| {
anyhow::anyhow!(
"Failed to get containing directory for app file '{}'",
app_file.as_ref().display()
)
})?
.to_owned();
Ok(path_buf)
}
5 changes: 1 addition & 4 deletions src/commands/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ use std::{ffi::OsString, path::PathBuf};
use anyhow::Result;
use clap::Parser;

use spin_loader::local::{config::RawAppManifestAnyVersion, raw_manifest_from_file};

use crate::opts::{APP_CONFIG_FILE_OPT, BUILD_UP_OPT, DEFAULT_MANIFEST_FILE};

use super::up::UpCommand;
Expand Down Expand Up @@ -35,9 +33,8 @@ impl BuildCommand {
.app
.as_deref()
.unwrap_or_else(|| DEFAULT_MANIFEST_FILE.as_ref());
let RawAppManifestAnyVersion::V1(app) = raw_manifest_from_file(&manifest_file).await?;

spin_build::build(app, manifest_file).await?;
spin_build::build(manifest_file).await?;

if self.up {
let mut cmd = UpCommand::parse_from(
Expand Down
4 changes: 2 additions & 2 deletions src/commands/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use spin_http::routes::RoutePattern;
use spin_http::WELL_KNOWN_HEALTH_PATH;
use spin_loader::bindle::BindleConnectionInfo;
use spin_loader::local::config::{RawAppManifest, RawAppManifestAnyVersion};
use spin_loader::local::{assets, config};
use spin_loader::local::{assets, config, parent_dir};
use spin_manifest::ApplicationTrigger;
use spin_manifest::{HttpTriggerConfiguration, TriggerConfig};
use tokio::fs;
Expand Down Expand Up @@ -425,7 +425,7 @@ impl DeployCommand {

async fn compute_buildinfo(&self, cfg: &RawAppManifest) -> Result<BuildMetadata> {
let mut sha256 = Sha256::new();
let app_folder = crate::app_dir(&self.app)?;
let app_folder = parent_dir(&self.app)?;

for x in cfg.components.iter() {
match &x.source {
Expand Down
11 changes: 4 additions & 7 deletions src/commands/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use std::{

use anyhow::{anyhow, Context, Result};
use clap::Parser;
use path_absolutize::Absolutize;
use tokio::{fs::File, io::AsyncReadExt};

use spin_loader::local::absolutize;
use spin_templates::{RunOptions, Template, TemplateManager};

/// Scaffold a new application or component based on a template.
Expand Down Expand Up @@ -111,17 +111,14 @@ impl FromStr for ParameterValue {
}

async fn values_from_file(file: impl AsRef<Path>) -> Result<HashMap<String, String>> {
let file = file
.as_ref()
.absolutize()
.context("Failed to resolve absolute path to values file")?;
let file = absolutize(file)?;

let mut buf = vec![];
File::open(file.as_ref())
File::open(&file)
.await?
.read_to_end(&mut buf)
.await
.with_context(|| anyhow!("Cannot read values file from {:?}", file.as_ref()))?;
.with_context(|| anyhow!("Cannot read values file from {:?}", file))?;

toml::from_slice(&buf).context("Failed to deserialize values file")
}
Expand Down
18 changes: 1 addition & 17 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,9 @@ pub mod commands;
pub(crate) mod opts;
mod sloth;

use std::path::{Path, PathBuf};

use anyhow::{anyhow, Result};
use anyhow::Result;
use semver::BuildMetadata;

pub(crate) fn app_dir(app_file: impl AsRef<Path>) -> Result<PathBuf> {
let path_buf = app_file
.as_ref()
.parent()
.ok_or_else(|| {
anyhow!(
"Failed to get containing directory for app file '{}'",
app_file.as_ref().display()
)
})?
.to_owned();
Ok(path_buf)
}

pub(crate) fn parse_buildinfo(buildinfo: &str) -> Result<BuildMetadata> {
Ok(BuildMetadata::new(buildinfo)?)
}

0 comments on commit aab59be

Please sign in to comment.