undeepend/src/maven/settings.rs
Hautvast, S. (Sander) f6e39067c8 added settings.xml
2025-09-11 20:38:08 +02:00

523 lines
13 KiB
Rust

use std::{fs, path::PathBuf, str::FromStr};
use crate::{
maven::{CUSTOM_SETTINGS_LOCATION, HOME, MAVEN_HOME},
xml::dom_parser::{Node, get_document},
};
pub fn get_settings() -> Result<Settings, String> {
let mut local_repository = None;
let mut interactive_mode = true;
let mut use_plugin_registry = false;
let mut offline = false;
let mut proxies = vec![];
let mut servers = vec![];
let mut mirrors = vec![];
let mut profiles = vec![];
let mut active_profiles = vec![];
let mut plugin_groups = vec![];
let settings_path = get_settings_path();
let settings_file = fs::read_to_string(settings_path?).map_err(|e| e.to_string())?;
for child in get_document(settings_file)
.map_err(|err| err.to_string())?
.root
.children
{
match child.name.as_str() {
"localRepository" => local_repository = child.text,
"interactiveMode" => interactive_mode = child.text.map(|b| b == "true").unwrap_or(true),
"usePluginRegistry" => {
use_plugin_registry = child.text.map(|b| b == "true").unwrap_or(false)
}
"offline" => offline = child.text.map(|b| b == "true").unwrap_or(false),
"proxies" => proxies = get_proxies(child),
"servers" => servers = get_servers(child),
"mirrors" => mirrors = get_mirrors(child),
"profiles" => profiles = get_profiles(child),
"activeProfiles" => active_profiles = get_active_profiles(child),
"pluginGroups" => plugin_groups = get_plugin_groups(child),
_ => {}
};
}
Ok(Settings {
local_repository,
interactive_mode,
use_plugin_registry,
offline,
proxies,
servers,
mirrors,
profiles,
active_profiles,
plugin_groups,
})
}
fn get_proxies(element: Node) -> Vec<Proxy> {
let mut proxies = vec![];
for child in element.children {
proxies.push(get_proxy(child));
}
proxies
}
fn get_active_profiles(element: Node) -> Vec<String> {
let mut active_profiles = vec![];
for child in element.children {
if let Some(active_profile) = child.text {
active_profiles.push(active_profile);
}
}
active_profiles
}
fn get_plugin_groups(element: Node) -> Vec<String> {
let mut plugin_groups = vec![];
for child in element.children {
if let Some(plugin_group) = child.text {
plugin_groups.push(plugin_group);
}
}
plugin_groups
}
fn get_servers(servers_element: Node) -> Vec<Server> {
let mut servers = vec![];
for server_element in servers_element.children {
servers.push(get_server(server_element));
}
servers
}
fn get_mirrors(mirrors_element: Node) -> Vec<Mirror> {
let mut mirrors = vec![];
for mirror_element in mirrors_element.children {
mirrors.push(get_mirror(mirror_element));
}
mirrors
}
fn get_profiles(profiles_element: Node) -> Vec<Profile> {
let mut profiles = vec![];
for mirror_element in profiles_element.children {
profiles.push(get_profile(mirror_element));
}
profiles
}
fn get_server(server_element: Node) -> Server {
let mut id = None;
let mut username = None;
let mut password = None;
let mut private_key = None;
let mut passphrase = None;
let mut file_permissions = None;
let mut directory_permissions = None;
let mut configuration = None;
for child in server_element.children {
match child.name.as_str() {
"id" => id = child.text,
"username" => username = child.text,
"password" => password = child.text,
"private_key" => private_key = child.text,
"passphrase" => passphrase = child.text,
"filePermissions" => file_permissions = child.text,
"directoryPermissions" => directory_permissions = child.text,
"configuration" => configuration = Some(child),
_ => {}
}
}
Server {
id,
username,
password,
private_key,
passphrase,
file_permissions,
directory_permissions,
configuration,
}
}
fn get_proxy(element: Node) -> Proxy {
let mut active = false;
let mut protocol = "http".to_owned();
let mut username = None;
let mut password = None;
let mut port: usize = 8080;
let mut host = None;
let mut non_proxy_hosts = None;
let mut id = None;
for child in element.children {
match child.name.as_str() {
"active" => active = child.text.map(|b| b == "true").unwrap_or(false),
"protocol" => protocol = child.text.unwrap_or("http".to_owned()),
"username" => username = child.text,
"password" => password = child.text,
"port" => {
port = child
.text
.map(|i| {
usize::from_str(&i).expect(&format!("Illegal value for port: '{}'", i))
})
.unwrap_or(8080)
}
"host" => host = child.text,
"non_proxy_hosts" => non_proxy_hosts = child.text,
"id" => id = child.text,
_ => {}
}
}
Proxy {
active,
protocol,
username,
password,
port,
host,
non_proxy_hosts,
id,
}
}
fn get_mirror(mirror_element: Node) -> Mirror {
let mut id = None;
let mut mirror_of = None;
let mut url = None;
let mut name = None;
for child in mirror_element.children {
match child.name.as_str() {
"id" => id = child.text,
"mirror_of" => mirror_of = child.text,
"url" => url = child.text,
"name" => name = child.text,
_ => {}
}
}
Mirror {
id,
mirror_of,
url,
name,
}
}
fn get_profile(profile_element: Node) -> Profile {
let mut id = None;
let mut activation = None;
let mut properties = vec![];
let mut repositories = vec![];
let mut plugin_repositories = vec![];
for child in profile_element.children {
match child.name.as_str() {
"id" => id = child.text,
"activation" => activation = Some(get_activation(child)),
"properties" => properties.append(&mut get_properties(child)),
"repositories" => repositories = get_repositories(child),
"pluginRepositories" => plugin_repositories = get_repositories(child),
_ => {}
}
}
Profile {
id,
activation,
properties,
repositories,
plugin_repositories,
}
}
fn get_activation(activation_element: Node) -> Activation {
let mut active_by_default = false;
let mut jdk = None;
let mut os = None;
let mut property = None;
let mut file = None;
for child in activation_element.children {
match child.name.as_str() {
"activeByDefault" => {
active_by_default = child.text.map(|b| b == "true").unwrap_or(false)
}
"jdk" => jdk = child.text,
"os" => os = Some(get_activation_os(child)),
"property" => property = Some(get_activation_property(child)),
"file" => file = Some(get_activation_file(child)),
_ => {}
}
}
Activation {
active_by_default,
jdk,
os,
property,
file,
}
}
fn get_properties(element: Node) -> Vec<Property> {
let mut properties = vec![];
for child in element.children {
properties.push(Property {
name: child.name,
value: child.text,
});
}
properties
}
fn get_repositories(element: Node) -> Vec<Repository> {
let mut repositories = vec![];
for child in element.children {
match child.name.as_str() {
"repository" => repositories.push(get_repository(child)),
_ => {}
}
}
repositories
}
fn get_repository(element: Node) -> Repository {
let mut releases = None;
let mut snapshots = None;
let mut id = None;
let mut name = None;
let mut url = None;
let mut layout = "default".to_owned();
for child in element.children {
match child.name.as_str() {
"releases" => releases = Some(get_update_policy(child)),
"snapshots" => snapshots = Some(get_update_policy(child)),
"id" => id = child.text,
"name" => name = child.text,
"url" => url = child.text,
"layout" => layout = child.text.unwrap_or("default".to_owned()),
_ => {}
}
}
Repository {
releases,
snapshots,
id,
name,
url,
layout,
}
}
fn get_update_policy(element: Node) -> RepositoryPolicy {
let mut enabled = true;
let mut update_policy = None;
let mut checksum_policy = None;
for child in element.children {
match child.name.as_str() {
"enabled" => enabled = child.text.map(|b| b == "true").unwrap_or(true),
"update_policy" => update_policy = child.text,
"checksum_policy" => checksum_policy = child.text,
_ => {}
}
}
RepositoryPolicy {
enabled,
update_policy,
checksum_policy,
}
}
fn get_activation_os(element: Node) -> ActivationOs {
let mut name = None;
let mut family = None;
let mut arch = None;
let mut version = None;
for child in element.children {
match child.name.as_str() {
"name" => name = child.text,
"family" => family = child.text,
"arch" => arch = child.text,
"version" => version = child.text,
_ => {}
}
}
ActivationOs {
name,
family,
arch,
version,
}
}
fn get_activation_property(element: Node) -> ActivationProperty {
let mut name = None;
let mut value = None;
for child in element.children {
match child.name.as_str() {
"name" => name = child.text,
"value" => value = child.text,
_ => {}
}
}
ActivationProperty { name, value }
}
fn get_activation_file(element: Node) -> ActivationFile {
let mut missing = None;
let mut exists = None;
for child in element.children {
match child.name.as_str() {
"missing" => missing = child.text,
"exists" => exists = child.text,
_ => {}
}
}
ActivationFile { missing, exists }
}
fn get_settings_path() -> Result<PathBuf, String> {
let mut settings = PathBuf::from_str(HOME.as_str()).map_err(|e| e.to_string())?;
settings.push(".m2/settings.xml");
if !settings.exists() {
settings = PathBuf::from_str(MAVEN_HOME.as_str()).map_err(|e| e.to_string())?;
settings.push("conf/settings.xml");
}
if !settings.exists() {
settings =
PathBuf::from_str(CUSTOM_SETTINGS_LOCATION.as_str()).map_err(|e| e.to_string())?;
if settings.is_dir() {
settings.push("settings.xml");
}
}
Ok(settings)
}
#[derive(Debug)]
pub struct Settings {
local_repository: Option<String>,
interactive_mode: bool,
use_plugin_registry: bool,
offline: bool,
proxies: Vec<Proxy>,
servers: Vec<Server>,
mirrors: Vec<Mirror>,
profiles: Vec<Profile>,
active_profiles: Vec<String>,
plugin_groups: Vec<String>,
}
#[derive(Debug)]
struct Server {
id: Option<String>,
username: Option<String>,
password: Option<String>,
private_key: Option<String>,
passphrase: Option<String>,
file_permissions: Option<String>,
directory_permissions: Option<String>,
configuration: Option<Node>, //xsd:any
}
#[derive(Debug)]
struct Mirror {
id: Option<String>,
mirror_of: Option<String>,
name: Option<String>,
url: Option<String>,
}
#[derive(Debug)]
struct Proxy {
active: bool,
protocol: String,
username: Option<String>,
password: Option<String>,
port: usize,
host: Option<String>,
non_proxy_hosts: Option<String>,
id: Option<String>,
}
#[derive(Debug)]
struct Profile {
id: Option<String>,
activation: Option<Activation>,
properties: Vec<Property>,
repositories: Vec<Repository>,
plugin_repositories: Vec<Repository>,
}
#[derive(Debug)]
struct Activation {
active_by_default: bool,
jdk: Option<String>,
os: Option<ActivationOs>,
property: Option<ActivationProperty>,
file: Option<ActivationFile>,
}
#[derive(Debug)]
struct ActivationOs {
name: Option<String>,
family: Option<String>,
arch: Option<String>,
version: Option<String>,
}
#[derive(Debug)]
struct ActivationProperty {
name: Option<String>,
value: Option<String>,
}
#[derive(Debug)]
struct ActivationFile {
missing: Option<String>,
exists: Option<String>,
}
#[derive(Debug)]
struct Property {
name: String,
value: Option<String>,
}
#[derive(Debug)]
struct Repository {
releases: Option<RepositoryPolicy>,
snapshots: Option<RepositoryPolicy>,
id: Option<String>,
name: Option<String>,
url: Option<String>,
layout: String,
}
#[derive(Debug)]
struct RepositoryPolicy {
enabled: bool,
update_policy: Option<String>,
checksum_policy: Option<String>,
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test() {
let settings = get_settings().expect("no fail");
println!("{:?}", settings);
}
}