diff --git a/pgml-apps/cargo-pgml-components/Cargo.lock b/pgml-apps/cargo-pgml-components/Cargo.lock index fa54e9722..c02281263 100644 --- a/pgml-apps/cargo-pgml-components/Cargo.lock +++ b/pgml-apps/cargo-pgml-components/Cargo.lock @@ -79,7 +79,7 @@ checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "cargo-pgml-components" -version = "0.1.7" +version = "0.1.8" dependencies = [ "anyhow", "clap", diff --git a/pgml-apps/cargo-pgml-components/Cargo.toml b/pgml-apps/cargo-pgml-components/Cargo.toml index 84be9f5b5..ed7e37973 100644 --- a/pgml-apps/cargo-pgml-components/Cargo.toml +++ b/pgml-apps/cargo-pgml-components/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cargo-pgml-components" -version = "0.1.7" +version = "0.1.8" edition = "2021" authors = ["PostgresML "] license = "MIT" diff --git a/pgml-apps/cargo-pgml-components/src/frontend/javascript.rs b/pgml-apps/cargo-pgml-components/src/frontend/javascript.rs index 90b733122..0c9bde514 100644 --- a/pgml-apps/cargo-pgml-components/src/frontend/javascript.rs +++ b/pgml-apps/cargo-pgml-components/src/frontend/javascript.rs @@ -7,7 +7,8 @@ use std::process::Command; use convert_case::{Case, Casing}; -use crate::util::{execute_command, info, unwrap_or_exit, warn}; +use crate::frontend::tools::execute_with_nvm; +use crate::util::{info, unwrap_or_exit, warn}; /// The name of the JS file that imports all other JS files /// created in the modules. @@ -99,7 +100,7 @@ pub fn bundle() { assemble_modules(); // Bundle JavaScript. - unwrap_or_exit!(execute_command( + unwrap_or_exit!(execute_with_nvm( Command::new(JS_COMPILER) .arg(MODULES_FILE) .arg("--file") diff --git a/pgml-apps/cargo-pgml-components/src/frontend/nvm.sh b/pgml-apps/cargo-pgml-components/src/frontend/nvm.sh new file mode 100644 index 000000000..067872416 --- /dev/null +++ b/pgml-apps/cargo-pgml-components/src/frontend/nvm.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm +[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion + +${@} diff --git a/pgml-apps/cargo-pgml-components/src/frontend/sass.rs b/pgml-apps/cargo-pgml-components/src/frontend/sass.rs index dc74cd5d2..c12ba643d 100644 --- a/pgml-apps/cargo-pgml-components/src/frontend/sass.rs +++ b/pgml-apps/cargo-pgml-components/src/frontend/sass.rs @@ -5,7 +5,8 @@ use std::fs::{copy, read_to_string, remove_file, File}; use std::io::Write; use std::process::Command; -use crate::util::{execute_command, info, unwrap_or_exit, warn}; +use crate::frontend::tools::execute_with_nvm; +use crate::util::{info, unwrap_or_exit, warn}; /// The name of the SASS file that imports all other SASS files /// created in the modules. @@ -77,7 +78,7 @@ pub fn bundle() { cleanup_old_bundles(); // Build Sass. - unwrap_or_exit!(execute_command( + unwrap_or_exit!(execute_with_nvm( Command::new(SASS_COMPILER).arg(SASS_FILE).arg(CSS_FILE), )); diff --git a/pgml-apps/cargo-pgml-components/src/frontend/tools.rs b/pgml-apps/cargo-pgml-components/src/frontend/tools.rs index b6b2e785c..c3f19f79d 100644 --- a/pgml-apps/cargo-pgml-components/src/frontend/tools.rs +++ b/pgml-apps/cargo-pgml-components/src/frontend/tools.rs @@ -1,29 +1,102 @@ //! Tools required by us to build stuff. -use crate::util::{error, execute_command, unwrap_or_exit, warn}; +use crate::util::{debug1, error, execute_command, unwrap_or_exit, warn}; +use std::fs::File; +use std::io::Write; use std::process::{exit, Command}; /// Required tools. static TOOLS: &[&str] = &["sass", "rollup"]; +static NVM_EXEC: &'static str = "/tmp/pgml-components-nvm.sh"; +static NVM_SOURCE: &'static str = "https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh"; +static NVM_SOURCE_DOWNLOADED: &'static str = "/tmp/pgml-components-nvm-source.sh"; /// Install any missing tools. pub fn install() { - if let Err(err) = execute_command(Command::new("node").arg("--version")) { - error("Node is not installed. Install it with nvm or your system package manager."); - debug!("{}", err); - exit(1); - } + install_nvm_entrypoint(); + debug!("installed node entrypoint"); + install_node(); + debug!("installed node"); for tool in TOOLS { - match execute_command(Command::new(tool).arg("--version")) { + match execute_with_nvm(Command::new(tool).arg("--version")) { Ok(_) => (), Err(err) => { - debug!("{}", err); + debug1!(err); warn(&format!("installing {}", tool)); - unwrap_or_exit!(execute_command( + unwrap_or_exit!(execute_with_nvm( Command::new("npm").arg("install").arg("-g").arg(tool) )); } } } } + +/// Execute a command making sure that nvm is available. +pub fn execute_with_nvm(command: &mut Command) -> std::io::Result { + let mut cmd = Command::new(NVM_EXEC); + cmd.arg(command.get_program()); + for arg in command.get_args() { + cmd.arg(arg); + } + execute_command(&mut cmd) +} + +/// Install the nvm entrypoint we provide into /tmp +fn install_nvm_entrypoint() { + let mut file = unwrap_or_exit!(File::create(NVM_EXEC)); + unwrap_or_exit!(writeln!(&mut file, "{}", include_str!("nvm.sh"))); + drop(file); + + unwrap_or_exit!(execute_command( + Command::new("chmod").arg("+x").arg(NVM_EXEC) + )); +} + +/// Install node using nvm +fn install_node() { + debug!("installing node"); + // Node is already installed. + if let Ok(_) = execute_with_nvm(Command::new("node").arg("--version")) { + debug!("node is available"); + return; + } + + warn("installing node using nvm"); + + debug!("node is not available"); + + if let Err(err) = execute_command(Command::new("nvm").arg("--version")) { + debug!("nvm is not available"); + debug1!(err); + // Install Node Version Manager. + if let Err(err) = execute_command( + Command::new("curl") + .arg("-Ls") + .arg(NVM_SOURCE) + .arg("-o") + .arg(NVM_SOURCE_DOWNLOADED), + ) { + debug!("curl is not available"); + error("couldn't not download nvm from Github, please do so manually before proceeding"); + debug1!(err); + exit(1); + } else { + if let Err(err) = execute_command(Command::new("bash").arg(NVM_SOURCE_DOWNLOADED)) { + error("couldn't install nvm, please do so manually before proceeding"); + debug1!(err); + exit(1); + } else { + warn("installed nvm"); + } + } + } + + if let Err(err) = execute_with_nvm(Command::new("nvm").arg("install").arg("stable")) { + error("couldn't install Node, please do so manually before proceeding"); + debug1!(err); + exit(1); + } else { + warn("installed node") + } +} diff --git a/pgml-apps/cargo-pgml-components/src/main.rs b/pgml-apps/cargo-pgml-components/src/main.rs index 6f2a57a6d..5a47b1caf 100644 --- a/pgml-apps/cargo-pgml-components/src/main.rs +++ b/pgml-apps/cargo-pgml-components/src/main.rs @@ -2,7 +2,7 @@ use clap::{Args, Parser, Subcommand}; use std::env::{current_dir, set_current_dir}; -use std::fs::{create_dir_all}; +use std::fs::create_dir_all; use std::path::Path; #[macro_use] @@ -62,17 +62,23 @@ fn main() { let cli = Cli::parse(); match cli.subcomand { - CargoSubcommands::PgmlComponents(pgml_commands) => match pgml_commands.command { - Commands::Bundle {} => bundle(pgml_commands.project_path), - Commands::Add(command) => match command { - AddCommands::Component { name } => crate::frontend::components::add(&name, pgml_commands.overwrite), - }, - }, + CargoSubcommands::PgmlComponents(pgml_commands) => { + validate_project(pgml_commands.project_path); + match pgml_commands.command { + Commands::Bundle {} => bundle(), + Commands::Add(command) => match command { + AddCommands::Component { name } => { + crate::frontend::components::add(&name, pgml_commands.overwrite) + } + }, + } + } } } -/// Bundle SASS and JavaScript into neat bundle files. -fn bundle(project_path: Option) { +fn validate_project(project_path: Option) { + debug!("validating project directory"); + // Validate that the required project paths exist. let cwd = if let Some(project_path) = project_path { project_path @@ -92,9 +98,13 @@ fn bundle(project_path: Option) { } unwrap_or_exit!(set_current_dir(path)); +} + +/// Bundle SASS and JavaScript into neat bundle files. +fn bundle() { frontend::sass::bundle(); frontend::javascript::bundle(); frontend::components::update_modules(); - info("Bundle complete"); + info("bundle complete"); } diff --git a/pgml-apps/cargo-pgml-components/src/util.rs b/pgml-apps/cargo-pgml-components/src/util.rs index 7205c4a9b..ec3d4aa3d 100644 --- a/pgml-apps/cargo-pgml-components/src/util.rs +++ b/pgml-apps/cargo-pgml-components/src/util.rs @@ -1,8 +1,8 @@ use owo_colors::OwoColorize; use std::fs::File; -use std::io::Write; +use std::io::{ErrorKind, Write}; use std::path::Path; -use std::process::{exit, Command}; +use std::process::Command; macro_rules! unwrap_or_exit { ($i:expr) => { @@ -17,6 +17,13 @@ macro_rules! unwrap_or_exit { }; } +macro_rules! debug1 { + ($e:expr) => { + debug!("{}:{}:{} {}", file!(), line!(), column!(), $e); + }; +} + +pub(crate) use debug1; pub(crate) use unwrap_or_exit; pub fn info(value: &str) { @@ -43,12 +50,14 @@ pub fn execute_command(command: &mut Command) -> std::io::Result { let stdout = String::from_utf8_lossy(&output.stderr).to_string(); if !output.status.success() { - error!( + let error = String::from_utf8_lossy(&output.stderr).to_string(); + debug!( "{} failed: {}", command.get_program().to_str().unwrap(), - String::from_utf8_lossy(&output.stderr).to_string(), + error, ); - exit(1); + + return Err(std::io::Error::new(ErrorKind::Other, error)); } if !stderr.is_empty() { pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy