From 1ecc48d9f4f55b78877edbd734a8baf48b847c99 Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Thu, 31 Aug 2023 09:48:00 -0700 Subject: [PATCH 1/3] Install node and nvm --- pgml-apps/cargo-pgml-components/Cargo.lock | 2 +- pgml-apps/cargo-pgml-components/Cargo.toml | 2 +- .../src/frontend/javascript.rs | 5 +- .../cargo-pgml-components/src/frontend/nvm.sh | 6 ++ .../src/frontend/sass.rs | 5 +- .../src/frontend/tools.rs | 88 +++++++++++++++++-- pgml-apps/cargo-pgml-components/src/main.rs | 6 +- pgml-apps/cargo-pgml-components/src/util.rs | 19 ++-- 8 files changed, 111 insertions(+), 22 deletions(-) create mode 100644 pgml-apps/cargo-pgml-components/src/frontend/nvm.sh 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..33a289b59 100644 --- a/pgml-apps/cargo-pgml-components/src/frontend/tools.rs +++ b/pgml-apps/cargo-pgml-components/src/frontend/tools.rs @@ -1,29 +1,99 @@ //! 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) )); } } } } + +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) +} + +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) + )); +} + +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..c3ae683c7 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] @@ -65,7 +65,9 @@ fn main() { 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), + AddCommands::Component { name } => { + crate::frontend::components::add(&name, pgml_commands.overwrite) + } }, }, } 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() { From d25826ed225d434c4a76c25a50c175c71940af7f Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Thu, 31 Aug 2023 09:52:38 -0700 Subject: [PATCH 2/3] always validate project path --- pgml-apps/cargo-pgml-components/src/main.rs | 30 +++++++++++++-------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/pgml-apps/cargo-pgml-components/src/main.rs b/pgml-apps/cargo-pgml-components/src/main.rs index c3ae683c7..5a47b1caf 100644 --- a/pgml-apps/cargo-pgml-components/src/main.rs +++ b/pgml-apps/cargo-pgml-components/src/main.rs @@ -62,19 +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 @@ -94,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"); } From b64951e4b2bb737e124c147d93545e9d5a3bbabd Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Thu, 31 Aug 2023 09:55:10 -0700 Subject: [PATCH 3/3] Comments --- pgml-apps/cargo-pgml-components/src/frontend/tools.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pgml-apps/cargo-pgml-components/src/frontend/tools.rs b/pgml-apps/cargo-pgml-components/src/frontend/tools.rs index 33a289b59..c3f19f79d 100644 --- a/pgml-apps/cargo-pgml-components/src/frontend/tools.rs +++ b/pgml-apps/cargo-pgml-components/src/frontend/tools.rs @@ -32,6 +32,7 @@ pub fn install() { } } +/// 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()); @@ -41,6 +42,7 @@ pub fn execute_with_nvm(command: &mut Command) -> std::io::Result { 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"))); @@ -51,6 +53,7 @@ fn install_nvm_entrypoint() { )); } +/// Install node using nvm fn install_node() { debug!("installing node"); // Node is already installed. 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