summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorMatthias Beyer <matthias.beyer@atos.net>2021-06-11 10:22:36 +0200
committerMatthias Beyer <matthias.beyer@atos.net>2021-06-16 13:16:27 +0200
commitab5805d24fe3c35b25495cf9a9e9f7618a590b48 (patch)
treea3adb98895b3a426698e82786a0ab9090624bc74 /src/ui
parent2ebb3a00aca2eaaea5f182b1f72e21c09fcba6ee (diff)
Move module to directory
Signed-off-by: Matthias Beyer <matthias.beyer@atos.net>
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/mod.rs230
1 files changed, 230 insertions, 0 deletions
diff --git a/src/ui/mod.rs b/src/ui/mod.rs
new file mode 100644
index 0000000..526db8c
--- /dev/null
+++ b/src/ui/mod.rs
@@ -0,0 +1,230 @@
+//
+// Copyright (c) 2020-2021 science+computing ag and other contributors
+//
+// This program and the accompanying materials are made
+// available under the terms of the Eclipse Public License 2.0
+// which is available at https://www.eclipse.org/legal/epl-2.0/
+//
+// SPDX-License-Identifier: EPL-2.0
+//
+
+//! Utility functions for the UI
+
+use std::collections::BTreeMap;
+use std::io::Write;
+use std::path::Path;
+use std::path::PathBuf;
+
+use anyhow::anyhow;
+use anyhow::Context;
+use anyhow::Error;
+use anyhow::Result;
+use handlebars::Handlebars;
+use itertools::Itertools;
+use log::error;
+
+use crate::config::Configuration;
+use crate::package::Package;
+use crate::package::Script;
+use crate::package::ScriptBuilder;
+use crate::package::Shebang;
+
+pub fn package_repo_cleanness_check(repo: &git2::Repository) -> Result<()> {
+ if !crate::util::git::repo_is_clean(&repo)? {
+ error!(
+ "Repository not clean, refusing to go on: {}",
+ repo.path().display()
+ );
+ Err(anyhow!(
+ "Repository not clean, refusing to go on: {}",
+ repo.path().display()
+ ))
+ } else {
+ Ok(())
+ }
+}
+
+pub struct PackagePrintFlags {
+ pub print_all: bool,
+ pub print_runtime_deps: bool,
+ pub print_build_deps: bool,
+ pub print_sources: bool,
+ pub print_dependencies: bool,
+ pub print_patches: bool,
+ pub print_env: bool,
+ pub print_flags: bool,
+ pub print_allowed_images: bool,
+ pub print_denied_images: bool,
+ pub print_phases: bool,
+ pub print_script: bool,
+ pub script_line_numbers: bool,
+ pub script_highlighting: bool,
+}
+
+impl PackagePrintFlags {
+ // Helper to check whether any of the CLI args requested one of these flags.
+ //
+ // The print_build_deps and print_runtime_deps as well as the script_highlighting and
+ // script_line_numbers is not included, because these only modify what to print and not whether
+ // to print.
+ fn print_any(&self) -> bool {
+ self.print_all || {
+ self.print_sources
+ || self.print_dependencies
+ || self.print_patches
+ || self.print_env
+ || self.print_flags
+ || self.print_allowed_images
+ || self.print_denied_images
+ || self.print_phases
+ || self.print_script
+ }
+ }
+}
+
+pub fn print_packages<'a, I>(
+ out: &mut dyn Write,
+ format: &str,
+ iter: I,
+ config: &Configuration,
+ flags: &PackagePrintFlags,
+) -> Result<()>
+where
+ I: Iterator<Item = &'a Package>,
+{
+ let mut hb = Handlebars::new();
+ hb.register_escape_fn(handlebars::no_escape);
+ hb.register_template_string("package", format)?;
+
+ iter.enumerate()
+ .try_for_each(|(i, package)| print_package(out, &hb, i, package, config, flags))
+}
+
+fn print_package(
+ out: &mut dyn Write,
+ hb: &Handlebars,
+ i: usize,
+ package: &Package,
+ config: &Configuration,
+ flags: &PackagePrintFlags,
+) -> Result<()> {
+ let script = ScriptBuilder::new(&Shebang::from(config.shebang().clone())).build(
+ package,
+ config.available_phases(),
+ *config.strict_script_interpolation(),
+ ).context("Rendering script for printing it failed")?;
+
+ let script = crate::ui::script_to_printable(
+ &script,
+ flags.script_highlighting,
+ config
+ .script_highlight_theme()
+ .as_ref()
+ .ok_or_else(|| anyhow!("Highlighting for script enabled, but no theme configured"))?,
+ flags.script_line_numbers,
+ )?;
+
+ let mut data = BTreeMap::new();
+ data.insert("i", serde_json::Value::Number(serde_json::Number::from(i)));
+ data.insert("p", serde_json::to_value(package)?);
+ data.insert("script", serde_json::Value::String(script));
+ data.insert("print_any", serde_json::Value::Bool(flags.print_any()));
+ data.insert(
+ "print_runtime_deps",
+ serde_json::Value::Bool(flags.print_runtime_deps),
+ );
+ data.insert(
+ "print_build_deps",
+ serde_json::Value::Bool(flags.print_build_deps),
+ );
+
+ data.insert(
+ "print_sources",
+ serde_json::Value::Bool(flags.print_all || flags.print_sources),
+ );
+ data.insert(
+ "print_dependencies",
+ serde_json::Value::Bool(flags.print_all || flags.print_dependencies),
+ );
+ data.insert(
+ "print_patches",
+ serde_json::Value::Bool(flags.print_all || flags.print_patches),
+ );
+ data.insert(
+ "print_env",
+ serde_json::Value::Bool(flags.print_all || flags.print_env),
+ );
+ data.insert(
+ "print_flags",
+ serde_json::Value::Bool(flags.print_all || flags.print_flags),
+ );
+ data.insert(
+ "print_allowed_images",
+ serde_json::Value::Bool(flags.print_all || flags.print_allowed_images),
+ );
+ data.insert(
+ "print_denied_images",
+ serde_json::Value::Bool(flags.print_all || flags.print_denied_images),
+ );
+ data.insert(
+ "print_phases",
+ serde_json::Value::Bool(flags.print_all || flags.print_phases),
+ );
+ data.insert(
+ "print_script",
+ serde_json::Value::Bool(flags.print_all || flags.print_script),
+ );
+
+ hb.render("package", &data)
+ .map_err(Error::from)
+ .and_then(|r| writeln!(out, "{}", r).map_err(Error::from))
+}
+
+pub fn script_to_printable(
+ script: &Script,
+ highlight: bool,
+ highlight_theme: &str,
+ line_numbers: bool,
+) -> Result<String> {
+ let script = if highlight {
+ let script = script.highlighted(highlight_theme);
+ if line_numbers {
+ script
+ .lines_numbered()?
+ .map(|(i, s)| format!("{:>4} | {}", i, s))
+ .join("")
+ } else {
+ script.lines()?.join("")
+ }
+ } else if line_numbers {
+ script
+ .lines_numbered()
+ .map(|(i, s)| format!("{:>4} | {}", i, s))
+ .join("")
+ } else {
+ script.to_string()
+ };
+
+ Ok(script)
+}
+
+pub fn find_linter_command(repo_path: &Path, config: &Configuration) -> Result<Option<PathBuf>> {
+ match config.script_linter().as_ref() {
+ None => Ok(None),
+ Some(linter) => {
+ if linter.is_absolute() {
+ Ok(Some(linter.to_path_buf()))
+ } else {
+ let linter = repo_path.join(linter);
+ if !linter.is_file() {
+ Err(anyhow!(
+ "Cannot find linter command, searched in: {}",
+ linter.display()
+ ))
+ } else {
+ Ok(Some(linter))
+ }
+ }
+ }
+ }
+}