Loading lcov.info +432 −425 Original line number Diff line number Diff line Loading @@ -370,63 +370,63 @@ LH:0 end_of_record TN: SF:/root/dev/command/pipe-lib/src/lib.rs FN:427,Command::test FN:450,Config::read FN:474,Config::read_json FN:495,Config::read_yaml FN:512,Config::set_environment_variables FN:526,<impl PartialEq for Details>::eq FN:533,EnvironmentValue::from_string FN:536,EnvironmentValue::from_value FN:544,EnvironmentValue::prepend_prefix FN:548,EnvironmentValue::trim_prefix FN:552,EnvironmentValue::get_from_config FN:559,EnvironmentValue::get_from_serde FN:573,EnvironmentValue::get_all FN:583,EnvironmentValue::print_all FN:588,EnvironmentValue::set_variable FN:598,EnvironmentValue::set_variables FN:605,Extension::from_string FN:614,Label::dry_run FN:618,Label::invalid FN:622,Label::fail FN:626,Label::found FN:630,Label::not_found FN:634,Label::output FN:638,Label::read FN:642,Label::rejected FN:646,Label::run FN:650,Label::using FN:656,ModuleUri<'_>::from FN:666,ModuleUri<'_>::hash FN:690,ModuleUri<'_>::get_whitelist FN:693,ModuleUri<'_>::is_allowed FN:696,ModuleUri<'_>::test FN:697,ModuleUri<'_>::test::check FN:714,ModuleUri<'_>::working_directory FN:726,SemanticVersion::from_string FN:749,Script::expand_arguments FN:784,Script::expand_arguments_from FN:819,Script::from_module FN:877,Script::from_path FN:900,Script::from_template FN:925,Script::get_command FN:935,Script::get_arguments FN:966,Script::maybe_create_virtual_environment FN:1003,Script::maybe_git_clone FN:1010,Script::python_default FN:1024,Script::run FN:1091,Script::with_container FN:1098,Script::with_current_dir FN:1103,Script::with_envs FN:1142,Script::with_virtual_environment FN:1151,StringTemplate::new FN:1160,StringTemplate::expand FN:1167,StringTemplate::get_variable FN:1197,StringTemplate::is_handlebars FN:1232,StringTemplate::remove_spaces FN:1242,add_dot_slash FN:1250,add_forward_slash FN:445,Command::test FN:468,Config::read FN:492,Config::read_json FN:513,Config::read_yaml FN:530,Config::set_environment_variables FN:544,<impl PartialEq for Details>::eq FN:551,EnvironmentValue::from_string FN:554,EnvironmentValue::from_value FN:562,EnvironmentValue::prepend_prefix FN:566,EnvironmentValue::trim_prefix FN:570,EnvironmentValue::get_from_config FN:577,EnvironmentValue::get_from_serde FN:591,EnvironmentValue::get_all FN:601,EnvironmentValue::print_all FN:606,EnvironmentValue::set_variable FN:616,EnvironmentValue::set_variables FN:623,Extension::from_string FN:632,Label::dry_run FN:636,Label::invalid FN:640,Label::fail FN:644,Label::found FN:648,Label::not_found FN:652,Label::output FN:656,Label::read FN:660,Label::rejected FN:664,Label::run FN:668,Label::using FN:674,ModuleUri<'_>::from FN:684,ModuleUri<'_>::hash FN:708,ModuleUri<'_>::get_whitelist FN:711,ModuleUri<'_>::is_allowed FN:714,ModuleUri<'_>::test FN:715,ModuleUri<'_>::test::check FN:732,ModuleUri<'_>::working_directory FN:744,SemanticVersion::from_string FN:767,Script::expand_arguments FN:802,Script::expand_arguments_from FN:837,Script::from_module FN:895,Script::from_path FN:918,Script::from_template FN:947,Script::get_command FN:957,Script::get_arguments FN:996,Script::maybe_create_virtual_environment FN:1033,Script::maybe_git_clone FN:1040,Script::python_default FN:1054,Script::run FN:1121,Script::with_container FN:1128,Script::with_current_dir FN:1133,Script::with_envs FN:1172,Script::with_virtual_environment FN:1181,StringTemplate::new FN:1190,StringTemplate::expand FN:1197,StringTemplate::get_variable FN:1227,StringTemplate::is_handlebars FN:1262,StringTemplate::remove_spaces FN:1272,add_dot_slash FN:1280,add_forward_slash FNF:57 FNDA:1,Command::test FNDA:1,Config::read Loading Loading @@ -478,458 +478,465 @@ FNDA:1,Script::with_container FNDA:1,Script::with_current_dir FNDA:0,Script::with_envs FNDA:1,Script::with_virtual_environment FNDA:1,StringTemplate::new FNDA:2,StringTemplate::new FNDA:1,StringTemplate::expand FNDA:1,StringTemplate::get_variable FNDA:1,StringTemplate::is_handlebars FNDA:2,StringTemplate::is_handlebars FNDA:1,StringTemplate::remove_spaces FNDA:1,add_dot_slash FNDA:1,add_forward_slash DA:427,1 DA:428,2 DA:429,1 DA:430,4 DA:431,4 DA:433,6 DA:434,2 DA:437,0 DA:438,0 DA:443,3 DA:444,1 DA:450,1 DA:451,2 DA:445,1 DA:446,2 DA:447,2 DA:448,6 DA:449,4 DA:451,6 DA:452,2 DA:453,1 DA:454,0 DA:456,2 DA:457,1 DA:458,0 DA:462,2 DA:463,1 DA:465,0 DA:466,0 DA:474,1 DA:475,2 DA:476,2 DA:478,0 DA:479,0 DA:482,3 DA:483,2 DA:484,4 DA:485,0 DA:487,6 DA:488,2 DA:495,1 DA:496,2 DA:497,1 DA:499,0 DA:500,0 DA:503,2 DA:504,1 DA:505,2 DA:506,0 DA:508,3 DA:509,1 DA:512,0 DA:513,0 DA:514,0 DA:515,0 DA:516,0 DA:455,0 DA:456,0 DA:461,3 DA:462,1 DA:468,1 DA:469,2 DA:470,2 DA:471,1 DA:472,0 DA:474,2 DA:475,1 DA:476,0 DA:480,2 DA:481,1 DA:483,0 DA:484,0 DA:492,1 DA:493,2 DA:494,2 DA:496,0 DA:497,0 DA:500,2 DA:501,2 DA:502,4 DA:503,0 DA:505,6 DA:506,2 DA:513,1 DA:514,2 DA:515,1 DA:517,0 DA:522,0 DA:526,1 DA:518,0 DA:521,2 DA:522,1 DA:523,2 DA:524,0 DA:526,3 DA:527,1 DA:530,0 DA:531,0 DA:532,0 DA:533,0 DA:534,0 DA:536,0 DA:537,0 DA:538,0 DA:539,0 DA:535,0 DA:540,0 DA:541,0 DA:544,0 DA:545,0 DA:548,1 DA:549,1 DA:550,2 DA:544,1 DA:545,1 DA:551,0 DA:552,0 DA:553,0 DA:554,0 DA:555,0 DA:556,0 DA:557,0 DA:558,0 DA:559,0 DA:560,0 DA:561,0 DA:562,0 DA:563,0 DA:564,0 DA:565,0 DA:566,0 DA:567,0 DA:569,0 DA:566,1 DA:567,1 DA:568,2 DA:570,0 DA:571,0 DA:573,1 DA:574,1 DA:575,2 DA:576,2 DA:577,2 DA:578,2 DA:579,1 DA:572,0 DA:573,0 DA:574,0 DA:575,0 DA:577,0 DA:578,0 DA:579,0 DA:580,0 DA:581,0 DA:582,0 DA:583,0 DA:584,0 DA:585,0 DA:588,0 DA:587,0 DA:589,0 DA:590,0 DA:591,0 DA:592,0 DA:593,0 DA:594,0 DA:598,0 DA:599,0 DA:591,1 DA:592,1 DA:593,2 DA:594,2 DA:595,2 DA:596,2 DA:597,1 DA:601,0 DA:605,1 DA:606,2 DA:607,2 DA:608,3 DA:602,0 DA:603,0 DA:606,0 DA:607,0 DA:608,0 DA:609,0 DA:614,0 DA:615,0 DA:610,0 DA:611,0 DA:612,0 DA:616,0 DA:618,0 DA:617,0 DA:619,0 DA:620,0 DA:622,0 DA:623,0 DA:624,0 DA:626,0 DA:623,1 DA:624,2 DA:625,2 DA:626,3 DA:627,0 DA:628,0 DA:630,0 DA:631,0 DA:632,0 DA:634,1 DA:635,3 DA:636,3 DA:633,0 DA:634,0 DA:636,0 DA:637,0 DA:638,0 DA:639,0 DA:640,0 DA:641,0 DA:642,0 DA:643,0 DA:644,0 DA:645,0 DA:646,0 DA:647,0 DA:648,0 DA:649,0 DA:650,0 DA:651,0 DA:652,0 DA:656,2 DA:657,2 DA:658,5 DA:659,2 DA:660,2 DA:652,1 DA:653,3 DA:654,3 DA:656,0 DA:657,0 DA:658,0 DA:660,0 DA:661,0 DA:663,1 DA:666,1 DA:667,1 DA:668,1 DA:669,1 DA:670,2 DA:671,0 DA:673,4 DA:677,4 DA:678,4 DA:680,4 DA:681,2 DA:683,2 DA:686,0 DA:690,0 DA:691,0 DA:693,0 DA:694,0 DA:696,0 DA:697,0 DA:698,0 DA:700,0 DA:701,0 DA:702,0 DA:703,0 DA:662,0 DA:664,0 DA:665,0 DA:666,0 DA:668,0 DA:669,0 DA:670,0 DA:674,2 DA:675,2 DA:676,5 DA:677,2 DA:678,2 DA:679,0 DA:681,1 DA:684,1 DA:685,1 DA:686,1 DA:687,1 DA:688,2 DA:689,0 DA:691,4 DA:695,4 DA:696,4 DA:698,4 DA:699,2 DA:701,2 DA:704,0 DA:705,0 DA:706,0 DA:708,0 DA:710,0 DA:709,0 DA:711,0 DA:712,0 DA:714,0 DA:715,0 DA:716,0 DA:717,0 DA:718,0 DA:719,0 DA:720,0 DA:721,0 DA:726,1 DA:727,1 DA:728,3 DA:729,3 DA:730,3 DA:749,1 DA:750,2 DA:753,2 DA:754,1 DA:755,2 DA:756,1 DA:757,1 DA:759,2 DA:763,1 DA:764,1 DA:784,1 DA:785,2 DA:788,2 DA:789,1 DA:790,2 DA:791,2 DA:794,2 DA:796,1 DA:798,2 DA:722,0 DA:723,0 DA:724,0 DA:726,0 DA:728,0 DA:732,0 DA:733,0 DA:734,0 DA:735,0 DA:736,0 DA:738,0 DA:739,0 DA:744,1 DA:745,1 DA:746,3 DA:747,3 DA:748,3 DA:767,1 DA:768,2 DA:771,2 DA:772,1 DA:773,2 DA:774,1 DA:775,1 DA:777,2 DA:781,1 DA:782,1 DA:802,1 DA:803,1 DA:819,0 DA:821,0 DA:822,0 DA:823,0 DA:826,0 DA:827,0 DA:828,0 DA:829,0 DA:830,0 DA:832,0 DA:833,0 DA:834,0 DA:803,2 DA:806,2 DA:807,1 DA:808,2 DA:809,2 DA:812,2 DA:814,1 DA:816,2 DA:820,1 DA:821,1 DA:837,0 DA:838,0 DA:839,0 DA:840,0 DA:843,0 DA:841,0 DA:844,0 DA:845,0 DA:846,0 DA:847,0 DA:848,0 DA:850,0 DA:851,0 DA:854,0 DA:860,0 DA:852,0 DA:855,0 DA:856,0 DA:857,0 DA:858,0 DA:861,0 DA:877,1 DA:878,2 DA:879,1 DA:881,0 DA:882,0 DA:885,2 DA:886,1 DA:887,1 DA:900,1 DA:901,1 DA:902,3 DA:906,2 DA:908,2 DA:910,2 DA:913,1 DA:914,1 DA:915,2 DA:916,1 DA:918,2 DA:862,0 DA:863,0 DA:866,0 DA:868,0 DA:869,0 DA:872,0 DA:878,0 DA:879,0 DA:895,1 DA:896,2 DA:897,1 DA:899,0 DA:900,0 DA:903,2 DA:904,1 DA:905,1 DA:918,1 DA:919,1 DA:920,1 DA:921,1 DA:923,1 DA:925,1 DA:926,1 DA:927,1 DA:928,1 DA:930,1 DA:931,2 DA:920,3 DA:924,2 DA:926,2 DA:928,2 DA:931,1 DA:932,1 DA:935,1 DA:933,2 DA:934,1 DA:936,1 DA:937,1 DA:938,1 DA:939,1 DA:940,1 DA:942,0 DA:943,0 DA:946,2 DA:941,1 DA:942,1 DA:943,1 DA:945,2 DA:947,1 DA:948,1 DA:949,1 DA:951,1 DA:950,1 DA:952,1 DA:953,1 DA:954,2 DA:955,2 DA:957,2 DA:953,2 DA:954,1 DA:957,1 DA:958,1 DA:959,1 DA:960,1 DA:961,1 DA:962,1 DA:963,0 DA:965,0 DA:966,0 DA:971,0 DA:972,0 DA:973,0 DA:975,0 DA:976,0 DA:977,0 DA:978,0 DA:979,0 DA:980,0 DA:982,0 DA:983,0 DA:969,2 DA:970,1 DA:972,1 DA:974,1 DA:975,1 DA:976,1 DA:977,2 DA:978,2 DA:980,1 DA:981,2 DA:982,2 DA:984,0 DA:985,0 DA:986,0 DA:987,0 DA:988,0 DA:990,0 DA:991,0 DA:994,0 DA:998,0 DA:999,0 DA:1003,1 DA:1004,2 DA:1005,2 DA:1006,2 DA:1007,3 DA:1008,1 DA:988,1 DA:989,1 DA:991,1 DA:996,0 DA:1001,0 DA:1002,0 DA:1003,0 DA:1005,0 DA:1006,0 DA:1007,0 DA:1008,0 DA:1009,0 DA:1010,0 DA:1011,0 DA:1012,0 DA:1013,0 DA:1014,0 DA:1015,0 DA:1016,0 DA:1017,0 DA:1018,0 DA:1020,0 DA:1024,1 DA:1025,1 DA:1026,1 DA:1027,2 DA:1028,2 DA:1029,3 DA:1030,1 DA:1031,7 DA:1032,2 DA:1021,0 DA:1024,0 DA:1028,0 DA:1029,0 DA:1033,1 DA:1034,1 DA:1035,1 DA:1036,1 DA:1041,2 DA:1042,1 DA:1044,0 DA:1045,0 DA:1048,1 DA:1049,1 DA:1050,2 DA:1051,2 DA:1054,2 DA:1034,2 DA:1035,2 DA:1036,2 DA:1037,3 DA:1038,1 DA:1040,0 DA:1041,0 DA:1042,0 DA:1050,0 DA:1054,1 DA:1055,1 DA:1057,0 DA:1058,0 DA:1061,1 DA:1062,1 DA:1063,2 DA:1064,0 DA:1065,0 DA:1068,2 DA:1069,1 DA:1070,3 DA:1071,1 DA:1072,3 DA:1073,3 DA:1074,1 DA:1076,0 DA:1077,0 DA:1078,0 DA:1081,0 DA:1082,0 DA:1083,0 DA:1056,1 DA:1057,2 DA:1058,2 DA:1059,3 DA:1060,1 DA:1061,7 DA:1062,2 DA:1063,1 DA:1064,1 DA:1065,1 DA:1066,1 DA:1071,2 DA:1072,1 DA:1074,0 DA:1075,0 DA:1078,1 DA:1079,1 DA:1080,2 DA:1081,2 DA:1084,2 DA:1085,1 DA:1087,0 DA:1088,0 DA:1091,1 DA:1092,1 DA:1093,1 DA:1098,1 DA:1099,2 DA:1100,1 DA:1103,0 DA:1104,0 DA:1105,0 DA:1142,1 DA:1143,1 DA:1144,1 DA:1151,1 DA:1153,1 DA:1160,1 DA:1161,4 DA:1162,3 DA:1167,1 DA:1168,2 DA:1169,2 DA:1170,1 DA:1171,2 DA:1173,0 DA:1093,2 DA:1094,0 DA:1095,0 DA:1098,2 DA:1099,1 DA:1100,3 DA:1101,1 DA:1102,3 DA:1103,3 DA:1104,1 DA:1106,0 DA:1107,0 DA:1108,0 DA:1111,0 DA:1112,0 DA:1113,0 DA:1117,0 DA:1118,0 DA:1121,1 DA:1122,1 DA:1123,1 DA:1128,1 DA:1129,2 DA:1130,1 DA:1133,0 DA:1134,0 DA:1135,0 DA:1172,1 DA:1173,1 DA:1174,1 DA:1181,2 DA:1183,2 DA:1190,1 DA:1191,6 DA:1192,5 DA:1197,1 DA:1198,2 DA:1199,2 DA:1200,1 DA:1201,0 DA:1201,2 DA:1203,0 DA:1232,1 DA:1233,2 DA:1234,1 DA:1235,0 DA:1237,3 DA:1238,1 DA:1242,1 DA:1243,2 DA:1244,2 DA:1246,3 DA:1250,1 DA:1251,2 DA:1252,0 DA:1254,2 DA:1267,1 DA:1268,2 DA:1269,2 DA:1270,2 DA:1271,2 DA:1272,5 DA:1275,1 DA:1277,2 DA:1279,4 DA:1227,2 DA:1228,4 DA:1229,4 DA:1230,2 DA:1231,0 DA:1233,0 DA:1262,1 DA:1263,2 DA:1264,1 DA:1265,0 DA:1267,3 DA:1268,1 DA:1272,1 DA:1273,2 DA:1274,2 DA:1276,3 DA:1280,1 DA:1281,2 DA:1282,0 DA:1309,1 DA:1310,1 DA:1311,1 DA:1312,6 DA:1324,1 DA:1326,0 DA:1284,2 DA:1297,1 DA:1298,2 DA:1299,2 DA:1300,2 DA:1301,2 DA:1302,5 DA:1305,1 DA:1307,2 DA:1309,4 DA:1312,0 DA:1339,1 DA:1340,1 DA:1341,1 DA:1342,1 DA:1345,1 DA:1346,3 DA:1358,1 DA:1359,1 DA:1362,0 DA:1363,0 DA:1364,0 DA:1366,0 DA:1370,0 DA:1371,0 DA:1372,0 DA:1374,0 DA:1388,2 DA:1389,2 DA:1390,6 DA:1391,4 DA:1392,12 DA:1393,8 DA:1395,1 DA:1396,3 DA:1397,1 DA:1400,1 DA:1402,1 DA:1403,4 LF:445 LH:245 DA:1342,6 DA:1354,1 DA:1356,0 DA:1371,1 DA:1372,1 DA:1375,1 DA:1376,3 DA:1388,1 DA:1389,1 DA:1392,0 DA:1393,0 DA:1394,0 DA:1396,0 DA:1400,0 DA:1401,0 DA:1402,0 DA:1404,0 DA:1418,2 DA:1419,2 DA:1420,6 DA:1421,4 DA:1422,12 DA:1423,8 DA:1425,1 DA:1426,3 DA:1427,1 DA:1430,1 DA:1432,1 DA:1433,4 LF:452 LH:249 end_of_record pipe-lib/src/lib.rs +40 −10 Original line number Diff line number Diff line Loading @@ -39,12 +39,16 @@ pub type Void = Result<(), Report>; pub type Output = Vec<Option<Details>>; #[derive(Clone, Debug, Display, Serialize, Deserialize, Valuable)] #[serde(rename_all = "lowercase")] pub enum ContainerRuntime { #[display("docker")] #[serde(alias = "Docker")] Docker, #[display("podman")] #[serde(alias = "Podman")] Podman, #[display("apptainer")] #[serde(alias = "Apptainer", alias = "Singularity", alias = "singularity")] Apptainer, #[display("unknown")] Unknown, Loading Loading @@ -175,12 +179,16 @@ pub enum TemplateAttribute { #[derive(Copy, Clone, Debug, Deserialize, Serialize)] pub enum TemplateType { /// Example: `"some <%= value %>"` #[serde(alias = "ejs")] EmbeddedJavaScript, /// Example: `"some <%= value %>"` #[serde(alias = "erb")] EmbeddedRuby, /// Example: `"some {{ value }}"` #[serde(alias = "handlebars", alias = "hbs")] Handlebars, /// Example: `"some {{ value }}"` #[serde(alias = "mustache")] Mustache, Unknown, } Loading @@ -188,16 +196,24 @@ pub enum TemplateType { pub enum VirtualEnvironmentManager { /// [Conda package manager](https://github.com/conda/conda) #[display("conda")] #[serde(alias = "conda")] Conda, /// Simple Python version management (https://github.com/pyenv/pyenv) #[display("pyenv")] #[serde(alias = "pyenv")] Pyenv, /// Tool to create isolated Python environments (https://virtualenv.pypa.io/en/latest/) #[display("venv")] #[serde(alias = "venv")] Virtualenv, /// [Pixi package manager](https://github.com/prefix-dev/pixi/) (that has functional parity with Conda) #[display("pixi")] #[serde(alias = "pixi")] Pixi, /// [Poetry](https://python-poetry.org/) - Python packaging and dependency management made easy #[display("poetry")] #[serde(alias = "poetry")] Poetry, #[display("unknown")] Unknown, } Loading Loading @@ -393,8 +409,10 @@ pub struct Script { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct ScriptTemplate { pub command: String, pub container: Option<ContainerEnvironment>, pub manager: Option<VirtualEnvironmentManager>, pub environment: Option<String>, #[serde(alias = "environment")] pub virtual_environment: Option<String>, pub arguments: Instruction, } #[derive(Clone, Debug, Deserialize, Serialize)] Loading Loading @@ -911,16 +929,20 @@ impl Script { .collect(), }; let manager = template.manager; let virtual_environment = match template.environment { let virtual_environment = match template.virtual_environment { | Some(name) => Some(VirtualEnvironment::init().name(name).maybe_manager(manager).build()), | None => None, }; let command = Command::init().name(template.command).build(); Script::init() .command(command) .arguments(arguments) .build() .with_virtual_environment(virtual_environment) let container = match template.container { | Some(value) => Some(value), | None => None, }; let command = Command::init() .name(template.command) .maybe_container(container) .maybe_virtual_environment(virtual_environment) .build(); Script::init().command(command).arguments(arguments).build() } fn get_command(&self) -> String { let name = match &self.command.virtual_environment { Loading @@ -938,6 +960,7 @@ impl Script { let mut arguments = match manager { | VirtualEnvironmentManager::Conda => to_string(vec!["run", "--name", name, "--no-capture-output", &self.command.name]), | VirtualEnvironmentManager::Pixi => to_string(vec!["run", "--environment", name, &self.command.name]), | VirtualEnvironmentManager::Poetry => to_string(vec!["run", &self.command.name]), | _ => { error!(name = manager.to_string(), "=> {} Virtual environment manager", Label::not_found()); vec![] Loading @@ -949,12 +972,19 @@ impl Script { | _ => self.arguments.clone(), }; match &self.command.container { | Some(ContainerEnvironment { name, .. }) => { | Some(ContainerEnvironment { name, runtime, .. }) => { let wrapped_command = match &self.command.virtual_environment { | Some(VirtualEnvironment { manager, .. }) => manager.to_string(), | _ => self.command.name.clone(), }; let mut arguments = to_string(vec!["run", "--rm", name, &wrapped_command]); let mut arguments = match runtime { | ContainerRuntime::Docker | ContainerRuntime::Podman => to_string(vec!["run", "--rm", name, &wrapped_command]), | ContainerRuntime::Apptainer => to_string(vec!["exec", name, &wrapped_command]), | ContainerRuntime::Unknown => { error!(name = runtime.to_string(), "=> {} Container runtime", Label::not_found()); vec![] } }; arguments.extend(self_arguments); arguments } Loading pipe-lib/src/tests.rs +39 −19 Original line number Diff line number Diff line Loading @@ -345,51 +345,53 @@ fn test_script_expand_arguments_from() { ("BAR".to_string(), "two".to_string()), ("BAZ".to_string(), "three".to_string()), ]); let script = Script::init().command(command).arguments(arguments).build(); assert_eq!( script let script = Script::init() .command(command) .arguments(arguments) .build() .clone() .expand_arguments_from(envs.clone()) .with_virtual_environment(None) .to_string(), "echo one two and three one two three one/three" ); .to_string(); assert_eq!(script, "echo one two and three one two three one/three"); } #[test] fn test_script_from_template() { let expected_value: Vec<String> = to_string(vec!["-m", "lib", "--input", "{{INPUT_DIRECTORY}}", "--output", "{{OUTPUT_DIRECTORY}}"]); // "shell" format arguments let path = PathBuf::from(format!("{}/template.json", FIXTURES)); let script = Script::from_path(path); let expected_value: Vec<String> = to_string(vec!["-m", "lib", "--input", "{{INPUT_DIRECTORY}}", "--output", "{{OUTPUT_DIRECTORY}}"]); assert_eq!(script.command.name, "python"); assert_eq!(script.arguments, expected_value); // "exec" format arguments let path = PathBuf::from(format!("{}/template_exec.json", FIXTURES)); let script = Script::from_path(path); assert_eq!( format!("{}", script), "conda run --name base --no-capture-output python -m lib --input {{INPUT_DIRECTORY}} --output {{OUTPUT_DIRECTORY}}" ); let expected = "conda run --name base --no-capture-output python -m lib --input {{INPUT_DIRECTORY}} --output {{OUTPUT_DIRECTORY}}"; assert_eq!(format!("{}", script), expected); assert_eq!(script.command.name, "python"); assert_eq!(script.arguments, expected_value); // Pixi virtual environment manager let path = PathBuf::from(format!("{}/template_pixi.json", FIXTURES)); let script = Script::from_path(path); assert_eq!( format!("{}", script), "pixi run --environment cuda python -m lib --input {{INPUT_DIRECTORY}} --output {{OUTPUT_DIRECTORY}}" ); let expected = "pixi run --environment cuda python -m lib --input {{INPUT_DIRECTORY}} --output {{OUTPUT_DIRECTORY}}"; assert_eq!(format!("{}", script), expected); // Docker + Pixi let path = PathBuf::from(format!("{}/template_docker_pixi.json", FIXTURES)); let script = Script::from_path(path); let expected = "docker run --rm CONTAINER pixi run --environment ENVIRONMENT python -m lib --method {{METHOD}} --profile {{PROFILE}}"; assert_eq!(format!("{}", script), expected); } #[test] fn test_script_get_arguments() { let command = Command::init().name("echo".to_string()).build(); let container = ContainerEnvironment::init().name("CONTAINER".to_string()).build(); let manager = VirtualEnvironmentManager::Conda; let virtual_environment = VirtualEnvironment::init().name("base".to_string()).manager(manager).build(); let container = ContainerEnvironment::init().name("CONTAINER".to_string()).build(); let arguments = to_string(vec!["hello", "world"]); let script = Script::init().command(command).arguments(arguments).build(); // Docker runtime (default) assert_eq!(format!("{}", script), "echo hello world"); assert_eq!( format!("{}", script.clone().with_virtual_environment(Some(virtual_environment.clone()))), Loading @@ -403,6 +405,24 @@ fn test_script_get_arguments() { format!("{}", script.with_container(container).with_virtual_environment(Some(virtual_environment))), "docker run --rm CONTAINER conda run --name base --no-capture-output echo hello world" ); // Docker runtime (default) let command = Command::init().name("echo".to_string()).build(); let container = ContainerEnvironment::init() .name("CONTAINER".to_string()) .runtime(ContainerRuntime::Apptainer) .build(); let manager = VirtualEnvironmentManager::Conda; let virtual_environment = VirtualEnvironment::init().name("base".to_string()).manager(manager).build(); let arguments = to_string(vec!["hello", "world"]); let script = Script::init().command(command).arguments(arguments).build(); assert_eq!( format!("{}", script.clone().with_container(container.clone())), "apptainer exec CONTAINER echo hello world" ); assert_eq!( format!("{}", script.with_container(container).with_virtual_environment(Some(virtual_environment))), "apptainer exec CONTAINER conda run --name base --no-capture-output echo hello world" ); } #[test] Loading tests/fixtures/template_docker_pixi.json 0 → 100644 +17 −0 Original line number Diff line number Diff line { "command": "python", "container": { "name": "CONTAINER", "runtime": "docker" }, "manager": "pixi", "environment": "ENVIRONMENT", "arguments": [ "-m", "lib", "--method", "{{ METHOD }}", "--profile", "{{ PROFILE }}" ] } No newline at end of file Loading
lcov.info +432 −425 Original line number Diff line number Diff line Loading @@ -370,63 +370,63 @@ LH:0 end_of_record TN: SF:/root/dev/command/pipe-lib/src/lib.rs FN:427,Command::test FN:450,Config::read FN:474,Config::read_json FN:495,Config::read_yaml FN:512,Config::set_environment_variables FN:526,<impl PartialEq for Details>::eq FN:533,EnvironmentValue::from_string FN:536,EnvironmentValue::from_value FN:544,EnvironmentValue::prepend_prefix FN:548,EnvironmentValue::trim_prefix FN:552,EnvironmentValue::get_from_config FN:559,EnvironmentValue::get_from_serde FN:573,EnvironmentValue::get_all FN:583,EnvironmentValue::print_all FN:588,EnvironmentValue::set_variable FN:598,EnvironmentValue::set_variables FN:605,Extension::from_string FN:614,Label::dry_run FN:618,Label::invalid FN:622,Label::fail FN:626,Label::found FN:630,Label::not_found FN:634,Label::output FN:638,Label::read FN:642,Label::rejected FN:646,Label::run FN:650,Label::using FN:656,ModuleUri<'_>::from FN:666,ModuleUri<'_>::hash FN:690,ModuleUri<'_>::get_whitelist FN:693,ModuleUri<'_>::is_allowed FN:696,ModuleUri<'_>::test FN:697,ModuleUri<'_>::test::check FN:714,ModuleUri<'_>::working_directory FN:726,SemanticVersion::from_string FN:749,Script::expand_arguments FN:784,Script::expand_arguments_from FN:819,Script::from_module FN:877,Script::from_path FN:900,Script::from_template FN:925,Script::get_command FN:935,Script::get_arguments FN:966,Script::maybe_create_virtual_environment FN:1003,Script::maybe_git_clone FN:1010,Script::python_default FN:1024,Script::run FN:1091,Script::with_container FN:1098,Script::with_current_dir FN:1103,Script::with_envs FN:1142,Script::with_virtual_environment FN:1151,StringTemplate::new FN:1160,StringTemplate::expand FN:1167,StringTemplate::get_variable FN:1197,StringTemplate::is_handlebars FN:1232,StringTemplate::remove_spaces FN:1242,add_dot_slash FN:1250,add_forward_slash FN:445,Command::test FN:468,Config::read FN:492,Config::read_json FN:513,Config::read_yaml FN:530,Config::set_environment_variables FN:544,<impl PartialEq for Details>::eq FN:551,EnvironmentValue::from_string FN:554,EnvironmentValue::from_value FN:562,EnvironmentValue::prepend_prefix FN:566,EnvironmentValue::trim_prefix FN:570,EnvironmentValue::get_from_config FN:577,EnvironmentValue::get_from_serde FN:591,EnvironmentValue::get_all FN:601,EnvironmentValue::print_all FN:606,EnvironmentValue::set_variable FN:616,EnvironmentValue::set_variables FN:623,Extension::from_string FN:632,Label::dry_run FN:636,Label::invalid FN:640,Label::fail FN:644,Label::found FN:648,Label::not_found FN:652,Label::output FN:656,Label::read FN:660,Label::rejected FN:664,Label::run FN:668,Label::using FN:674,ModuleUri<'_>::from FN:684,ModuleUri<'_>::hash FN:708,ModuleUri<'_>::get_whitelist FN:711,ModuleUri<'_>::is_allowed FN:714,ModuleUri<'_>::test FN:715,ModuleUri<'_>::test::check FN:732,ModuleUri<'_>::working_directory FN:744,SemanticVersion::from_string FN:767,Script::expand_arguments FN:802,Script::expand_arguments_from FN:837,Script::from_module FN:895,Script::from_path FN:918,Script::from_template FN:947,Script::get_command FN:957,Script::get_arguments FN:996,Script::maybe_create_virtual_environment FN:1033,Script::maybe_git_clone FN:1040,Script::python_default FN:1054,Script::run FN:1121,Script::with_container FN:1128,Script::with_current_dir FN:1133,Script::with_envs FN:1172,Script::with_virtual_environment FN:1181,StringTemplate::new FN:1190,StringTemplate::expand FN:1197,StringTemplate::get_variable FN:1227,StringTemplate::is_handlebars FN:1262,StringTemplate::remove_spaces FN:1272,add_dot_slash FN:1280,add_forward_slash FNF:57 FNDA:1,Command::test FNDA:1,Config::read Loading Loading @@ -478,458 +478,465 @@ FNDA:1,Script::with_container FNDA:1,Script::with_current_dir FNDA:0,Script::with_envs FNDA:1,Script::with_virtual_environment FNDA:1,StringTemplate::new FNDA:2,StringTemplate::new FNDA:1,StringTemplate::expand FNDA:1,StringTemplate::get_variable FNDA:1,StringTemplate::is_handlebars FNDA:2,StringTemplate::is_handlebars FNDA:1,StringTemplate::remove_spaces FNDA:1,add_dot_slash FNDA:1,add_forward_slash DA:427,1 DA:428,2 DA:429,1 DA:430,4 DA:431,4 DA:433,6 DA:434,2 DA:437,0 DA:438,0 DA:443,3 DA:444,1 DA:450,1 DA:451,2 DA:445,1 DA:446,2 DA:447,2 DA:448,6 DA:449,4 DA:451,6 DA:452,2 DA:453,1 DA:454,0 DA:456,2 DA:457,1 DA:458,0 DA:462,2 DA:463,1 DA:465,0 DA:466,0 DA:474,1 DA:475,2 DA:476,2 DA:478,0 DA:479,0 DA:482,3 DA:483,2 DA:484,4 DA:485,0 DA:487,6 DA:488,2 DA:495,1 DA:496,2 DA:497,1 DA:499,0 DA:500,0 DA:503,2 DA:504,1 DA:505,2 DA:506,0 DA:508,3 DA:509,1 DA:512,0 DA:513,0 DA:514,0 DA:515,0 DA:516,0 DA:455,0 DA:456,0 DA:461,3 DA:462,1 DA:468,1 DA:469,2 DA:470,2 DA:471,1 DA:472,0 DA:474,2 DA:475,1 DA:476,0 DA:480,2 DA:481,1 DA:483,0 DA:484,0 DA:492,1 DA:493,2 DA:494,2 DA:496,0 DA:497,0 DA:500,2 DA:501,2 DA:502,4 DA:503,0 DA:505,6 DA:506,2 DA:513,1 DA:514,2 DA:515,1 DA:517,0 DA:522,0 DA:526,1 DA:518,0 DA:521,2 DA:522,1 DA:523,2 DA:524,0 DA:526,3 DA:527,1 DA:530,0 DA:531,0 DA:532,0 DA:533,0 DA:534,0 DA:536,0 DA:537,0 DA:538,0 DA:539,0 DA:535,0 DA:540,0 DA:541,0 DA:544,0 DA:545,0 DA:548,1 DA:549,1 DA:550,2 DA:544,1 DA:545,1 DA:551,0 DA:552,0 DA:553,0 DA:554,0 DA:555,0 DA:556,0 DA:557,0 DA:558,0 DA:559,0 DA:560,0 DA:561,0 DA:562,0 DA:563,0 DA:564,0 DA:565,0 DA:566,0 DA:567,0 DA:569,0 DA:566,1 DA:567,1 DA:568,2 DA:570,0 DA:571,0 DA:573,1 DA:574,1 DA:575,2 DA:576,2 DA:577,2 DA:578,2 DA:579,1 DA:572,0 DA:573,0 DA:574,0 DA:575,0 DA:577,0 DA:578,0 DA:579,0 DA:580,0 DA:581,0 DA:582,0 DA:583,0 DA:584,0 DA:585,0 DA:588,0 DA:587,0 DA:589,0 DA:590,0 DA:591,0 DA:592,0 DA:593,0 DA:594,0 DA:598,0 DA:599,0 DA:591,1 DA:592,1 DA:593,2 DA:594,2 DA:595,2 DA:596,2 DA:597,1 DA:601,0 DA:605,1 DA:606,2 DA:607,2 DA:608,3 DA:602,0 DA:603,0 DA:606,0 DA:607,0 DA:608,0 DA:609,0 DA:614,0 DA:615,0 DA:610,0 DA:611,0 DA:612,0 DA:616,0 DA:618,0 DA:617,0 DA:619,0 DA:620,0 DA:622,0 DA:623,0 DA:624,0 DA:626,0 DA:623,1 DA:624,2 DA:625,2 DA:626,3 DA:627,0 DA:628,0 DA:630,0 DA:631,0 DA:632,0 DA:634,1 DA:635,3 DA:636,3 DA:633,0 DA:634,0 DA:636,0 DA:637,0 DA:638,0 DA:639,0 DA:640,0 DA:641,0 DA:642,0 DA:643,0 DA:644,0 DA:645,0 DA:646,0 DA:647,0 DA:648,0 DA:649,0 DA:650,0 DA:651,0 DA:652,0 DA:656,2 DA:657,2 DA:658,5 DA:659,2 DA:660,2 DA:652,1 DA:653,3 DA:654,3 DA:656,0 DA:657,0 DA:658,0 DA:660,0 DA:661,0 DA:663,1 DA:666,1 DA:667,1 DA:668,1 DA:669,1 DA:670,2 DA:671,0 DA:673,4 DA:677,4 DA:678,4 DA:680,4 DA:681,2 DA:683,2 DA:686,0 DA:690,0 DA:691,0 DA:693,0 DA:694,0 DA:696,0 DA:697,0 DA:698,0 DA:700,0 DA:701,0 DA:702,0 DA:703,0 DA:662,0 DA:664,0 DA:665,0 DA:666,0 DA:668,0 DA:669,0 DA:670,0 DA:674,2 DA:675,2 DA:676,5 DA:677,2 DA:678,2 DA:679,0 DA:681,1 DA:684,1 DA:685,1 DA:686,1 DA:687,1 DA:688,2 DA:689,0 DA:691,4 DA:695,4 DA:696,4 DA:698,4 DA:699,2 DA:701,2 DA:704,0 DA:705,0 DA:706,0 DA:708,0 DA:710,0 DA:709,0 DA:711,0 DA:712,0 DA:714,0 DA:715,0 DA:716,0 DA:717,0 DA:718,0 DA:719,0 DA:720,0 DA:721,0 DA:726,1 DA:727,1 DA:728,3 DA:729,3 DA:730,3 DA:749,1 DA:750,2 DA:753,2 DA:754,1 DA:755,2 DA:756,1 DA:757,1 DA:759,2 DA:763,1 DA:764,1 DA:784,1 DA:785,2 DA:788,2 DA:789,1 DA:790,2 DA:791,2 DA:794,2 DA:796,1 DA:798,2 DA:722,0 DA:723,0 DA:724,0 DA:726,0 DA:728,0 DA:732,0 DA:733,0 DA:734,0 DA:735,0 DA:736,0 DA:738,0 DA:739,0 DA:744,1 DA:745,1 DA:746,3 DA:747,3 DA:748,3 DA:767,1 DA:768,2 DA:771,2 DA:772,1 DA:773,2 DA:774,1 DA:775,1 DA:777,2 DA:781,1 DA:782,1 DA:802,1 DA:803,1 DA:819,0 DA:821,0 DA:822,0 DA:823,0 DA:826,0 DA:827,0 DA:828,0 DA:829,0 DA:830,0 DA:832,0 DA:833,0 DA:834,0 DA:803,2 DA:806,2 DA:807,1 DA:808,2 DA:809,2 DA:812,2 DA:814,1 DA:816,2 DA:820,1 DA:821,1 DA:837,0 DA:838,0 DA:839,0 DA:840,0 DA:843,0 DA:841,0 DA:844,0 DA:845,0 DA:846,0 DA:847,0 DA:848,0 DA:850,0 DA:851,0 DA:854,0 DA:860,0 DA:852,0 DA:855,0 DA:856,0 DA:857,0 DA:858,0 DA:861,0 DA:877,1 DA:878,2 DA:879,1 DA:881,0 DA:882,0 DA:885,2 DA:886,1 DA:887,1 DA:900,1 DA:901,1 DA:902,3 DA:906,2 DA:908,2 DA:910,2 DA:913,1 DA:914,1 DA:915,2 DA:916,1 DA:918,2 DA:862,0 DA:863,0 DA:866,0 DA:868,0 DA:869,0 DA:872,0 DA:878,0 DA:879,0 DA:895,1 DA:896,2 DA:897,1 DA:899,0 DA:900,0 DA:903,2 DA:904,1 DA:905,1 DA:918,1 DA:919,1 DA:920,1 DA:921,1 DA:923,1 DA:925,1 DA:926,1 DA:927,1 DA:928,1 DA:930,1 DA:931,2 DA:920,3 DA:924,2 DA:926,2 DA:928,2 DA:931,1 DA:932,1 DA:935,1 DA:933,2 DA:934,1 DA:936,1 DA:937,1 DA:938,1 DA:939,1 DA:940,1 DA:942,0 DA:943,0 DA:946,2 DA:941,1 DA:942,1 DA:943,1 DA:945,2 DA:947,1 DA:948,1 DA:949,1 DA:951,1 DA:950,1 DA:952,1 DA:953,1 DA:954,2 DA:955,2 DA:957,2 DA:953,2 DA:954,1 DA:957,1 DA:958,1 DA:959,1 DA:960,1 DA:961,1 DA:962,1 DA:963,0 DA:965,0 DA:966,0 DA:971,0 DA:972,0 DA:973,0 DA:975,0 DA:976,0 DA:977,0 DA:978,0 DA:979,0 DA:980,0 DA:982,0 DA:983,0 DA:969,2 DA:970,1 DA:972,1 DA:974,1 DA:975,1 DA:976,1 DA:977,2 DA:978,2 DA:980,1 DA:981,2 DA:982,2 DA:984,0 DA:985,0 DA:986,0 DA:987,0 DA:988,0 DA:990,0 DA:991,0 DA:994,0 DA:998,0 DA:999,0 DA:1003,1 DA:1004,2 DA:1005,2 DA:1006,2 DA:1007,3 DA:1008,1 DA:988,1 DA:989,1 DA:991,1 DA:996,0 DA:1001,0 DA:1002,0 DA:1003,0 DA:1005,0 DA:1006,0 DA:1007,0 DA:1008,0 DA:1009,0 DA:1010,0 DA:1011,0 DA:1012,0 DA:1013,0 DA:1014,0 DA:1015,0 DA:1016,0 DA:1017,0 DA:1018,0 DA:1020,0 DA:1024,1 DA:1025,1 DA:1026,1 DA:1027,2 DA:1028,2 DA:1029,3 DA:1030,1 DA:1031,7 DA:1032,2 DA:1021,0 DA:1024,0 DA:1028,0 DA:1029,0 DA:1033,1 DA:1034,1 DA:1035,1 DA:1036,1 DA:1041,2 DA:1042,1 DA:1044,0 DA:1045,0 DA:1048,1 DA:1049,1 DA:1050,2 DA:1051,2 DA:1054,2 DA:1034,2 DA:1035,2 DA:1036,2 DA:1037,3 DA:1038,1 DA:1040,0 DA:1041,0 DA:1042,0 DA:1050,0 DA:1054,1 DA:1055,1 DA:1057,0 DA:1058,0 DA:1061,1 DA:1062,1 DA:1063,2 DA:1064,0 DA:1065,0 DA:1068,2 DA:1069,1 DA:1070,3 DA:1071,1 DA:1072,3 DA:1073,3 DA:1074,1 DA:1076,0 DA:1077,0 DA:1078,0 DA:1081,0 DA:1082,0 DA:1083,0 DA:1056,1 DA:1057,2 DA:1058,2 DA:1059,3 DA:1060,1 DA:1061,7 DA:1062,2 DA:1063,1 DA:1064,1 DA:1065,1 DA:1066,1 DA:1071,2 DA:1072,1 DA:1074,0 DA:1075,0 DA:1078,1 DA:1079,1 DA:1080,2 DA:1081,2 DA:1084,2 DA:1085,1 DA:1087,0 DA:1088,0 DA:1091,1 DA:1092,1 DA:1093,1 DA:1098,1 DA:1099,2 DA:1100,1 DA:1103,0 DA:1104,0 DA:1105,0 DA:1142,1 DA:1143,1 DA:1144,1 DA:1151,1 DA:1153,1 DA:1160,1 DA:1161,4 DA:1162,3 DA:1167,1 DA:1168,2 DA:1169,2 DA:1170,1 DA:1171,2 DA:1173,0 DA:1093,2 DA:1094,0 DA:1095,0 DA:1098,2 DA:1099,1 DA:1100,3 DA:1101,1 DA:1102,3 DA:1103,3 DA:1104,1 DA:1106,0 DA:1107,0 DA:1108,0 DA:1111,0 DA:1112,0 DA:1113,0 DA:1117,0 DA:1118,0 DA:1121,1 DA:1122,1 DA:1123,1 DA:1128,1 DA:1129,2 DA:1130,1 DA:1133,0 DA:1134,0 DA:1135,0 DA:1172,1 DA:1173,1 DA:1174,1 DA:1181,2 DA:1183,2 DA:1190,1 DA:1191,6 DA:1192,5 DA:1197,1 DA:1198,2 DA:1199,2 DA:1200,1 DA:1201,0 DA:1201,2 DA:1203,0 DA:1232,1 DA:1233,2 DA:1234,1 DA:1235,0 DA:1237,3 DA:1238,1 DA:1242,1 DA:1243,2 DA:1244,2 DA:1246,3 DA:1250,1 DA:1251,2 DA:1252,0 DA:1254,2 DA:1267,1 DA:1268,2 DA:1269,2 DA:1270,2 DA:1271,2 DA:1272,5 DA:1275,1 DA:1277,2 DA:1279,4 DA:1227,2 DA:1228,4 DA:1229,4 DA:1230,2 DA:1231,0 DA:1233,0 DA:1262,1 DA:1263,2 DA:1264,1 DA:1265,0 DA:1267,3 DA:1268,1 DA:1272,1 DA:1273,2 DA:1274,2 DA:1276,3 DA:1280,1 DA:1281,2 DA:1282,0 DA:1309,1 DA:1310,1 DA:1311,1 DA:1312,6 DA:1324,1 DA:1326,0 DA:1284,2 DA:1297,1 DA:1298,2 DA:1299,2 DA:1300,2 DA:1301,2 DA:1302,5 DA:1305,1 DA:1307,2 DA:1309,4 DA:1312,0 DA:1339,1 DA:1340,1 DA:1341,1 DA:1342,1 DA:1345,1 DA:1346,3 DA:1358,1 DA:1359,1 DA:1362,0 DA:1363,0 DA:1364,0 DA:1366,0 DA:1370,0 DA:1371,0 DA:1372,0 DA:1374,0 DA:1388,2 DA:1389,2 DA:1390,6 DA:1391,4 DA:1392,12 DA:1393,8 DA:1395,1 DA:1396,3 DA:1397,1 DA:1400,1 DA:1402,1 DA:1403,4 LF:445 LH:245 DA:1342,6 DA:1354,1 DA:1356,0 DA:1371,1 DA:1372,1 DA:1375,1 DA:1376,3 DA:1388,1 DA:1389,1 DA:1392,0 DA:1393,0 DA:1394,0 DA:1396,0 DA:1400,0 DA:1401,0 DA:1402,0 DA:1404,0 DA:1418,2 DA:1419,2 DA:1420,6 DA:1421,4 DA:1422,12 DA:1423,8 DA:1425,1 DA:1426,3 DA:1427,1 DA:1430,1 DA:1432,1 DA:1433,4 LF:452 LH:249 end_of_record
pipe-lib/src/lib.rs +40 −10 Original line number Diff line number Diff line Loading @@ -39,12 +39,16 @@ pub type Void = Result<(), Report>; pub type Output = Vec<Option<Details>>; #[derive(Clone, Debug, Display, Serialize, Deserialize, Valuable)] #[serde(rename_all = "lowercase")] pub enum ContainerRuntime { #[display("docker")] #[serde(alias = "Docker")] Docker, #[display("podman")] #[serde(alias = "Podman")] Podman, #[display("apptainer")] #[serde(alias = "Apptainer", alias = "Singularity", alias = "singularity")] Apptainer, #[display("unknown")] Unknown, Loading Loading @@ -175,12 +179,16 @@ pub enum TemplateAttribute { #[derive(Copy, Clone, Debug, Deserialize, Serialize)] pub enum TemplateType { /// Example: `"some <%= value %>"` #[serde(alias = "ejs")] EmbeddedJavaScript, /// Example: `"some <%= value %>"` #[serde(alias = "erb")] EmbeddedRuby, /// Example: `"some {{ value }}"` #[serde(alias = "handlebars", alias = "hbs")] Handlebars, /// Example: `"some {{ value }}"` #[serde(alias = "mustache")] Mustache, Unknown, } Loading @@ -188,16 +196,24 @@ pub enum TemplateType { pub enum VirtualEnvironmentManager { /// [Conda package manager](https://github.com/conda/conda) #[display("conda")] #[serde(alias = "conda")] Conda, /// Simple Python version management (https://github.com/pyenv/pyenv) #[display("pyenv")] #[serde(alias = "pyenv")] Pyenv, /// Tool to create isolated Python environments (https://virtualenv.pypa.io/en/latest/) #[display("venv")] #[serde(alias = "venv")] Virtualenv, /// [Pixi package manager](https://github.com/prefix-dev/pixi/) (that has functional parity with Conda) #[display("pixi")] #[serde(alias = "pixi")] Pixi, /// [Poetry](https://python-poetry.org/) - Python packaging and dependency management made easy #[display("poetry")] #[serde(alias = "poetry")] Poetry, #[display("unknown")] Unknown, } Loading Loading @@ -393,8 +409,10 @@ pub struct Script { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct ScriptTemplate { pub command: String, pub container: Option<ContainerEnvironment>, pub manager: Option<VirtualEnvironmentManager>, pub environment: Option<String>, #[serde(alias = "environment")] pub virtual_environment: Option<String>, pub arguments: Instruction, } #[derive(Clone, Debug, Deserialize, Serialize)] Loading Loading @@ -911,16 +929,20 @@ impl Script { .collect(), }; let manager = template.manager; let virtual_environment = match template.environment { let virtual_environment = match template.virtual_environment { | Some(name) => Some(VirtualEnvironment::init().name(name).maybe_manager(manager).build()), | None => None, }; let command = Command::init().name(template.command).build(); Script::init() .command(command) .arguments(arguments) .build() .with_virtual_environment(virtual_environment) let container = match template.container { | Some(value) => Some(value), | None => None, }; let command = Command::init() .name(template.command) .maybe_container(container) .maybe_virtual_environment(virtual_environment) .build(); Script::init().command(command).arguments(arguments).build() } fn get_command(&self) -> String { let name = match &self.command.virtual_environment { Loading @@ -938,6 +960,7 @@ impl Script { let mut arguments = match manager { | VirtualEnvironmentManager::Conda => to_string(vec!["run", "--name", name, "--no-capture-output", &self.command.name]), | VirtualEnvironmentManager::Pixi => to_string(vec!["run", "--environment", name, &self.command.name]), | VirtualEnvironmentManager::Poetry => to_string(vec!["run", &self.command.name]), | _ => { error!(name = manager.to_string(), "=> {} Virtual environment manager", Label::not_found()); vec![] Loading @@ -949,12 +972,19 @@ impl Script { | _ => self.arguments.clone(), }; match &self.command.container { | Some(ContainerEnvironment { name, .. }) => { | Some(ContainerEnvironment { name, runtime, .. }) => { let wrapped_command = match &self.command.virtual_environment { | Some(VirtualEnvironment { manager, .. }) => manager.to_string(), | _ => self.command.name.clone(), }; let mut arguments = to_string(vec!["run", "--rm", name, &wrapped_command]); let mut arguments = match runtime { | ContainerRuntime::Docker | ContainerRuntime::Podman => to_string(vec!["run", "--rm", name, &wrapped_command]), | ContainerRuntime::Apptainer => to_string(vec!["exec", name, &wrapped_command]), | ContainerRuntime::Unknown => { error!(name = runtime.to_string(), "=> {} Container runtime", Label::not_found()); vec![] } }; arguments.extend(self_arguments); arguments } Loading
pipe-lib/src/tests.rs +39 −19 Original line number Diff line number Diff line Loading @@ -345,51 +345,53 @@ fn test_script_expand_arguments_from() { ("BAR".to_string(), "two".to_string()), ("BAZ".to_string(), "three".to_string()), ]); let script = Script::init().command(command).arguments(arguments).build(); assert_eq!( script let script = Script::init() .command(command) .arguments(arguments) .build() .clone() .expand_arguments_from(envs.clone()) .with_virtual_environment(None) .to_string(), "echo one two and three one two three one/three" ); .to_string(); assert_eq!(script, "echo one two and three one two three one/three"); } #[test] fn test_script_from_template() { let expected_value: Vec<String> = to_string(vec!["-m", "lib", "--input", "{{INPUT_DIRECTORY}}", "--output", "{{OUTPUT_DIRECTORY}}"]); // "shell" format arguments let path = PathBuf::from(format!("{}/template.json", FIXTURES)); let script = Script::from_path(path); let expected_value: Vec<String> = to_string(vec!["-m", "lib", "--input", "{{INPUT_DIRECTORY}}", "--output", "{{OUTPUT_DIRECTORY}}"]); assert_eq!(script.command.name, "python"); assert_eq!(script.arguments, expected_value); // "exec" format arguments let path = PathBuf::from(format!("{}/template_exec.json", FIXTURES)); let script = Script::from_path(path); assert_eq!( format!("{}", script), "conda run --name base --no-capture-output python -m lib --input {{INPUT_DIRECTORY}} --output {{OUTPUT_DIRECTORY}}" ); let expected = "conda run --name base --no-capture-output python -m lib --input {{INPUT_DIRECTORY}} --output {{OUTPUT_DIRECTORY}}"; assert_eq!(format!("{}", script), expected); assert_eq!(script.command.name, "python"); assert_eq!(script.arguments, expected_value); // Pixi virtual environment manager let path = PathBuf::from(format!("{}/template_pixi.json", FIXTURES)); let script = Script::from_path(path); assert_eq!( format!("{}", script), "pixi run --environment cuda python -m lib --input {{INPUT_DIRECTORY}} --output {{OUTPUT_DIRECTORY}}" ); let expected = "pixi run --environment cuda python -m lib --input {{INPUT_DIRECTORY}} --output {{OUTPUT_DIRECTORY}}"; assert_eq!(format!("{}", script), expected); // Docker + Pixi let path = PathBuf::from(format!("{}/template_docker_pixi.json", FIXTURES)); let script = Script::from_path(path); let expected = "docker run --rm CONTAINER pixi run --environment ENVIRONMENT python -m lib --method {{METHOD}} --profile {{PROFILE}}"; assert_eq!(format!("{}", script), expected); } #[test] fn test_script_get_arguments() { let command = Command::init().name("echo".to_string()).build(); let container = ContainerEnvironment::init().name("CONTAINER".to_string()).build(); let manager = VirtualEnvironmentManager::Conda; let virtual_environment = VirtualEnvironment::init().name("base".to_string()).manager(manager).build(); let container = ContainerEnvironment::init().name("CONTAINER".to_string()).build(); let arguments = to_string(vec!["hello", "world"]); let script = Script::init().command(command).arguments(arguments).build(); // Docker runtime (default) assert_eq!(format!("{}", script), "echo hello world"); assert_eq!( format!("{}", script.clone().with_virtual_environment(Some(virtual_environment.clone()))), Loading @@ -403,6 +405,24 @@ fn test_script_get_arguments() { format!("{}", script.with_container(container).with_virtual_environment(Some(virtual_environment))), "docker run --rm CONTAINER conda run --name base --no-capture-output echo hello world" ); // Docker runtime (default) let command = Command::init().name("echo".to_string()).build(); let container = ContainerEnvironment::init() .name("CONTAINER".to_string()) .runtime(ContainerRuntime::Apptainer) .build(); let manager = VirtualEnvironmentManager::Conda; let virtual_environment = VirtualEnvironment::init().name("base".to_string()).manager(manager).build(); let arguments = to_string(vec!["hello", "world"]); let script = Script::init().command(command).arguments(arguments).build(); assert_eq!( format!("{}", script.clone().with_container(container.clone())), "apptainer exec CONTAINER echo hello world" ); assert_eq!( format!("{}", script.with_container(container).with_virtual_environment(Some(virtual_environment))), "apptainer exec CONTAINER conda run --name base --no-capture-output echo hello world" ); } #[test] Loading
tests/fixtures/template_docker_pixi.json 0 → 100644 +17 −0 Original line number Diff line number Diff line { "command": "python", "container": { "name": "CONTAINER", "runtime": "docker" }, "manager": "pixi", "environment": "ENVIRONMENT", "arguments": [ "-m", "lib", "--method", "{{ METHOD }}", "--profile", "{{ PROFILE }}" ] } No newline at end of file