Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(config): config.toml #353

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions rocks-bin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ async fn main() {
let cli = Cli::parse();

let config = ConfigBuilder::new()
.unwrap()
.dev(Some(cli.dev))
.lua_dir(cli.lua_dir)
.lua_version(cli.lua_version)
Expand Down
1 change: 1 addition & 0 deletions rocks-bin/src/run_lua.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ mod test {
};
let temp: PathBuf = assert_fs::TempDir::new().unwrap().path().into();
let config = ConfigBuilder::new()
.unwrap()
.tree(Some(temp.clone()))
.luarocks_tree(Some(temp))
.build()
Expand Down
1 change: 1 addition & 0 deletions rocks-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ url = "2.5.4"
bon = { version = "3.3.2", features = ["implied-bounds"] }
clean-path = "0.2.1"
diffy = "0.4.0"
toml = "0.8.19"

[dev-dependencies]
httptest = { version = "0.16.1" }
Expand Down
2 changes: 1 addition & 1 deletion rocks-lib/src/build/external_dependency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl ExternalDependencyInfo {
}
for prefix in search_prefixes {
let inc_dir = prefix.join(&config.include_subdir);
for lib_subdir in &config.lib_subdir {
for lib_subdir in &config.lib_subdirs {
let lib_dir = prefix.join(lib_subdir);
if library_exists(&lib_dir, lib, &config.lib_patterns) {
return Ok(Self::Library {
Expand Down
2 changes: 1 addition & 1 deletion rocks-lib/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ mod tests {
let build_dir = assert_fs::TempDir::new().unwrap();
build_dir.copy_from(&project_root, &["**"]).unwrap();
let dest_dir = assert_fs::TempDir::new().unwrap();
let config = ConfigBuilder::new().build().unwrap();
let config = ConfigBuilder::new().unwrap().build().unwrap();
let rock_layout = RockLayout {
rock_path: dest_dir.to_path_buf(),
etc: dest_dir.join("etc"),
Expand Down
57 changes: 43 additions & 14 deletions rocks-lib/src/config/external_deps.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,60 @@
use std::{collections::HashMap, path::PathBuf};

use serde::{Deserialize, Serialize};

/// Used as a fallback when searching for external dependencies if they
/// cannot be found using pkg-config.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExternalDependencySearchConfig {
/// Patterns for binary files
pub bin_patterns: Vec<String>,
#[serde(default = "default_bin_patterns")]
pub(crate) bin_patterns: Vec<String>,
/// Patterns for header files
pub include_patterns: Vec<String>,
#[serde(default = "default_include_patterns")]
pub(crate) include_patterns: Vec<String>,
/// Patterns for library files
pub lib_patterns: Vec<String>,
#[serde(default = "default_lib_patterns")]
pub(crate) lib_patterns: Vec<String>,
/// Default binary subdirectory
pub bin_subdir: String,
#[serde(default = "default_bin_subdir")]
pub(crate) bin_subdir: String,
/// Default include subdirectory
pub include_subdir: String,
#[serde(default = "default_include_subdir")]
pub(crate) include_subdir: String,
/// Default library subdirectory
pub lib_subdir: Vec<String>,
#[serde(default = "default_lib_subdirs")]
pub(crate) lib_subdirs: Vec<PathBuf>,
/// System-wide search paths
pub search_prefixes: Vec<PathBuf>,
#[serde(default = "default_prefixes")]
pub(crate) search_prefixes: Vec<PathBuf>,
/// Known installation prefixes for specific dependencies.
/// These can also be set via environment variables.
pub prefixes: HashMap<String, PathBuf>,
pub(crate) prefixes: HashMap<String, PathBuf>,
}

impl Default for ExternalDependencySearchConfig {
fn default() -> Self {
Self {
bin_patterns: vec!["?".into()],
include_patterns: vec!["?.h".into()],
bin_patterns: default_bin_patterns(),
include_patterns: default_include_patterns(),
lib_patterns: default_lib_patterns(),
bin_subdir: "bin".into(),
include_subdir: "include".into(),
lib_subdir: vec!["lib".into(), "lib64".into()],
bin_subdir: default_bin_subdir(),
include_subdir: default_include_subdir(),
lib_subdirs: default_lib_subdirs(),
search_prefixes: default_prefixes(),
prefixes: HashMap::default(),
}
}
}

fn default_bin_patterns() -> Vec<String> {
vec!["?".into()]
}

fn default_include_patterns() -> Vec<String> {
vec!["?.h".into()]
}

#[cfg(target_family = "unix")]
fn default_lib_patterns() -> Vec<String> {
#[cfg(target_os = "macos")]
Expand Down Expand Up @@ -89,3 +106,15 @@ fn default_prefixes() -> Vec<PathBuf> {
PathBuf::from(r"C:\Program Files (x86)"),
]
}

fn default_bin_subdir() -> String {
"bin".into()
}

fn default_include_subdir() -> String {
"include".into()
}

fn default_lib_subdirs() -> Vec<PathBuf> {
vec!["lib".into(), "lib64".into()]
}
81 changes: 47 additions & 34 deletions rocks-lib/src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use directories::ProjectDirs;
use external_deps::ExternalDependencySearchConfig;
use serde::{Deserialize, Serialize};
use std::{
collections::HashMap, env, fmt::Display, io, path::PathBuf, str::FromStr, time::Duration,
};
Expand All @@ -17,13 +18,19 @@ use crate::{

pub mod external_deps;

#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub enum LuaVersion {
#[serde(rename = "5.1")]
Lua51,
#[serde(rename = "5.2")]
Lua52,
#[serde(rename = "5.3")]
Lua53,
#[serde(rename = "5.4")]
Lua54,
#[serde(rename = "jit")]
LuaJIT,
#[serde(rename = "jit5.2")]
LuaJIT52,
// TODO(vhyrro): Support luau?
// LuaU,
Expand Down Expand Up @@ -276,14 +283,18 @@ impl HasVariables for Config {
}

#[derive(Error, Debug)]
#[error(transparent)]
pub enum ConfigError {
#[error(transparent)]
Io(#[from] io::Error),
#[error(transparent)]
NoValidHomeDirectory(#[from] NoValidHomeDirectory),
#[error(transparent)]
Project(#[from] ProjectError),
#[error("error deserializing rocks config: {0}")]
Deserialize(#[from] toml::de::Error),
}

#[derive(Default)]
#[derive(Default, Deserialize, Serialize)]
pub struct ConfigBuilder {
enable_development_rockspecs: Option<bool>,
server: Option<Url>,
Expand All @@ -300,15 +311,22 @@ pub struct ConfigBuilder {
make: Option<String>,
cmake: Option<String>,
variables: Option<HashMap<String, String>>,
external_deps: Option<ExternalDependencySearchConfig>,

cache_dir: Option<PathBuf>,
data_dir: Option<PathBuf>,
#[serde(default)]
external_deps: ExternalDependencySearchConfig,
}

impl ConfigBuilder {
pub fn new() -> Self {
Self::default()
/// Create a new `ConfigBuilder` from a config file by deserializing from a config file
/// if present, or otherwise by instantiating the default config.
pub fn new() -> Result<Self, ConfigError> {
let config_file = config_file()?;
if config_file.is_file() {
Ok(toml::from_str(&std::fs::read_to_string(&config_file)?)?)
} else {
Ok(Self::default())
}
}

pub fn dev(self, dev: Option<bool>) -> Self {
Expand Down Expand Up @@ -382,17 +400,6 @@ impl ConfigBuilder {
Self { cmake, ..self }
}

pub fn variables(self, variables: Option<HashMap<String, String>>) -> Self {
Self { variables, ..self }
}

pub fn external_deps(self, external_deps: Option<ExternalDependencySearchConfig>) -> Self {
Self {
external_deps,
..self
}
}

pub fn cache_dir(self, cache_dir: Option<PathBuf>) -> Self {
Self { cache_dir, ..self }
}
Expand All @@ -413,20 +420,6 @@ impl ConfigBuilder {
.or(crate::lua_installation::get_installed_lua_version("lua")
.ok()
.and_then(|version| LuaVersion::from_version(version).ok()));
let cflags = env::var("CFLAGS").unwrap_or(utils::default_cflags().into());
let default_variables = vec![
("LUA", "lua"),
("LIB_EXTENSION", utils::lua_lib_extension()),
("OBJ_EXTENSION", utils::lua_obj_extension()),
("CFLAGS", cflags.as_str()),
("LIBFLAG", utils::default_libflag()),
];

let variables = default_variables
.into_iter()
.map(|(key, val)| (key.into(), val.into()))
.chain(self.variables.unwrap_or_default())
.collect();
Ok(Config {
enable_development_rockspecs: self.enable_development_rockspecs.unwrap_or(false),
server: self
Expand Down Expand Up @@ -455,10 +448,30 @@ impl ConfigBuilder {
timeout: self.timeout.unwrap_or_else(|| Duration::from_secs(30)),
make: self.make.unwrap_or("make".into()),
cmake: self.cmake.unwrap_or("cmake".into()),
variables,
external_deps: self.external_deps.unwrap_or_default(),
variables: default_variables()
.chain(self.variables.unwrap_or_default())
.collect(),
external_deps: self.external_deps,
cache_dir,
data_dir,
})
}
}

fn default_variables() -> impl Iterator<Item = (String, String)> {
let cflags = env::var("CFLAGS").unwrap_or(utils::default_cflags().into());
vec![
("LUA".into(), "lua".into()),
("LIB_EXTENSION".into(), utils::lua_lib_extension().into()),
("OBJ_EXTENSION".into(), utils::lua_obj_extension().into()),
("CFLAGS".into(), cflags),
("LIBFLAG".into(), utils::default_libflag().into()),
]
.into_iter()
}

fn config_file() -> Result<PathBuf, NoValidHomeDirectory> {
let project_dirs =
directories::ProjectDirs::from("org", "neorocks", "rocks").ok_or(NoValidHomeDirectory)?;
Ok(project_dirs.config_dir().join("config.toml").to_path_buf())
}
1 change: 1 addition & 0 deletions rocks-lib/src/luarocks/install_binary_rock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ mod test {
let rockspec = unpack_rockspec(&rock).await.unwrap();
let dir = assert_fs::TempDir::new().unwrap();
let config = ConfigBuilder::new()
.unwrap()
.tree(Some(dir.to_path_buf()))
.build()
.unwrap();
Expand Down
3 changes: 3 additions & 0 deletions rocks-lib/src/manifest/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ mod tests {
let mut url_str = server.url_str(""); // Remove trailing "/"
url_str.pop();
let config = ConfigBuilder::new()
.unwrap()
.cache_dir(Some(cache_dir))
.lua_version(Some(crate::config::LuaVersion::LuaJIT))
.build()
Expand All @@ -358,6 +359,7 @@ mod tests {
url_str.pop();

let config = ConfigBuilder::new()
.unwrap()
.cache_dir(Some(cache_dir))
.lua_version(Some(crate::config::LuaVersion::Lua51))
.build()
Expand All @@ -384,6 +386,7 @@ mod tests {
fs::write(&cache, manifest_content).await.unwrap();
let _metadata = fs::metadata(&cache).await.unwrap();
let config = ConfigBuilder::new()
.unwrap()
.cache_dir(Some(cache_dir.to_path_buf()))
.lua_version(Some(crate::config::LuaVersion::Lua51))
.build()
Expand Down
6 changes: 5 additions & 1 deletion rocks-lib/tests/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ async fn builtin_build() {
let rockspec = Rockspec::new(&content).unwrap();

let config = ConfigBuilder::new()
.unwrap()
.tree(Some(dir.into_path()))
.build()
.unwrap();
Expand All @@ -53,6 +54,7 @@ async fn make_build() {
let rockspec = Rockspec::new(&content).unwrap();

let config = ConfigBuilder::new()
.unwrap()
.tree(Some(dir.into_path()))
.build()
.unwrap();
Expand All @@ -75,7 +77,7 @@ async fn cmake_build() {
#[tokio::test]
async fn command_build() {
// The rockspec appears to be broken when using luajit headers on macos
let config = ConfigBuilder::new().build().unwrap();
let config = ConfigBuilder::new().unwrap().build().unwrap();
if cfg!(target_os = "macos") && config.lua_version() == Some(&LuaVersion::LuaJIT) {
println!("luaposix is broken on macos/luajit! Skipping...");
return;
Expand All @@ -86,6 +88,7 @@ async fn command_build() {
#[tokio::test]
async fn lockfile_update() {
let config = ConfigBuilder::new()
.unwrap()
.tree(Some(assert_fs::TempDir::new().unwrap().path().into()))
.build()
.unwrap();
Expand Down Expand Up @@ -129,6 +132,7 @@ async fn test_build_rockspec(rockspec_path: PathBuf) {
let rockspec = Rockspec::new(&content).unwrap();

let config = ConfigBuilder::new()
.unwrap()
.tree(Some(dir.into_path()))
.build()
.unwrap();
Expand Down
1 change: 1 addition & 0 deletions rocks-lib/tests/luarocks_installation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use rocks_lib::{
async fn luarocks_make() {
let dir = TempDir::new().unwrap();
let config = ConfigBuilder::new()
.unwrap()
.tree(Some(dir.path().into()))
.luarocks_tree(Some(TempDir::new().unwrap().path().into()))
.build()
Expand Down
1 change: 1 addition & 0 deletions rocks-lib/tests/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use tempdir::TempDir;
async fn run_nlua() {
let dir = TempDir::new("rocks-test").unwrap();
let config = ConfigBuilder::new()
.unwrap()
.tree(Some(dir.into_path()))
.build()
.unwrap();
Expand Down
6 changes: 5 additions & 1 deletion rocks-lib/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ async fn run_busted_test() {
let project: Project = Project::from(project_root).unwrap().unwrap();
let tree_root = project.root().to_path_buf().join(".rocks");
let _ = std::fs::remove_dir_all(&tree_root);
let config = ConfigBuilder::new().tree(Some(tree_root)).build().unwrap();
let config = ConfigBuilder::new()
.unwrap()
.tree(Some(tree_root))
.build()
.unwrap();
Test::new(project, &config).run().await.unwrap();
}
Loading