Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reactor-uc project templates #53

Merged
merged 1 commit into from
Dec 10, 2024
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
5 changes: 5 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::path::PathBuf;
#[value(rename_all = "lowercase")]
pub enum TargetLanguage {
C,
UC,
CCpp,
Cpp,
Rust,
Expand All @@ -19,6 +20,10 @@ pub enum Platform {
Native,
Zephyr,
RP2040,
LF3PI,
FlexPRET,
Patmos,
RIOT,
}

#[derive(clap::ValueEnum, Clone, Copy, Debug, Deserialize, Serialize, Eq, PartialEq, Hash)]
Expand Down
47 changes: 26 additions & 21 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,15 @@ use std::process::Command;
use std::{env, io};

use clap::Parser;
use git2::Repository;
use git2::{BranchType, ObjectType, Repository};

use liblingo::args::InitArgs;
use liblingo::args::{BuildArgs, Command as ConsoleCommand, CommandLineArgs};
use liblingo::backends::{BatchBuildResults, BuildCommandOptions, CommandSpec};
use liblingo::package::tree::GitLock;
use liblingo::package::{Config, ConfigFile};
use liblingo::util::errors::{BuildResult, LingoError};
use liblingo::{GitCloneCapability, GitCloneError, GitUrl, WhichCapability, WhichError};

fn do_repo_clone(url: GitUrl, into: &std::path::Path) -> Result<(), GitCloneError> {
Repository::clone(url.into(), into).map_or_else(
|err: git2::Error| Err(GitCloneError(format!("{}", err))),
|_| Ok(()),
)
}
use liblingo::{GitCloneAndCheckoutCap, GitCloneError, GitUrl, WhichCapability, WhichError};

fn do_which(cmd: &str) -> Result<PathBuf, WhichError> {
which::which(cmd).map_err(|err| match err {
Expand All @@ -42,18 +35,30 @@ fn do_clone_and_checkout(
let mut git_rev = None;

if let Some(git_lock) = git_tag {
let name = match git_lock {
GitLock::Tag(tag) => tag,
GitLock::Branch(branch) => branch,
GitLock::Rev(rev) => rev,
let (object, reference) = match git_lock {
GitLock::Tag(tag) => repo
.revparse_ext(&tag)
.map_err(|e| GitCloneError(format!("cannot parse rev {e}")))?,
GitLock::Branch(branch) => {
let reference = repo
.find_branch(&branch, BranchType::Remote)
.map_err(|_| GitCloneError("cannot find branch".to_string()))?
.into_reference();
(
reference
.peel(ObjectType::Any)
.map_err(|_| GitCloneError("cannot peel object".to_string()))?,
Some(reference),
)
}
GitLock::Rev(rev) => repo
.revparse_ext(&rev)
.map_err(|e| GitCloneError(format!("cannot parse rev {e}")))?,
};
repo.checkout_tree(&object, None)
.map_err(|e| GitCloneError(format!("cannot checkout rev {e}")))?;

// TODO: this produces hard to debug output
let (object, reference) = repo
.revparse_ext(&name)
.map_err(|_| GitCloneError("cannot parse rev".to_string()))?;
repo.checkout_tree(&object, None)
.map_err(|_| GitCloneError("cannot checkout rev".to_string()))?;

match reference {
// gref is an actual reference like branches or tags
Expand Down Expand Up @@ -100,7 +105,7 @@ fn main() {
&mut wrapped_config,
args.command,
Box::new(do_which),
Box::new(do_repo_clone),
Box::new(do_clone_and_checkout),
);

match result {
Expand Down Expand Up @@ -145,7 +150,7 @@ fn execute_command<'a>(
config: &'a mut Option<Config>,
command: ConsoleCommand,
_which_capability: WhichCapability,
git_clone_capability: GitCloneCapability,
git_clone_capability: GitCloneAndCheckoutCap,
) -> CommandResult<'a> {
match (config, command) {
(_, ConsoleCommand::Init(init_config)) => {
Expand Down Expand Up @@ -174,7 +179,7 @@ fn execute_command<'a>(
}
}

fn do_init(init_config: InitArgs, git_clone_capability: &GitCloneCapability) -> BuildResult {
fn do_init(init_config: InitArgs, git_clone_capability: &GitCloneAndCheckoutCap) -> BuildResult {
let initial_config = ConfigFile::new_for_init_task(&init_config)?;
initial_config.write(Path::new("./Lingo.toml"))?;
initial_config.setup_example(
Expand Down
74 changes: 56 additions & 18 deletions src/package/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
use std::str::FromStr;
use std::{env, fmt, io};

use crate::args::TargetLanguage::UC;
use crate::args::{
BuildSystem,
BuildSystem::{CMake, LFC},
InitArgs, Platform, TargetLanguage,
};
use crate::package::tree::GitLock;
use crate::package::{
target_properties::{
AppTargetProperties, AppTargetPropertiesFile, LibraryTargetProperties,
Expand All @@ -33,7 +35,7 @@
analyzer, copy_recursively,
errors::{BuildResult, LingoError},
};
use crate::{FsReadCapability, GitCloneCapability, GitUrl, WhichCapability};
use crate::{FsReadCapability, GitCloneAndCheckoutCap, GitUrl, WhichCapability};

/// place where are the build artifacts will be dropped
pub const OUTPUT_DIRECTORY: &str = "build";
Expand Down Expand Up @@ -291,7 +293,7 @@

struct VersioningVisitor;

impl<'de> Visitor<'de> for VersioningVisitor {

Check warning on line 296 in src/package/mod.rs

View workflow job for this annotation

GitHub Actions / Clippy Output

the following explicit lifetimes could be elided: 'de

warning: the following explicit lifetimes could be elided: 'de --> src/package/mod.rs:296:6 | 296 | impl<'de> Visitor<'de> for VersioningVisitor { | ^^^ ^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes help: elide the lifetimes | 296 - impl<'de> Visitor<'de> for VersioningVisitor { 296 + impl Visitor<'_> for VersioningVisitor { |
type Value = Versioning;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Expand Down Expand Up @@ -404,10 +406,23 @@
Ok(())
}

fn setup_template_repo(&self, url: &str, clone: &GitCloneCapability) -> BuildResult {
fn setup_template_repo(
&self,
url: &str,
target_language: TargetLanguage,
clone: &GitCloneAndCheckoutCap,
) -> BuildResult {
let dir = tempdir()?;
let tmp_path = dir.path();
clone(GitUrl::from(url), tmp_path)?;

let git_rev = if target_language == UC {
Some(GitLock::Branch("origin/reactor-uc".to_string()))
} else {
None
};

clone(GitUrl::from(url), tmp_path, git_rev)?;

// Copy the cloned template repo into the project directory
copy_recursively(tmp_path, Path::new("."))?;
// Remove temporary folder
Expand All @@ -416,34 +431,57 @@
}

// Sets up a LF project with Zephyr as the target platform.
fn setup_zephyr(&self, clone: &GitCloneCapability) -> BuildResult {
let url = "https://github.com/lf-lang/lf-west-template";
self.setup_template_repo(url, clone)?;
fn clone_and_clean(
&self,
url: &str,
target_language: TargetLanguage,
clone: &GitCloneAndCheckoutCap,
) -> BuildResult {
self.setup_template_repo(url, target_language, clone)?;
remove_file(".gitignore")?;
remove_dir_all(Path::new(".git"))?;
Ok(())
}

// Sets up a LF project with RP2040 MCU as the target platform.
// Initializes a repo using the lf-pico-template
fn setup_rp2040(&self, clone: &GitCloneCapability) -> BuildResult {
let url = "https://github.com/lf-lang/lf-pico-template";
// leave git artifacts
self.setup_template_repo(url, clone)?;
Ok(())
}

pub fn setup_example(
&self,
platform: Platform,
target_language: TargetLanguage,
git_clone_capability: &GitCloneCapability,
git_clone_capability: &GitCloneAndCheckoutCap,
) -> BuildResult {
if is_valid_location_for_project(Path::new(".")) {
match platform {
Platform::Native => self.setup_native(target_language),
Platform::Zephyr => self.setup_zephyr(git_clone_capability),
Platform::RP2040 => self.setup_rp2040(git_clone_capability),
Platform::Zephyr => self.clone_and_clean(
"https://github.com/lf-lang/lf-west-template",
target_language,
git_clone_capability,
),
Platform::RP2040 => self.clone_and_clean(
"https://github.com/lf-lang/lf-pico-template",
target_language,
git_clone_capability,
),
Platform::LF3PI => self.clone_and_clean(
"https://github.com/lf-lang/lf-3pi-template",
target_language,
git_clone_capability,
),
Platform::FlexPRET => self.clone_and_clean(
"https://github.com/lf-lang/lf-flexpret-template",
target_language,
git_clone_capability,
),
Platform::Patmos => self.clone_and_clean(
"https://github.com/lf-lang/lf-patmos-template",
target_language,
git_clone_capability,
),
Platform::RIOT => self.clone_and_clean(
"https://github.com/lf-lang/lf-riot-template",
target_language,
git_clone_capability,
),
}
} else {
Err(Box::new(LingoError::InvalidProjectLocation(
Expand Down
Loading