Link command WIP
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
89
Cargo.lock
generated
Normal file
89
Cargo.lock
generated
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "alma"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.51"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.154"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8cdd151213925e7f1ab45a9bbfb129316bd00799784b174b7cc7bcd16961c49e"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.154"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4fc80d722935453bcafdc2c9a73cd6fac4dc1938f0346035d84bf99fa9e33217"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.94"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.109"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||||
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "alma"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
19
src/application/mod.rs
Normal file
19
src/application/mod.rs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
use crate::command::Command;
|
||||||
|
use crate::commands;
|
||||||
|
|
||||||
|
pub fn run(args: Vec<String>) {
|
||||||
|
if args.len() < 2 {
|
||||||
|
println!("No command provided");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let command: Option<Box<dyn Command>> = match args[1].as_str() {
|
||||||
|
"link" => Some(Box::new(commands::link::LinkCommand {})),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
|
match command {
|
||||||
|
Some(command) => command.run(&args[2..]),
|
||||||
|
None => println!("Invalid command: {}", args[1]),
|
||||||
|
}
|
||||||
|
}
|
||||||
3
src/command/mod.rs
Normal file
3
src/command/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
pub trait Command {
|
||||||
|
fn run(&self, args: &[std::string::String]);
|
||||||
|
}
|
||||||
73
src/commands/link/mod.rs
Normal file
73
src/commands/link/mod.rs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
use crate::command::Command;
|
||||||
|
use crate::configuration::module::resolver::*;
|
||||||
|
use crate::contants::*;
|
||||||
|
use crate::utils::path::path::*;
|
||||||
|
|
||||||
|
pub struct LinkCommand {}
|
||||||
|
|
||||||
|
impl LinkCommand {
|
||||||
|
pub fn run(args: &[std::string::String]) -> Result<(), String> {
|
||||||
|
let (repository_name, module_name) = get_repository_and_module_name(args, false);
|
||||||
|
|
||||||
|
if module_name.is_none() {
|
||||||
|
println!("No module specified!");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let (repo_source, repo_target) =
|
||||||
|
match get_repo_source_and_target_dir_with_default(repository_name) {
|
||||||
|
Ok((source, target)) => (source, target),
|
||||||
|
Err(e) => return Err(e.to_string()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let repo_source_path = std::path::Path::new(&repo_source);
|
||||||
|
if !repo_source_path.exists() {
|
||||||
|
return Err(format!(
|
||||||
|
"Repository source directory does not exist: {}",
|
||||||
|
repo_source
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let module_name_as_path = module_name
|
||||||
|
.unwrap()
|
||||||
|
.replace("/", &std::path::MAIN_SEPARATOR.to_string());
|
||||||
|
let module_dir = repo_source_path
|
||||||
|
.join(module_name_as_path)
|
||||||
|
.display()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
let module_config_dir = std::path::Path::new(&module_dir);
|
||||||
|
if !module_config_dir.exists() {
|
||||||
|
return Err(format!(
|
||||||
|
"Module source directory does not exist: {}",
|
||||||
|
module_dir
|
||||||
|
));
|
||||||
|
}
|
||||||
|
let module_config_file_stub = module_config_dir
|
||||||
|
.join(MODULE_CONFIG_FILE_STUB)
|
||||||
|
.display()
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
let module_configuration = resolve_module_configuration(module_config_file_stub);
|
||||||
|
|
||||||
|
if module_configuration.is_err() {
|
||||||
|
return Err(module_configuration.err().unwrap().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let module_configuration = module_configuration.unwrap();
|
||||||
|
for l in module_configuration.links.unwrap().iter() {
|
||||||
|
print!("Linking {} to {}...", l.0, l.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command for LinkCommand {
|
||||||
|
fn run(&self, args: &[std::string::String]) {
|
||||||
|
match Self::run(args) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => println!("Error while linking: {}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/commands/mod.rs
Normal file
1
src/commands/mod.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub mod link;
|
||||||
62
src/configuration/module/mod.rs
Normal file
62
src/configuration/module/mod.rs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
pub mod resolver;
|
||||||
|
|
||||||
|
use std::{collections::HashMap, fmt::{Display, Formatter}};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct ModuleConfiguration {
|
||||||
|
pub target: Option<String>,
|
||||||
|
pub install: Option<String>,
|
||||||
|
pub configure: Option<String>,
|
||||||
|
pub links: Option<HashMap<String, String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModuleConfiguration {
|
||||||
|
pub fn empty() -> ModuleConfiguration {
|
||||||
|
return ModuleConfiguration {
|
||||||
|
target: None,
|
||||||
|
install: None,
|
||||||
|
configure: None,
|
||||||
|
links: None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clone_option<T: Clone>(s: &Option<T>) -> Option<T> {
|
||||||
|
match s {
|
||||||
|
Some(s) => Some(s.clone()),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn merge(self, to_merge: &ModuleConfiguration) -> ModuleConfiguration {
|
||||||
|
let mut merged_links = self.links.unwrap_or(HashMap::new()).clone();
|
||||||
|
let links_to_merge = Self::clone_option::<HashMap<String, String>>(&to_merge.links)
|
||||||
|
.unwrap_or(HashMap::new())
|
||||||
|
.clone();
|
||||||
|
for (key, value) in links_to_merge {
|
||||||
|
merged_links.insert(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
let to_merge_target = Self::clone_option::<String>(&to_merge.target);
|
||||||
|
let to_merge_install = Self::clone_option::<String>(&to_merge.install);
|
||||||
|
let to_merge_configure = Self::clone_option::<String>(&to_merge.configure);
|
||||||
|
|
||||||
|
return ModuleConfiguration {
|
||||||
|
target: to_merge_target.or(self.target),
|
||||||
|
install: to_merge_install.or(self.install),
|
||||||
|
configure: to_merge_configure.or(self.configure),
|
||||||
|
links: Some(merged_links),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for ModuleConfiguration {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"target: {:?}, install: {:?}, configure: {:?}, links: {:?}",
|
||||||
|
self.target, self.install, self.configure, self.links
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/configuration/module/resolver.rs
Normal file
24
src/configuration/module/resolver.rs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::configuration::module::ModuleConfiguration;
|
||||||
|
use crate::configuration::reader;
|
||||||
|
use crate::utils::os_information::*;
|
||||||
|
|
||||||
|
pub fn resolve_module_configuration(
|
||||||
|
config_file_stub: String,
|
||||||
|
) -> std::io::Result<ModuleConfiguration> {
|
||||||
|
let configurations =
|
||||||
|
reader::read_config::<HashMap<String, ModuleConfiguration>>(config_file_stub)?;
|
||||||
|
let os_identifier = get_os_identifier();
|
||||||
|
|
||||||
|
let configurations: Vec<&ModuleConfiguration> = configurations
|
||||||
|
.iter()
|
||||||
|
.filter(|(k, _)| is_on_platform(&os_identifier, k))
|
||||||
|
.map(|c| c.1)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let configuration = configurations.iter()
|
||||||
|
.fold(ModuleConfiguration::empty(), |acc, c| acc.merge(c));
|
||||||
|
|
||||||
|
return Ok(configuration);
|
||||||
|
}
|
||||||
7
src/configuration/reader.rs
Normal file
7
src/configuration/reader.rs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
pub fn read_config<T>(config_file_stub: String) -> std::io::Result<T> where T: serde::de::DeserializeOwned {
|
||||||
|
let config_file_path = format!("{}.json", config_file_stub);
|
||||||
|
let config_file = std::fs::File::open(config_file_path)?;
|
||||||
|
let config: T = serde_json::from_reader(config_file)?;
|
||||||
|
|
||||||
|
return Ok(config);
|
||||||
|
}
|
||||||
29
src/configuration/repository/mod.rs
Normal file
29
src/configuration/repository/mod.rs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
use crate::utils::folder::get_config_home_path;
|
||||||
|
|
||||||
|
use super::reader;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct RepositoryConfigurationEntry {
|
||||||
|
pub name: Option<String>,
|
||||||
|
pub repository_path: Option<String>,
|
||||||
|
pub link_path: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct RepositoryConfigurationRoot {
|
||||||
|
pub repositories: Vec<RepositoryConfigurationEntry>
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_repository_configuration() -> std::io::Result<RepositoryConfigurationRoot> {
|
||||||
|
let config_file_path = get_config_home_path();
|
||||||
|
let repo_config_file_path_stub = Path::new(&config_file_path).join("repository").display().to_string();
|
||||||
|
|
||||||
|
let config = reader::read_config::<RepositoryConfigurationRoot>(repo_config_file_path_stub)?;
|
||||||
|
|
||||||
|
return Ok(config);
|
||||||
|
}
|
||||||
1
src/contants.rs
Normal file
1
src/contants.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub const MODULE_CONFIG_FILE_STUB: &str = ".alma-config";
|
||||||
22
src/main.rs
Normal file
22
src/main.rs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
use std::env;
|
||||||
|
|
||||||
|
mod application;
|
||||||
|
mod command;
|
||||||
|
mod commands;
|
||||||
|
mod contants;
|
||||||
|
mod utils {
|
||||||
|
pub mod path;
|
||||||
|
pub mod folder;
|
||||||
|
pub mod os_information;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod configuration {
|
||||||
|
pub mod module;
|
||||||
|
pub mod reader;
|
||||||
|
pub mod repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
application::run(args);
|
||||||
|
}
|
||||||
18
src/utils/folder.rs
Normal file
18
src/utils/folder.rs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
const APPLICATION_SUBFOLDER_NAME: &str = "alma";
|
||||||
|
|
||||||
|
pub fn get_config_home_path() -> String {
|
||||||
|
let config_home_path = std::env::var("XDG_CONFIG_HOME")
|
||||||
|
.map_or_else(
|
||||||
|
|_| {
|
||||||
|
let home_path = std::env::var("HOME").unwrap();
|
||||||
|
Path::new(&home_path).join(".config")
|
||||||
|
},
|
||||||
|
|c| Path::new(&c).to_path_buf(),
|
||||||
|
)
|
||||||
|
.join(APPLICATION_SUBFOLDER_NAME)
|
||||||
|
.display()
|
||||||
|
.to_string();
|
||||||
|
return config_home_path;
|
||||||
|
}
|
||||||
60
src/utils/os_information.rs
Normal file
60
src/utils/os_information.rs
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
use std::{
|
||||||
|
fs::File,
|
||||||
|
io::{BufRead, BufReader},
|
||||||
|
path::Path,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const OS_IDENTIFIER_DEFAULT: &str = "default";
|
||||||
|
pub const OS_IDENTIFIER_WINDOWS: &str = "windows";
|
||||||
|
pub const OS_IDENTIFIER_MAC: &str = "macos";
|
||||||
|
pub const OS_IDENTIFIER_LINUX: &str = "linux";
|
||||||
|
pub const OS_IDENTIFIER_FREEBSD: &str = "freebsd";
|
||||||
|
|
||||||
|
pub fn is_on_platform(current_os_identifier: &String, taget_os_identifier: &String) -> bool {
|
||||||
|
return taget_os_identifier == OS_IDENTIFIER_DEFAULT
|
||||||
|
|| current_os_identifier == taget_os_identifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_os_identifier() -> String {
|
||||||
|
let base_os_identifier = match std::env::consts::OS {
|
||||||
|
"windows" => OS_IDENTIFIER_WINDOWS.to_string(),
|
||||||
|
"macos" => OS_IDENTIFIER_MAC.to_string(),
|
||||||
|
"linux" => get_linux_identifier(),
|
||||||
|
"freebsd" => OS_IDENTIFIER_FREEBSD.to_string(),
|
||||||
|
_ => String::from("unknown"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let processor_architecture = std::env::consts::ARCH;
|
||||||
|
|
||||||
|
return base_os_identifier + "-" + processor_architecture;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_linux_identifier() -> String {
|
||||||
|
let os_release_path = Path::new("/etc/os-release");
|
||||||
|
let distroname = if os_release_path.exists() {
|
||||||
|
get_os_release(os_release_path)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
distroname.map_or(OS_IDENTIFIER_LINUX.to_string(), |s| {
|
||||||
|
OS_IDENTIFIER_LINUX.to_string() + "-" + &s
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_os_release(os_release_path: &Path) -> Option<String> {
|
||||||
|
let os_release_file = File::open(os_release_path).unwrap();
|
||||||
|
let reader = BufReader::new(os_release_file);
|
||||||
|
for line in reader.lines() {
|
||||||
|
if line.is_err() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let line = line.unwrap();
|
||||||
|
if line.starts_with("ID=") {
|
||||||
|
let os_identifier = line.replace("ID=", "");
|
||||||
|
return Some(os_identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
}
|
||||||
81
src/utils/path.rs
Normal file
81
src/utils/path.rs
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
pub mod path {
|
||||||
|
use std::env::current_dir;
|
||||||
|
|
||||||
|
use crate::configuration::repository::read_repository_configuration;
|
||||||
|
|
||||||
|
pub fn get_repository_and_module_name(
|
||||||
|
args: &[std::string::String],
|
||||||
|
single_param_is_repo: bool,
|
||||||
|
) -> (Option<String>, Option<String>) {
|
||||||
|
//TODO: handle parameters
|
||||||
|
|
||||||
|
match args.len() {
|
||||||
|
0 => (None, None),
|
||||||
|
1 => {
|
||||||
|
return if single_param_is_repo {
|
||||||
|
(Some(args[0].clone()), None)
|
||||||
|
} else {
|
||||||
|
(None, Some(args[0].clone()))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_ => (Some(args[0].clone()), Some(args[1].clone())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_repo_source_and_target_dir_with_default(
|
||||||
|
repo_name: Option<String>,
|
||||||
|
) -> std::io::Result<(String, String)> {
|
||||||
|
if current_dir().is_err() {
|
||||||
|
return Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::Other,
|
||||||
|
"Could not get current directory!",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
let source_dir_fallback = current_dir()?.display().to_string();
|
||||||
|
|
||||||
|
let mut target_dir_fallback = current_dir()?;
|
||||||
|
target_dir_fallback.push("..");
|
||||||
|
let target_dir_fallback = target_dir_fallback.display().to_string();
|
||||||
|
|
||||||
|
let (repo_source_dir, repo_target_dir) =
|
||||||
|
get_repo_source_and_target_dir(repo_name, source_dir_fallback, target_dir_fallback)?;
|
||||||
|
|
||||||
|
return Ok((repo_source_dir, repo_target_dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_repo_source_and_target_dir(
|
||||||
|
repo_name: Option<String>,
|
||||||
|
fallback_source: String,
|
||||||
|
fallback_target: String,
|
||||||
|
) -> std::io::Result<(String, String)> {
|
||||||
|
if repo_name.is_none() {
|
||||||
|
return Ok((fallback_source, fallback_target));
|
||||||
|
}
|
||||||
|
|
||||||
|
let repo_name = repo_name.unwrap();
|
||||||
|
|
||||||
|
let repo_configurtaion = read_repository_configuration()?;
|
||||||
|
let repo_config = repo_configurtaion
|
||||||
|
.repositories
|
||||||
|
.iter()
|
||||||
|
.find(|x| x.name.clone().map_or(false, |s| s == repo_name));
|
||||||
|
|
||||||
|
if repo_config.is_none() {
|
||||||
|
println!(
|
||||||
|
"No repository configuration found for repository: {}",
|
||||||
|
repo_name
|
||||||
|
);
|
||||||
|
return Ok((fallback_source, fallback_target));
|
||||||
|
}
|
||||||
|
|
||||||
|
let repo_config = repo_config.unwrap();
|
||||||
|
|
||||||
|
let source_path = repo_config
|
||||||
|
.repository_path
|
||||||
|
.clone()
|
||||||
|
.unwrap_or(fallback_source);
|
||||||
|
let target_path = repo_config.link_path.clone().unwrap_or(fallback_target);
|
||||||
|
|
||||||
|
return Ok((source_path, target_path));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user