Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ Build system for the Lingua Franca coordination language
Usage: lingo [OPTIONS] <COMMAND>

Commands:
init Initialize a Lingua Franca package
build Compile one or multiple binaries in a Lingua Franca package
update Update the dependencies and potentially build tools
run Build and run binaries
clean Remove build artifacts
help Print this message or the help of the given subcommand(s)
init Initialize a Lingua Franca package
build Compile one or multiple binaries in a Lingua Franca package
update Update the dependencies and potentially build tools
run Build and run binaries
clean Remove build artifacts
cleanall Remove build artifacts, dependencies, and lfc build artifacts
help Print this message or the help of the given subcommand(s)

Options:
-q, --quiet Do not produce any output
Expand Down
3 changes: 3 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ pub enum Command {

/// removes build artifacts
Clean,

/// removes build artifacts, installed dependencies, lock file, and lfc build artifacts
Cleanall,
Comment thread
edwardalee marked this conversation as resolved.
Outdated
}

#[derive(Parser)]
Expand Down
12 changes: 12 additions & 0 deletions src/backends/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@

match command {
CommandSpec::Build(_build) => {
println!(
"{} starting dependency resolution ({} declared dependencies)",
"Build step:".to_string(),

Check warning on line 36 in src/backends/mod.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

`to_string` applied to a type that implements `Display` in `println!` args

warning: `to_string` applied to a type that implements `Display` in `println!` args --> src/backends/mod.rs:36:30 | 36 | "Build step:".to_string(), | ^^^^^^^^^^^^ help: remove this | = help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.95.0/index.html#to_string_in_format_args = note: `#[warn(clippy::to_string_in_format_args)]` on by default
dependencies.len()
);
Comment thread
edwardalee marked this conversation as resolved.
Outdated
let manager = match DependencyManager::from_dependencies(
dependencies.clone(),
&PathBuf::from(OUTPUT_DIRECTORY),
Expand All @@ -44,6 +49,7 @@
};

// enriching the apps with the target properties from the libraries
println!("Build step: merging dependency target properties");
let library_properties = manager.get_target_properties().expect("lib properties");

// merging app with library target properties
Expand All @@ -67,6 +73,12 @@
}

for (build_system, apps) in by_build_system {
println!(
"Build step: dispatching {} app(s) to {:?}/{:?}",
apps.len(),
build_system.0,
build_system.1
);
let mut sub_res = BatchBuildResults::for_apps(&apps);

sub_res.map(|app| {
Expand Down
34 changes: 32 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use liblingo::args::TargetLanguage;
use std::io::ErrorKind;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::{env, io};
use std::{env, fs, io};

use clap::Parser;
use git2::BranchType::{Local, Remote};
Expand Down Expand Up @@ -91,6 +91,27 @@ fn do_read_to_string(p: &Path) -> io::Result<String> {
std::fs::read_to_string(p)
}

fn remove_if_exists(path: &Path) -> io::Result<()> {
if path.is_dir() {
println!("Deleted {}", path.display());
fs::remove_dir_all(path)?;
} else if path.is_file() {
println!("Deleted {}", path.display());
fs::remove_file(path)?;
Comment thread
edwardalee marked this conversation as resolved.
Outdated
}
Ok(())
}

fn clean_all(project_root: &Path) -> BuildResult {
remove_if_exists(&project_root.join("build"))?;
remove_if_exists(&project_root.join("Lingo.lock"))?;
remove_if_exists(&project_root.join("src-gen"))?;
remove_if_exists(&project_root.join("bin"))?;
remove_if_exists(&project_root.join("fed-gen"))?;
remove_if_exists(&project_root.join("include"))?;
Comment thread
edwardalee marked this conversation as resolved.
Outdated
Ok(())
}

fn main() {
print_logger::new().init().unwrap();
// parses command line arguments
Expand Down Expand Up @@ -187,6 +208,11 @@ fn execute_command<'a>(
(Some(config), ConsoleCommand::Clean) => {
CommandResult::Batch(run_command(CommandSpec::Clean, config, true))
}
(_, ConsoleCommand::Cleanall) => {
let cwd = env::current_dir()
.map_err(|e| -> Box<dyn std::error::Error + Send + Sync> { Box::new(e) });
CommandResult::Single(cwd.and_then(|path| clean_all(&path)))
}
Comment thread
edwardalee marked this conversation as resolved.
Outdated
_ => todo!(),
}
}
Expand Down Expand Up @@ -216,7 +242,11 @@ fn build<'a>(args: &BuildArgs, config: &'a mut Config) -> BatchBuildResults<'a>
)
}

fn run_command(task: CommandSpec, config: &mut Config, _fail_at_end: bool) -> BatchBuildResults {
fn run_command(
task: CommandSpec,
config: &mut Config,
_fail_at_end: bool,
) -> BatchBuildResults<'_> {
let _apps = config.apps.iter().collect::<Vec<_>>();
liblingo::backends::execute_command(
&task,
Expand Down
26 changes: 26 additions & 0 deletions src/package/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use std::fmt::Display;
use std::fs;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::time::Instant;

use crate::GitCloneAndCheckoutCap;

Expand Down Expand Up @@ -213,18 +214,43 @@ impl DependencyLock {
lfc_include_folder: &Path,
git_clone_and_checkout_cap: &GitCloneAndCheckoutCap,
) -> anyhow::Result<()> {
println!(
"{} checking lock entries in {}",
"Build step:".green().bold(),
lfc_include_folder.display()
);
Comment thread
edwardalee marked this conversation as resolved.
Outdated
for (_, lock) in self.dependencies.iter() {
let temp = lfc_include_folder.join(&lock.name);
// the Lingo.toml for this dependency doesnt exists, hence we need to fetch this package
if !temp.join("Lingo.toml").exists() {
let mut details = PackageDetails::try_from(&lock.source)?;
println!(
"{} {} from {}+{}",
"Fetching".green().bold(),
lock.name,
lock.source.source_type,
lock.source.uri
);

details
.fetch(&temp, git_clone_and_checkout_cap)
.expect("cannot pull package");
}

println!(
"{} computing checksum for locked dependency {} at {}",
"Build step:".green().bold(),
lock.name,
temp.display()
);
let checksum_started_at = Instant::now();
let hash = sha1dir::checksum_current_dir(&temp, false);
println!(
"{} checksum complete for {} in {:?}",
"Build step:".green().bold(),
lock.name,
checksum_started_at.elapsed()
Comment thread
tanneberger marked this conversation as resolved.
Outdated
);

if hash.to_string() != lock.checksum {
error!("checksum does not match aborting!");
Expand Down
70 changes: 63 additions & 7 deletions src/package/management.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anyhow::Context;
use colored::Colorize;
use log::error;
use versions::{Requirement, Versioning};
Expand All @@ -10,6 +11,7 @@ use std::fs::File;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::time::Instant;
use url::{ParseError, Url};

use crate::package::lock::{PackageLockSource, PackageLockSourceType};
Expand Down Expand Up @@ -75,8 +77,12 @@ impl PackageDetails {
) -> anyhow::Result<()> {
match &self.mutual_exclusive {
ProjectSource::Path(path_buf) => {
let src = fs::canonicalize(path_buf)?;
let dst = fs::canonicalize(library_path)?;
let src = fs::canonicalize(path_buf).with_context(|| {
Comment thread
edwardalee marked this conversation as resolved.
format!("dependency path not found: {}", path_buf.display())
})?;
let dst = fs::canonicalize(library_path).with_context(|| {
format!("library path not found: {}", library_path.display())
})?;
Ok(copy_dir_all(src, dst)?)
}
ProjectSource::Git(git_url) => {
Expand All @@ -98,22 +104,45 @@ impl DependencyManager {
target_path: &Path,
git_clone_and_checkout_cap: &GitCloneAndCheckoutCap,
) -> anyhow::Result<DependencyManager> {
println!(
"{} resolving dependencies in {}",
"Build step:".green().bold(),
target_path.display()
);
Comment thread
edwardalee marked this conversation as resolved.
Outdated
// create library folder
let library_path = target_path.join(LIBRARY_DIRECTORY);
fs::create_dir_all(&library_path)?;
fs::create_dir_all(&library_path).with_context(|| {
format!(
"failed to create library directory: {}",
library_path.display()
)
})?;

let mut manager;
let mut lock: DependencyLock;
let lock_file = target_path.join("../Lingo.lock");

// checks if a Lingo.lock file exists
if lock_file.exists() {
println!(
"{} loading lock file {}",
"Build step:".green().bold(),
lock_file.display()
);
// reads and parses Lockfile
lock = toml::from_str::<DependencyLock>(&fs::read_to_string(lock_file)?)
lock =
toml::from_str::<DependencyLock>(&fs::read_to_string(&lock_file).with_context(
|| format!("failed to read lock file: {}", lock_file.display()),
)?)
.expect("cannot parse lock");

// if a lock file is present it will load the dependencies from it and checks
// integrity of the build directory
println!(
"{} validating lock dependencies in {}",
"Build step:".green().bold(),
target_path.join("lfc_include").display()
);
if let Ok(()) = lock.init(&target_path.join("lfc_include"), git_clone_and_checkout_cap)
{
return Ok(DependencyManager {
Expand All @@ -140,7 +169,9 @@ impl DependencyManager {
lock = DependencyLock::create(selection);

// writes the lock file down
let mut lock_file = File::create(target_path.join("../Lingo.lock"))?;
let lock_file_path = target_path.join("../Lingo.lock");
let mut lock_file = File::create(&lock_file_path)
.with_context(|| format!("failed to create lock file: {}", lock_file_path.display()))?;

println!("{:?}", lock.dependencies);
let serialized_toml = toml::to_string(&lock).expect("cannot generate toml");
Expand Down Expand Up @@ -168,7 +199,12 @@ impl DependencyManager {
self.pulling_queue.append(&mut dependencies);
let sub_dependency_path = root_path.join("libraries");
//fs::remove_dir_all(&sub_dependency_path)?;
fs::create_dir_all(&sub_dependency_path)?;
fs::create_dir_all(&sub_dependency_path).with_context(|| {
format!(
"failed to create directory: {}",
sub_dependency_path.display()
)
})?;

while !self.pulling_queue.is_empty() {
if let Some((package_name, package_details)) = self.pulling_queue.pop() {
Expand Down Expand Up @@ -216,12 +252,32 @@ impl DependencyManager {
fs::create_dir_all(&temporary_path)?;

// cloning the specified package
println!(
"{} fetching dependency {} into {}",
"Build step:".green().bold(),
name,
temporary_path.display()
);
package.fetch(&temporary_path, git_clone_and_checkout_cap)?;

println!(
"{} computing checksum for {}",
"Build step:".green().bold(),
temporary_path.display()
);
let checksum_started_at = Instant::now();
let hash = sha1dir::checksum_current_dir(&temporary_path, false);
println!(
"{} checksum complete for {} in {:?}",
"Build step:".green().bold(),
temporary_path.display(),
checksum_started_at.elapsed()
);
let include_path = library_path.join(hash.to_string());

let lingo_toml_text = fs::read_to_string(temporary_path.clone().join("Lingo.toml"))?;
let lingo_toml_path = temporary_path.join("Lingo.toml");
let lingo_toml_text = fs::read_to_string(&lingo_toml_path)
.with_context(|| format!("failed to read {}", lingo_toml_path.display()))?;
let read_toml = toml::from_str::<ConfigFile>(&lingo_toml_text)?.to_config(&temporary_path);

println!(" {}", read_toml.package.version);
Expand Down
2 changes: 1 addition & 1 deletion src/package/target_properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub struct LibraryTargetPropertiesFile {
sources: Vec<PathBuf>,

/// list of files that should be made available to the user
#[serde(rename = "sources", default)]
#[serde(rename = "artifacts", default)]
artifacts: Vec<PathBuf>,
}

Expand Down
6 changes: 4 additions & 2 deletions src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,10 @@ pub fn delete_subdirs(path_root: &Path, subdirs: &[&str]) -> io::Result<()> {
for &sub_dir in subdirs {
buf.push(sub_dir);
if buf.is_dir() {
// ignore errors
let _ = fs::remove_dir_all(&buf);
match fs::remove_dir_all(&buf) {
Ok(_) => println!("Deleted {}", buf.display()),
Err(err) => eprintln!("Failed to delete {}: {}", buf.display(), err),
}
Comment thread
edwardalee marked this conversation as resolved.
}
buf.pop();
}
Expand Down
Loading