Make blueprint files configurable in and out

Closes #1055.
This commit is contained in:
KtorZ 2024-11-13 18:12:52 +01:00
parent c523b0153d
commit a51f7285c1
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
8 changed files with 120 additions and 34 deletions

View File

@ -9,6 +9,7 @@
### Changed ### Changed
- **aiken**: Add more flexibility around the management of Plutus blueprint files for `build`, `address`, `policy` and `apply` commands. See [#1055](https://github.com/aiken-lang/aiken/issues/1055). @KtorZ
- **aiken**: Rename `--filter_traces` to `--trace_filter` for more consistency with `--trace_level`. An alias for `--filter_traces` still exists for backward compatibility. @KtorZ - **aiken**: Rename `--filter_traces` to `--trace_filter` for more consistency with `--trace_level`. An alias for `--filter_traces` still exists for backward compatibility. @KtorZ
- **aiken-project**: Fix `aiken docs` wrongly formatting list constants as tuples. See [#1048](https://github.com/aiken-lang/aiken/issues/1048). @KtorZ - **aiken-project**: Fix `aiken docs` wrongly formatting list constants as tuples. See [#1048](https://github.com/aiken-lang/aiken/issues/1048). @KtorZ
- **aiken-project**: Fix `aiken docs` source linking crashing when generating docs for config modules. See [#1044](https://github.com/aiken-lang/aiken/issues/1044). @KtorZ - **aiken-project**: Fix `aiken docs` source linking crashing when generating docs for config modules. See [#1044](https://github.com/aiken-lang/aiken/issues/1044). @KtorZ

View File

@ -192,16 +192,25 @@ where
self.defined_modules = checkpoint.defined_modules; self.defined_modules = checkpoint.defined_modules;
} }
pub fn blueprint_path(&self, filepath: Option<&Path>) -> PathBuf {
match filepath {
Some(filepath) => filepath.to_path_buf(),
None => self.root.join(Options::default().blueprint_path),
}
}
pub fn build( pub fn build(
&mut self, &mut self,
uplc: bool, uplc: bool,
tracing: Tracing, tracing: Tracing,
blueprint_path: PathBuf,
env: Option<String>, env: Option<String>,
) -> Result<(), Vec<Error>> { ) -> Result<(), Vec<Error>> {
let options = Options { let options = Options {
code_gen_mode: CodeGenMode::Build(uplc), code_gen_mode: CodeGenMode::Build(uplc),
tracing, tracing,
env, env,
blueprint_path,
}; };
self.compile(options) self.compile(options)
@ -282,6 +291,7 @@ where
property_max_success, property_max_success,
} }
}, },
blueprint_path: self.blueprint_path(None),
}; };
self.compile(options) self.compile(options)
@ -307,10 +317,6 @@ where
Ok(()) Ok(())
} }
pub fn blueprint_path(&self) -> PathBuf {
self.root.join("plutus.json")
}
fn config_definitions(&mut self, env: Option<&str>) -> Option<Vec<UntypedDefinition>> { fn config_definitions(&mut self, env: Option<&str>) -> Option<Vec<UntypedDefinition>> {
if !self.config.config.is_empty() { if !self.config.config.is_empty() {
let env = env.unwrap_or(ast::DEFAULT_ENV_MODULE); let env = env.unwrap_or(ast::DEFAULT_ENV_MODULE);
@ -359,7 +365,7 @@ where
CodeGenMode::Build(uplc_dump) => { CodeGenMode::Build(uplc_dump) => {
self.event_listener self.event_listener
.handle_event(Event::GeneratingBlueprint { .handle_event(Event::GeneratingBlueprint {
path: self.blueprint_path(), path: options.blueprint_path.clone(),
}); });
self.checked_modules.values_mut().for_each(|m| { self.checked_modules.values_mut().for_each(|m| {
@ -381,10 +387,10 @@ where
let json = serde_json::to_string_pretty(&blueprint).unwrap(); let json = serde_json::to_string_pretty(&blueprint).unwrap();
fs::write(self.blueprint_path(), json).map_err(|error| { fs::write(options.blueprint_path.as_path(), json).map_err(|error| {
Error::FileIo { Error::FileIo {
error, error,
path: self.blueprint_path(), path: options.blueprint_path,
} }
.into() .into()
}) })
@ -444,6 +450,7 @@ where
&self, &self,
title: Option<&String>, title: Option<&String>,
stake_address: Option<&String>, stake_address: Option<&String>,
blueprint_path: &Path,
mainnet: bool, mainnet: bool,
) -> Result<ShelleyAddress, Error> { ) -> Result<ShelleyAddress, Error> {
// Parse stake address // Parse stake address
@ -465,7 +472,7 @@ where
}; };
// Read blueprint // Read blueprint
let blueprint = File::open(self.blueprint_path()) let blueprint = File::open(blueprint_path)
.map_err(|_| blueprint::error::Error::InvalidOrMissingFile)?; .map_err(|_| blueprint::error::Error::InvalidOrMissingFile)?;
let blueprint: Blueprint = serde_json::from_reader(BufReader::new(blueprint))?; let blueprint: Blueprint = serde_json::from_reader(BufReader::new(blueprint))?;
@ -502,9 +509,9 @@ where
}) })
} }
pub fn policy(&self, title: Option<&String>) -> Result<PolicyId, Error> { pub fn policy(&self, title: Option<&String>, blueprint_path: &Path) -> Result<PolicyId, Error> {
// Read blueprint // Read blueprint
let blueprint = File::open(self.blueprint_path()) let blueprint = File::open(blueprint_path)
.map_err(|_| blueprint::error::Error::InvalidOrMissingFile)?; .map_err(|_| blueprint::error::Error::InvalidOrMissingFile)?;
let blueprint: Blueprint = serde_json::from_reader(BufReader::new(blueprint))?; let blueprint: Blueprint = serde_json::from_reader(BufReader::new(blueprint))?;
@ -565,7 +572,7 @@ where
pub fn construct_parameter_incrementally<F>( pub fn construct_parameter_incrementally<F>(
&self, &self,
title: Option<&String>, title: Option<&String>,
blueprint_input: &Option<PathBuf>, blueprint_path: &Path,
ask: F, ask: F,
) -> Result<PlutusData, Error> ) -> Result<PlutusData, Error>
where where
@ -575,11 +582,6 @@ where
) -> Result<PlutusData, blueprint::error::Error>, ) -> Result<PlutusData, blueprint::error::Error>,
{ {
// Read blueprint // Read blueprint
let project_blueprint_path = self.blueprint_path();
let blueprint_path = blueprint_input
.as_ref()
.map(|p| p.as_path())
.unwrap_or_else(|| &project_blueprint_path);
let blueprint = File::open(blueprint_path) let blueprint = File::open(blueprint_path)
.map_err(|_| blueprint::error::Error::InvalidOrMissingFile)?; .map_err(|_| blueprint::error::Error::InvalidOrMissingFile)?;
let blueprint: Blueprint = serde_json::from_reader(BufReader::new(blueprint))?; let blueprint: Blueprint = serde_json::from_reader(BufReader::new(blueprint))?;
@ -601,10 +603,11 @@ where
pub fn apply_parameter( pub fn apply_parameter(
&self, &self,
title: Option<&String>, title: Option<&String>,
blueprint_path: &Path,
param: &PlutusData, param: &PlutusData,
) -> Result<Blueprint, Error> { ) -> Result<Blueprint, Error> {
// Read blueprint // Read blueprint
let blueprint = File::open(self.blueprint_path()) let blueprint = File::open(blueprint_path)
.map_err(|_| blueprint::error::Error::InvalidOrMissingFile)?; .map_err(|_| blueprint::error::Error::InvalidOrMissingFile)?;
let mut blueprint: Blueprint = serde_json::from_reader(BufReader::new(blueprint))?; let mut blueprint: Blueprint = serde_json::from_reader(BufReader::new(blueprint))?;

View File

@ -1,9 +1,11 @@
use aiken_lang::ast::Tracing; use aiken_lang::ast::Tracing;
use std::path::PathBuf;
pub struct Options { pub struct Options {
pub code_gen_mode: CodeGenMode, pub code_gen_mode: CodeGenMode,
pub tracing: Tracing, pub tracing: Tracing,
pub env: Option<String>, pub env: Option<String>,
pub blueprint_path: PathBuf,
} }
impl Default for Options { impl Default for Options {
@ -12,6 +14,7 @@ impl Default for Options {
code_gen_mode: CodeGenMode::NoOp, code_gen_mode: CodeGenMode::NoOp,
tracing: Tracing::silent(), tracing: Tracing::silent(),
env: None, env: None,
blueprint_path: PathBuf::from("plutus.json"),
} }
} }
} }

View File

@ -7,6 +7,18 @@ pub struct Args {
/// Path to project /// Path to project
directory: Option<PathBuf>, directory: Option<PathBuf>,
/// Optional path to the Plutus blueprint file to be used as input.
///
/// [default: plutus.json]
#[clap(
short,
long = "in",
value_parser,
value_name = "FILEPATH",
verbatim_doc_comment
)]
input: Option<PathBuf>,
/// Name of the validator's module within the project. Optional if there's only one validator /// Name of the validator's module within the project. Optional if there's only one validator
#[clap(short, long)] #[clap(short, long)]
module: Option<String>, module: Option<String>,
@ -27,6 +39,7 @@ pub struct Args {
pub fn exec( pub fn exec(
Args { Args {
directory, directory,
input,
module, module,
validator, validator,
delegated_to, delegated_to,
@ -46,7 +59,12 @@ pub fn exec(
let title = title.as_ref().or(validator.as_ref()); let title = title.as_ref().or(validator.as_ref());
let address = p.address(title, delegated_to.as_ref(), mainnet)?; let address = p.address(
title,
delegated_to.as_ref(),
p.blueprint_path(input.as_deref()).as_path(),
mainnet,
)?;
println!("{}", address.to_bech32().unwrap()); println!("{}", address.to_bech32().unwrap());

View File

@ -27,14 +27,22 @@ pub struct Args {
#[clap(value_name = "CBOR")] #[clap(value_name = "CBOR")]
parameter: Option<String>, parameter: Option<String>,
/// Optional path to the blueprint file to be used as input. Default to 'plutus.json' when /// Optional path to the blueprint file to be used as input.
/// omitted. ///
#[clap(short, long = "in", value_parser, value_name = "FILEPATH")] /// [default: plutus.json]
#[clap(
short,
long = "in",
value_parser,
value_name = "FILEPATH",
verbatim_doc_comment
)]
input: Option<PathBuf>, input: Option<PathBuf>,
/// Output file. Optional, print on stdout when omitted. /// Optional relative filepath to the generated Plutus blueprint. Default to printing to stdout
#[clap(short, long, value_name = "FILEPATH")] /// when omitted.
out: Option<PathBuf>, #[clap(short, long("out"), value_parser, value_name = "FILEPATH")]
output: Option<PathBuf>,
/// Name of the validator's module within the project. Optional if there's only one validator. /// Name of the validator's module within the project. Optional if there's only one validator.
#[clap(short, long)] #[clap(short, long)]
@ -49,7 +57,7 @@ pub fn exec(
Args { Args {
parameter, parameter,
input, input,
out, output,
module, module,
validator, validator,
}: Args, }: Args,
@ -74,6 +82,8 @@ pub fn exec(
.if_supports_color(Stderr, |s| s.bold()), .if_supports_color(Stderr, |s| s.bold()),
); );
let blueprint_input_path = p.blueprint_path(input.as_deref());
let data: PlutusData = match &parameter { let data: PlutusData = match &parameter {
Some(param) => { Some(param) => {
eprintln!( eprintln!(
@ -110,7 +120,9 @@ pub fn exec(
}) })
} }
None => p.construct_parameter_incrementally(title, &input, ask_schema)?, None => {
p.construct_parameter_incrementally(title, &blueprint_input_path, ask_schema)?
}
}; };
eprintln!( eprintln!(
@ -124,19 +136,22 @@ pub fn exec(
} }
); );
let blueprint = p.apply_parameter(title, &data)?; let blueprint = p.apply_parameter(title, &blueprint_input_path, &data)?;
let json = serde_json::to_string_pretty(&blueprint).unwrap(); let json = serde_json::to_string_pretty(&blueprint).unwrap();
match out { match output {
None => { None => {
println!("\n{}\n", json); println!("\n{}\n", json);
Ok(()) Ok(())
} }
Some(ref path) => fs::write(path, json).map_err(|error| Error::FileIo { Some(ref path) => {
let blueprint_output_path = p.blueprint_path(Some(path));
fs::write(&blueprint_output_path, json).map_err(|error| Error::FileIo {
error, error,
path: p.blueprint_path(), path: blueprint_output_path,
}), })
}
}?; }?;
eprintln!( eprintln!(

View File

@ -7,6 +7,18 @@ pub struct Args {
/// Path to project /// Path to project
directory: Option<PathBuf>, directory: Option<PathBuf>,
/// Optional path to the blueprint file to be used as input.
///
/// [default: plutus.json]
#[clap(
short,
long = "in",
value_parser,
value_name = "FILEPATH",
verbatim_doc_comment
)]
input: Option<PathBuf>,
/// Name of the validator's module within the project. Optional if there's only one validator /// Name of the validator's module within the project. Optional if there's only one validator
#[clap(short, long)] #[clap(short, long)]
module: Option<String>, module: Option<String>,
@ -19,6 +31,7 @@ pub struct Args {
pub fn exec( pub fn exec(
Args { Args {
directory, directory,
input,
module, module,
validator, validator,
}: Args, }: Args,
@ -36,7 +49,12 @@ pub fn exec(
let title = title.as_ref().or(validator.as_ref()); let title = title.as_ref().or(validator.as_ref());
let address = p.address(title, None, false)?; let address = p.address(
title,
None,
p.blueprint_path(input.as_deref()).as_path(),
false,
)?;
println!("{}", address.payment().to_hex()); println!("{}", address.payment().to_hex());

View File

@ -7,6 +7,18 @@ pub struct Args {
/// Path to project /// Path to project
directory: Option<PathBuf>, directory: Option<PathBuf>,
/// Optional path to the blueprint file to be used as input.
///
/// [default: plutus.json]
#[clap(
short,
long = "in",
value_parser,
value_name = "FILEPATH",
verbatim_doc_comment
)]
input: Option<PathBuf>,
/// Name of the validator's module within the project. Optional if there's only one validator /// Name of the validator's module within the project. Optional if there's only one validator
#[clap(short, long)] #[clap(short, long)]
module: Option<String>, module: Option<String>,
@ -19,6 +31,7 @@ pub struct Args {
pub fn exec( pub fn exec(
Args { Args {
directory, directory,
input,
module, module,
validator, validator,
}: Args, }: Args,
@ -36,7 +49,7 @@ pub fn exec(
let title = title.as_ref().or(validator.as_ref()); let title = title.as_ref().or(validator.as_ref());
let policy = p.policy(title)?; let policy = p.policy(title, p.blueprint_path(input.as_deref()).as_path())?;
println!("{}", policy); println!("{}", policy);

View File

@ -25,6 +25,18 @@ pub struct Args {
#[clap(long)] #[clap(long)]
env: Option<String>, env: Option<String>,
/// Optional relative filepath to the generated Plutus blueprint.
///
/// [default: plutus.json]
#[clap(
short,
long("out"),
value_parser,
value_name = "FILEPATH",
verbatim_doc_comment
)]
output: Option<PathBuf>,
/// Filter traces to be included in the generated program(s). /// Filter traces to be included in the generated program(s).
/// ///
/// - user-defined: /// - user-defined:
@ -67,6 +79,7 @@ pub fn exec(
uplc, uplc,
trace_filter, trace_filter,
trace_level, trace_level,
output,
env, env,
}: Args, }: Args,
) -> miette::Result<()> { ) -> miette::Result<()> {
@ -78,6 +91,7 @@ pub fn exec(
Some(trace_filter) => trace_filter(trace_level), Some(trace_filter) => trace_filter(trace_level),
None => Tracing::All(trace_level), None => Tracing::All(trace_level),
}, },
p.blueprint_path(output.as_deref()),
env.clone(), env.clone(),
) )
}) })
@ -89,6 +103,7 @@ pub fn exec(
Some(trace_filter) => trace_filter(trace_level), Some(trace_filter) => trace_filter(trace_level),
None => Tracing::All(trace_level), None => Tracing::All(trace_level),
}, },
p.blueprint_path(output.as_deref()),
env.clone(), env.clone(),
) )
}) })