Skip to content

Commit

Permalink
resolve part mostly done, partially migrated next
Browse files Browse the repository at this point in the history
  • Loading branch information
tiptenbrink committed May 2, 2024
1 parent 1cb5819 commit f787ece
Show file tree
Hide file tree
Showing 6 changed files with 336 additions and 259 deletions.
48 changes: 19 additions & 29 deletions src/next/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,43 +86,33 @@ fn overwrite_scope(original: ConfigScope, replacing: ConfigScope) -> ConfigScope
}

pub(crate) fn merge_vars(
root_vars: Option<Vec<ConfigVar>>,
overwrite_vars: Option<Vec<ConfigVar>>,
) -> Option<Vec<ConfigVar>> {
if let Some(root_vars) = root_vars {
if let Some(overwrite_vars) = overwrite_vars {
let mut vars_map: HashMap<String, String> = root_vars
.iter()
.map(|v| (v.key.clone(), v.env_name.clone()))
.collect();

for cfg_var in overwrite_vars {
vars_map.insert(cfg_var.key, cfg_var.env_name);
}

Some(
vars_map
.into_iter()
.map(|(k, v)| ConfigVar {
env_name: v,
key: k,
})
.collect(),
)
} else {
Some(root_vars)
}
} else {
overwrite_vars.clone()
root_vars: Vec<ConfigVar>,
overwrite_vars: Vec<ConfigVar>,
) -> Vec<ConfigVar> {
let mut vars_map: HashMap<String, String> = root_vars
.iter()
.map(|v| (v.key.clone(), v.env_name.clone()))
.collect();

for cfg_var in overwrite_vars {
vars_map.insert(cfg_var.key, cfg_var.env_name);
}

vars_map
.into_iter()
.map(|(k, v)| ConfigVar {
env_name: v,
key: k,
})
.collect()
}

fn overwrite_arguments(root_config: ArgumentConfig, overwrite_config: ArgumentConfig) -> ArgumentConfig {
let scope = merge_option(root_config.scope, overwrite_config.scope, &overwrite_scope);

let execution_path = overwrite_option(root_config.execution_path, overwrite_config.execution_path);
let executable = overwrite_option(root_config.executable, overwrite_config.executable);
let envs = merge_vars(root_config.envs, overwrite_config.envs);
let envs = merge_option(root_config.envs, overwrite_config.envs, &merge_vars);

ArgumentConfig {
scope,
Expand Down
15 changes: 7 additions & 8 deletions src/next/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,19 @@ where
/// Runs the entrypoint, sending the entrypoint's stdout and stderr to stdout. It adds the provided envs to
/// the envs of the tidploy process. `input_bytes` is useful mostly for testing, if set to None then the
/// child process will just inherit the stdin of the tidploy process.
pub(crate) fn run_entrypoint<P: AsRef<Path>>(
entrypoint_dir: P,
entrypoint: &RelativePath,
pub(crate) fn run_entrypoint(
working_dir: &Path,
entrypoint: &Path,
envs: HashMap<String, String>,
input_bytes: Option<Vec<u8>>,
) -> Result<EntrypointOut, Report> {
println!("Running {}!", &entrypoint);
let program_path = entrypoint.to_path(entrypoint_dir.as_ref());
println!("Running {:?} in working dir {:?}!", &entrypoint, &working_dir);
// Use parent process env variables as base
let mut combined_envs: HashMap<_, _> = std::env::vars().collect();
combined_envs.extend(envs);

let cmd_expr = cmd(&program_path, Vec::<String>::new())
.dir(entrypoint_dir.as_ref())
let cmd_expr = cmd(entrypoint, Vec::<String>::new())
.dir(working_dir)
.full_env(&combined_envs)
.stderr_to_stdout()
.unchecked();
Expand All @@ -87,7 +86,7 @@ pub(crate) fn run_entrypoint<P: AsRef<Path>>(

let reader = cmd_expr.reader()?;

let entry_span = span!(Level::DEBUG, "entrypoint", path = program_path.to_str());
let entry_span = span!(Level::DEBUG, "entrypoint", path = entrypoint.to_string_lossy().as_ref());
let _enter = entry_span.enter();

let mut out: String = String::with_capacity(128);
Expand Down
193 changes: 130 additions & 63 deletions src/next/resolve.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
use std::{collections::HashMap, env, path::{Path, PathBuf}};

use relative_path::RelativePath;
use relative_path::{RelativePath, RelativePathBuf};

use super::{config::traverse_configs, errors::ResolutionError};
use super::{config::{merge_vars, traverse_configs, ArgumentConfig, ConfigScope, ConfigVar}, errors::ResolutionError};

#[derive(Default)]
struct SecretScopeArguments {
name: Option<String>,
sub: Option<String>,
service: Option<String>
pub(crate) struct SecretScopeArguments {
pub(crate) name: Option<String>,
pub(crate) sub: Option<String>,
pub(crate) service: Option<String>
}

impl SecretScopeArguments {
/// Overrides fields with other if other has them defined
fn merge(&self, other: Self) -> Self {
Self {
service: other.service.or(self.service),
Expand All @@ -21,48 +22,81 @@ impl SecretScopeArguments {
}
}

impl From<ConfigScope> for SecretScopeArguments {
fn from(value: ConfigScope) -> Self {
Self {
service: value.service,
name: value.name,
sub: value.sub
}
}
}

#[derive(Default)]
struct RunArguments {
executable: Option<String>,
execution_path: Option<String>,
envs: Vec<String>,
scope_args: SecretScopeArguments
pub(crate) struct RunArguments {
pub(crate) executable: Option<String>,
pub(crate) execution_path: Option<String>,
pub(crate) envs: Vec<ConfigVar>,
pub(crate) scope_args: SecretScopeArguments
}

impl RunArguments {
/// Overrides fields with other if other has them defined
fn merge(&self, other: Self) -> Self {
Self {
executable: other.executable.or(self.executable),
execution_path: other.execution_path.or(self.execution_path),
envs: merge_vars(self.envs, other.envs),
scope_args: self.scope_args.merge(other.scope_args)
}
}
}

impl From<ArgumentConfig> for RunArguments {
fn from(value: ArgumentConfig) -> Self {
RunArguments {
executable: value.executable,
execution_path: value.execution_path,
envs: value.envs.unwrap_or_default(),
scope_args: value.scope.map(|s| s.into()).unwrap_or_default(),
}
}
}

struct SecretArguments {
key: String,
scope_args: SecretScopeArguments
}

struct SecretScope {
service: String,
name: String,
sub: String,
hash: String
pub(crate) struct SecretScope {
pub(crate) service: String,
pub(crate) name: String,
pub(crate) sub: String,
pub(crate) hash: String
}

struct RunResolved {
executable: PathBuf,
execution_path: PathBuf,
envs: HashMap<String, String>,
scope: SecretScope
pub(crate) struct RunResolved {
pub(crate) executable: PathBuf,
pub(crate) execution_path: PathBuf,
pub(crate) envs: Vec<ConfigVar>,
pub(crate) scope: SecretScope
}

struct SecretResolved {
key: String,
scope: SecretScope
}

enum OutArguments {
Secret,
Run
}

enum Arguments {
Secret(SecretArguments),
Run(RunArguments)
}

// enum ResolvedEnvironment {
// Run(RunResolved),
// Secret(SecretResolved)
// }

fn env_scope_args() -> SecretScopeArguments {
let mut scope_args = SecretScopeArguments::default();

Expand Down Expand Up @@ -103,46 +137,79 @@ fn env_run_args() -> RunArguments {
run_arguments
}

fn merge_scope(root_config: SecretScope, overwrite_config: SecretScope) -> SecretScope {
ArgumentConfig {
scope,
executable,
execution_path,
envs
pub(crate) trait Resolve<Resolved> where Self: Sized {
fn merge_env_config(self, state_root: &Path, state_path: &RelativePath) -> Result<Self, ResolutionError>;

fn resolve(self, resolve_root: &Path, name: &str, sub: &str, hash: &str) -> Resolved;
}

fn resolve_scope(args: Arguments, name: &str, sub: &str, hash: &str) -> SecretScope {
let scope_args = match args {
Arguments::Run(run_args) => run_args.scope_args,
Arguments::Secret(secret_args) => secret_args.scope_args
};

SecretScope {
service: scope_args.service.unwrap_or("tidploy".to_owned()),
name: scope_args.name.unwrap_or(name.to_owned()),
sub: scope_args.sub.unwrap_or(sub.to_owned()),
hash: hash.to_owned()
}
}

fn resolve(state_root: &Path, state_path: &RelativePath, resolve_root: &Path, hash: String, args: Arguments) -> Result<(), ResolutionError> {
let config = traverse_configs(state_root, state_path)?;

match args {
Arguments::Secret(secret_args) => {
let secret_args_env = env_secret_args();

let merged_args = SecretArguments {
key: secret_args.key,
scope_args: secret_args_env.scope_args.merge(secret_args.scope_args)
};

let merged_args = if let Some(config_args) = config.argument {
if let Some(config_scope) = config_args.scope {
let scope_args = merged_args.scope_args;
SecretArguments {
key: merged_args.key,
scope_args: SecretScopeArguments {
service: scope_args.service.or(config_scope.service),
name: scope_args.name.or(config_scope.name),
sub: scope_args.sub.or(config_scope.sub),
}
}
} else {
merged_args
}
} else {
merged_args
};
impl Resolve<RunResolved> for RunArguments {
fn merge_env_config(self, state_root: &Path, state_path: &RelativePath) -> Result<Self, ResolutionError> {
let config = traverse_configs(state_root, state_path)?;

let run_args_env = env_run_args();

let merged_args = run_args_env.merge(self);

let config_run = config.argument.map(|a| RunArguments::from(a))
.unwrap_or_default();

Ok(config_run.merge(merged_args))
}

fn resolve(self, resolve_root: &Path, name: &str, sub: &str, hash: &str) -> RunResolved {
let scope = resolve_scope(Arguments::Run(self), name, sub, hash);

let relative_exe = RelativePathBuf::from(self.executable.unwrap_or("".to_owned()));
let relative_exn_path = RelativePathBuf::from(self.execution_path.unwrap_or("".to_owned()));
RunResolved {
executable: relative_exe.to_path(resolve_root),
execution_path: relative_exn_path.to_path(resolve_root),
envs: self.envs,
scope
}
}
}

impl Resolve<SecretResolved> for SecretArguments {
fn merge_env_config(self, state_root: &Path, state_path: &RelativePath) -> Result<Self, ResolutionError> {
let config = traverse_configs(state_root, state_path)?;

let secret_args_env = env_secret_args();

let mut merged_args = SecretArguments {
key: self.key,
scope_args: secret_args_env.scope_args.merge(self.scope_args)
};

let config_scope = config.argument.map(|a| a.scope).flatten().map(|s| SecretScopeArguments::from(s))
.unwrap_or_default();

merged_args.scope_args = config_scope.merge(merged_args.scope_args);

Ok(())
}
Ok(merged_args)
}

fn resolve(self, resolve_root: &Path, name: &str, sub: &str, hash: &str) -> SecretResolved {
let scope = resolve_scope(Arguments::Secret(self), name, sub, hash);

SecretResolved {
key: self.key,
scope
}
}
}
Loading

0 comments on commit f787ece

Please sign in to comment.