Skip to content

Commit

Permalink
new: Add language crates. (#106)
Browse files Browse the repository at this point in the history
* Start lang crates.

* Add version managers.

* Add node.

* Move helper.

* Move node utils.

* Move find util.

* Update workspace.

* Fix ext.
  • Loading branch information
milesj authored May 24, 2022
1 parent 749490e commit cb744b7
Show file tree
Hide file tree
Showing 27 changed files with 379 additions and 189 deletions.
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ crate-type = ["rlib"]

[dependencies]
moon_config = { path = "../config" }
moon_lang = { path = "../lang" }
moon_lang_node = { path = "../lang-node" }
moon_logger = { path = "../logger" }
moon_project = { path = "../project" }
moon_terminal = { path = "../terminal" }
Expand Down
24 changes: 7 additions & 17 deletions crates/cli/src/commands/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use moon_config::{
default_node_version, default_npm_version, default_pnpm_version, default_yarn_version,
load_global_project_config_template, load_workspace_config_template,
};
use moon_lang::is_using_package_manager;
use moon_lang_node::{NODENV, NPM, NVMRC, PNPM, YARN};
use moon_logger::color;
use moon_terminal::create_theme;
use moon_utils::fs;
Expand Down Expand Up @@ -71,23 +73,11 @@ async fn detect_package_manager(dest_dir: &Path, yes: bool) -> Result<(String, S

// If no value, detect based on files
if pm_type.is_empty() {
// yarn
if dest_dir.join("yarn.lock").exists()
|| dest_dir.join(".yarn").exists()
|| dest_dir.join(".yarnrc").exists()
|| dest_dir.join(".yarnrc.yml").exists()
{
if is_using_package_manager(dest_dir, &YARN) {
pm_type = String::from("yarn");

// pnpm
} else if dest_dir.join("pnpm-lock.yaml").exists()
|| dest_dir.join("pnpm-workspace.yaml").exists()
|| dest_dir.join(".pnpmfile.cjs").exists()
{
} else if is_using_package_manager(dest_dir, &PNPM) {
pm_type = String::from("pnpm");

// npm
} else if dest_dir.join("package-lock.json").exists() {
} else if is_using_package_manager(dest_dir, &NPM) {
pm_type = String::from("npm");
}
}
Expand Down Expand Up @@ -126,13 +116,13 @@ async fn detect_package_manager(dest_dir: &Path, yes: bool) -> Result<(String, S
/// Detect the Node.js version from local configuration files,
/// otherwise fallback to the configuration default.
fn detect_node_version(dest_dir: &Path) -> Result<String, AnyError> {
let nvmrc_path = dest_dir.join(".nvmrc");
let nvmrc_path = dest_dir.join(NVMRC.version_filename);

if nvmrc_path.exists() {
return Ok(read_to_string(nvmrc_path)?.trim().to_owned());
}

let node_version_path = dest_dir.join(".node-version");
let node_version_path = dest_dir.join(NODENV.version_filename);

if node_version_path.exists() {
return Ok(read_to_string(node_version_path)?.trim().to_owned());
Expand Down
3 changes: 2 additions & 1 deletion crates/cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use moon_cli::run_cli;
use moon_config::constants;
use moon_lang_node::NODE;
use std::env;
use std::path::{Path, PathBuf};
use tokio::process::Command;
Expand Down Expand Up @@ -84,7 +85,7 @@ async fn main() {
// locally installed `moon` binary in node modules
if let Some(workspace_root) = find_workspace_root(&current_dir) {
let moon_bin = workspace_root
.join("node_modules")
.join(NODE.vendor_dir)
.join("@moonrepo")
.join("cli")
.join("moon");
Expand Down
1 change: 1 addition & 0 deletions crates/config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ crate-type = ["rlib"]

[dependencies]
moon_error = { path = "../error"}
moon_lang_node = { path = "../lang-node" }
moon_utils = { path = "../utils"}
figment = { version = "0.10.6", features = ["test", "yaml"] }
json = "0.12.4"
Expand Down
13 changes: 7 additions & 6 deletions crates/config/src/workspace/node.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::validators::validate_semver_version;
use moon_lang_node::{NODE, NODENV, NVMRC, PNPM, YARN};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::env;
use validator::{Validate, ValidationError};

pub fn default_node_version() -> String {
env::var("MOON_NODE_VERSION").unwrap_or_else(|_| String::from("16.15.0"))
env::var("MOON_NODE_VERSION").unwrap_or_else(|_| NODE.default_version.to_string())
}

pub fn default_npm_version() -> String {
Expand All @@ -14,11 +15,11 @@ pub fn default_npm_version() -> String {
}

pub fn default_pnpm_version() -> String {
env::var("MOON_PNPM_VERSION").unwrap_or_else(|_| String::from("6.32.2"))
env::var("MOON_PNPM_VERSION").unwrap_or_else(|_| PNPM.default_version.to_string())
}

pub fn default_yarn_version() -> String {
env::var("MOON_YARN_VERSION").unwrap_or_else(|_| String::from("3.2.0"))
env::var("MOON_YARN_VERSION").unwrap_or_else(|_| YARN.default_version.to_string())
}

fn default_bool_true() -> bool {
Expand Down Expand Up @@ -67,10 +68,10 @@ pub enum VersionManager {
}

impl VersionManager {
pub fn get_config_file_name(&self) -> String {
pub fn get_config_filename(&self) -> String {
match self {
VersionManager::Nodenv => String::from(".node-version"),
VersionManager::Nvm => String::from(".nvmrc"),
VersionManager::Nodenv => String::from(NODENV.version_filename),
VersionManager::Nvm => String::from(NVMRC.version_filename),
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions crates/lang-node/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "moon_lang_node"
version = "0.1.0"
edition = "2021"

[dependencies]
moon_lang = { path = "../lang" }
44 changes: 44 additions & 0 deletions crates/lang-node/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
pub mod node;

use moon_lang::{Language, PackageManager, VersionManager};

pub const NODE: Language = Language {
default_version: "16.15.0",
vendor_bins_dir: "node_modules/.bin",
vendor_dir: "node_modules",
};

// Package managers

pub const NPM: PackageManager = PackageManager {
config_filenames: &[".npmrc"],
default_version: "8.10.0",
lock_filenames: &["package-lock.json", "npm-shrinkwrap.json"],
manifest_filename: "package.json",
};

pub const PNPM: PackageManager = PackageManager {
config_filenames: &["pnpm-workspace.yaml", ".pnpmfile.cjs"],
default_version: "7.1.5",
lock_filenames: &["pnpm-lock.yaml"],
manifest_filename: "package.json",
};

pub const YARN: PackageManager = PackageManager {
config_filenames: &[".yarn", ".yarnrc", ".yarnrc.yml"],
default_version: "3.2.1",
lock_filenames: &["yarn.lock"],
manifest_filename: "package.json",
};

// Version managers

pub const NVMRC: VersionManager = VersionManager {
config_filename: None,
version_filename: ".nvmrc",
};

pub const NODENV: VersionManager = VersionManager {
config_filename: None,
version_filename: ".node-version",
};
118 changes: 118 additions & 0 deletions crates/lang-node/src/node.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
use crate::NODE;
use moon_lang::LangError;
use std::env::{self, consts};
use std::path::{Path, PathBuf};

pub fn extend_node_options_env_var(next: String) -> String {
match env::var("NODE_OPTIONS") {
Ok(prev) => format!("{} {}", prev, next),
Err(_) => next,
}
}

pub fn find_package(starting_dir: &Path, package_name: &str) -> Option<PathBuf> {
let pkg_path = starting_dir.join(NODE.vendor_dir).join(package_name);

if pkg_path.exists() {
return Some(pkg_path);
}

match starting_dir.parent() {
Some(dir) => find_package_bin(dir, package_name),
None => None,
}
}

pub fn find_package_bin(starting_dir: &Path, package_name: &str) -> Option<PathBuf> {
let bin_path = starting_dir
.join(NODE.vendor_bins_dir)
.join(get_bin_name_suffix(package_name, "cmd", true));

if bin_path.exists() {
return Some(bin_path);
}

match starting_dir.parent() {
Some(dir) => find_package_bin(dir, package_name),
None => None,
}
}

pub fn get_bin_name_suffix(name: &str, windows_ext: &str, flat: bool) -> String {
if cfg!(windows) {
format!("{}.{}", name, windows_ext)
} else if flat {
name.to_owned()
} else {
format!("bin/{}", name)
}
}

pub fn get_download_file_ext() -> &'static str {
if consts::OS == "windows" {
"zip"
} else {
"tar.gz"
}
}

// #[allow(unused_assignments)]
pub fn get_download_file_name(version: &str) -> Result<String, LangError> {
let platform;

if consts::OS == "linux" {
platform = "linux"
} else if consts::OS == "windows" {
platform = "win";
} else if consts::OS == "macos" {
platform = "darwin"
} else {
return Err(LangError::UnsupportedPlatform(
consts::OS.to_string(),
String::from("Node.js"),
));
}

let arch;

if consts::ARCH == "x86" {
arch = "x86"
} else if consts::ARCH == "x86_64" {
arch = "x64"
} else if consts::ARCH == "arm" {
arch = "arm64"
} else if consts::ARCH == "powerpc64" {
arch = "ppc64le"
} else if consts::ARCH == "s390x" {
arch = "s390x"
} else {
return Err(LangError::UnsupportedArchitecture(
consts::ARCH.to_string(),
String::from("Node.js"),
));
}

Ok(format!(
"node-v{version}-{platform}-{arch}",
version = version,
platform = platform,
arch = arch,
))
}

pub fn get_download_file(version: &str) -> Result<String, LangError> {
Ok(format!(
"{}.{}",
get_download_file_name(version)?,
get_download_file_ext()
))
}

pub fn get_nodejs_url(version: &str, host: &str, path: &str) -> String {
format!(
"{host}/dist/v{version}/{path}",
host = host,
version = version,
path = path,
)
}
7 changes: 7 additions & 0 deletions crates/lang/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "moon_lang"
version = "0.1.0"
edition = "2021"

[dependencies]
thiserror = "1.0.31"
26 changes: 26 additions & 0 deletions crates/lang/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use thiserror::Error;

#[derive(Error, Debug)]
pub enum LangError {
#[error(
"Shashum check has failed for <file>{0}</file>, which was downloaded from <url>{1}</url>."
)]
InvalidShasum(
String, // Download path
String, // URL
),

#[error(
"Unsupported architecture <symbol>{0}</symbol>. Unable to install <symbol>{1}</symbol>."
)]
UnsupportedArchitecture(
String, // Arch
String, // Tool name
),

#[error("Unsupported platform <symbol>{0}</symbol>. Unable to install <symbol>{1}</symbol>.")]
UnsupportedPlatform(
String, // Platform
String, // Tool name
),
}
Loading

0 comments on commit cb744b7

Please sign in to comment.