Release 0.4.1 - Compatibility bug and improved error handling.
- Disallow multiple type parameters applied to --create - Provide the ROOT type in pacwrap-utils replicate function - Updated help manual.
This commit is contained in:
parent
c14f6e0733
commit
c0bb7f80d1
10 changed files with 91 additions and 50 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -362,7 +362,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pacwrap"
|
name = "pacwrap"
|
||||||
version = "0.4.0"
|
version = "0.4.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alpm",
|
"alpm",
|
||||||
"bitflags 2.4.1",
|
"bitflags 2.4.1",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "pacwrap"
|
name = "pacwrap"
|
||||||
version = "0.4.0"
|
version = "0.4.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
|
@ -359,6 +359,7 @@ replicate_instance() {
|
||||||
[[ $type != BASE ]] && depend=$(return_dependency)
|
[[ $type != BASE ]] && depend=$(return_dependency)
|
||||||
|
|
||||||
case $type in
|
case $type in
|
||||||
|
ROOT) params+="r";;
|
||||||
BASE) params+="b";;
|
BASE) params+="b";;
|
||||||
DEP) params+="d";;
|
DEP) params+="d";;
|
||||||
LINK) ln -s "$INSTANCE_ROOT_DIR/$depend" "$INSTANCE_ROOT_DIR/$instance"
|
LINK) ln -s "$INSTANCE_ROOT_DIR/$depend" "$INSTANCE_ROOT_DIR/$instance"
|
||||||
|
|
2
dist/pacwrap-base-dist/PKGBUILD
vendored
2
dist/pacwrap-base-dist/PKGBUILD
vendored
|
@ -1,7 +1,7 @@
|
||||||
# Maintainer: Xavier R.M. (sapphirus at azorium dot net)
|
# Maintainer: Xavier R.M. (sapphirus at azorium dot net)
|
||||||
|
|
||||||
pkgname=('pacwrap-base-dist')
|
pkgname=('pacwrap-base-dist')
|
||||||
pkgver=0.4.0
|
pkgver=0.4.1
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc=""
|
pkgdesc=""
|
||||||
arch=('any')
|
arch=('any')
|
||||||
|
|
|
@ -10,6 +10,7 @@ use crate::config::{self,
|
||||||
InsVars,
|
InsVars,
|
||||||
InstanceType,
|
InstanceType,
|
||||||
InstanceHandle};
|
InstanceHandle};
|
||||||
|
use crate::utils::print_help_error;
|
||||||
use crate::utils::{arguments::{Arguments, Operand},
|
use crate::utils::{arguments::{Arguments, Operand},
|
||||||
handle_process,
|
handle_process,
|
||||||
env_var};
|
env_var};
|
||||||
|
@ -90,7 +91,7 @@ pub fn compat(mut args: Arguments) {
|
||||||
match args.next().unwrap_or_default() {
|
match args.next().unwrap_or_default() {
|
||||||
Operand::Short('s') | Operand::Long("save") => save_configuration(args.target()),
|
Operand::Short('s') | Operand::Long("save") => save_configuration(args.target()),
|
||||||
Operand::Short('l') | Operand::Long("load") => print_configuration(args.target()),
|
Operand::Short('l') | Operand::Long("load") => print_configuration(args.target()),
|
||||||
_ => args.invalid_operand()
|
_ => print_help_error(args.invalid_operand())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ fn main() {
|
||||||
Operand::Short('h') | Operand::Long("help") => manual::help(arguments),
|
Operand::Short('h') | Operand::Long("help") => manual::help(arguments),
|
||||||
Operand::Short('V') | Operand::Long("version") => manual::print_version(arguments),
|
Operand::Short('V') | Operand::Long("version") => manual::print_version(arguments),
|
||||||
Operand::Long("compat") => compat::compat(arguments),
|
Operand::Long("compat") => compat::compat(arguments),
|
||||||
Operand::None => print_help_error("Operation not specified."),
|
_ => print_help_error(arguments.invalid_operand()),
|
||||||
_ => arguments.invalid_operand(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,13 +20,16 @@ lazy_static! {
|
||||||
|
|
||||||
pub fn help(mut args: Arguments) {
|
pub fn help(mut args: Arguments) {
|
||||||
let help = ascertain_help(&mut args);
|
let help = ascertain_help(&mut args);
|
||||||
|
|
||||||
for topic in help.0 {
|
match help {
|
||||||
topic.display(help.1);
|
Ok(help) => for topic in help.0 {
|
||||||
|
topic.display(help.1);
|
||||||
|
}
|
||||||
|
Err(err) => print_help_error(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ascertain_help<'a>(args: &mut Arguments) -> (IndexSet<&'a HelpTopic>, &'a HelpLayout) {
|
fn ascertain_help<'a>(args: &mut Arguments) -> Result<(IndexSet<&'a HelpTopic>, &'a HelpLayout), String> {
|
||||||
let mut layout = match is_color_terminal() {
|
let mut layout = match is_color_terminal() {
|
||||||
true => &HelpLayout::Console, false => &HelpLayout::Dumb,
|
true => &HelpLayout::Console, false => &HelpLayout::Dumb,
|
||||||
};
|
};
|
||||||
|
@ -75,8 +78,9 @@ fn ascertain_help<'a>(args: &mut Arguments) -> (IndexSet<&'a HelpTopic>, &'a Hel
|
||||||
| Operand::LongPos("help", "all")
|
| Operand::LongPos("help", "all")
|
||||||
| Operand::Short('a')
|
| Operand::Short('a')
|
||||||
| Operand::Long("all") => topic.extend(HELP_ALL.iter()),
|
| Operand::Long("all") => topic.extend(HELP_ALL.iter()),
|
||||||
Operand::ShortPos('h', topic) | Operand::LongPos("help", topic) => print_help_error(format!("Topic '{topic}' is not available.")),
|
Operand::ShortPos('h', topic)
|
||||||
_ => args.invalid_operand(),
|
| Operand::LongPos("help", topic) => Err(format!("Topic '{topic}' is not available."))?,
|
||||||
|
_ => Err(args.invalid_operand())?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +88,7 @@ fn ascertain_help<'a>(args: &mut Arguments) -> (IndexSet<&'a HelpTopic>, &'a Hel
|
||||||
let start = if more || len == 1 || len > 7 { 0 } else { 1 };
|
let start = if more || len == 1 || len > 7 { 0 } else { 1 };
|
||||||
|
|
||||||
args.set_index(1);
|
args.set_index(1);
|
||||||
(topic.drain(start..).collect(), layout)
|
Ok((topic.drain(start..).collect(), layout))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn minimal(args: &mut Arguments) -> bool {
|
fn minimal(args: &mut Arguments) -> bool {
|
||||||
|
@ -203,7 +207,6 @@ fn default(layout: &HelpLayout) {
|
||||||
println!("# {name} 1 \"{version}-{suffix} ({timestamp})\" {name} \"User Manual\"\n");
|
println!("# {name} 1 \"{version}-{suffix} ({timestamp})\" {name} \"User Manual\"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
println!("{head}NAME{reset}
|
println!("{head}NAME{reset}
|
||||||
{tab}pacwrap - Command-line application which facilitates the creation, management, and execution of unprivileged,
|
{tab}pacwrap - Command-line application which facilitates the creation, management, and execution of unprivileged,
|
||||||
{tab}Sandboxed containers with bubblewrap and libalpm.
|
{tab}Sandboxed containers with bubblewrap and libalpm.
|
||||||
|
@ -271,6 +274,7 @@ fn meta(layout: &HelpLayout) {
|
||||||
|
|
||||||
fn sync(layout: &HelpLayout) {
|
fn sync(layout: &HelpLayout) {
|
||||||
let head = layout.head();
|
let head = layout.head();
|
||||||
|
let bold = layout.bold();
|
||||||
let sub = layout.sub();
|
let sub = layout.sub();
|
||||||
let sub_text = layout.sub_text();
|
let sub_text = layout.sub_text();
|
||||||
let reset = layout.reset();
|
let reset = layout.reset();
|
||||||
|
@ -287,6 +291,18 @@ fn sync(layout: &HelpLayout) {
|
||||||
{sub}-f, --filesystem{reset_bold}
|
{sub}-f, --filesystem{reset_bold}
|
||||||
{sub_text}Force execution of filesystem synchronization coroutines on all or specified containers.
|
{sub_text}Force execution of filesystem synchronization coroutines on all or specified containers.
|
||||||
|
|
||||||
|
{sub}-c, --create{reset_bold}
|
||||||
|
{sub_text}Create a container with the first specified target. Providing a container type argument is also required.
|
||||||
|
|
||||||
|
{sub}-b, --base{reset_bold}
|
||||||
|
{sub_text}Base container type. Specify alongside {bold}-c, --create{reset_bold} to assign container type during creation.
|
||||||
|
|
||||||
|
{sub}-d, --slice{reset_bold}
|
||||||
|
{sub_text}Slice container type. Specify alongside {bold}-c, --create{reset_bold} to to assign container type during creation.
|
||||||
|
|
||||||
|
{sub}-r, --root{reset_bold}
|
||||||
|
{sub_text}Root container type. Specify alongside {bold}-c, --create{reset_bold} to assign container type during creation.
|
||||||
|
|
||||||
{sub}--dbonly{reset_bold}
|
{sub}--dbonly{reset_bold}
|
||||||
{sub_text}Transact on resident containers with a database-only transaction.
|
{sub_text}Transact on resident containers with a database-only transaction.
|
||||||
|
|
||||||
|
@ -294,7 +310,11 @@ fn sync(layout: &HelpLayout) {
|
||||||
{sub_text}Force synchronization of foreign packages on resident container.
|
{sub_text}Force synchronization of foreign packages on resident container.
|
||||||
|
|
||||||
{sub}--dbonly{reset_bold}
|
{sub}--dbonly{reset_bold}
|
||||||
{sub_text}Override confirmation prompts and confirm all operations.\n");
|
{sub_text}Override confirmation prompts and confirm all operations.
|
||||||
|
|
||||||
|
{sub}-t, --target=TARGET{reset_bold}
|
||||||
|
{sub_text}Specify a target container for the specified operation.\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process(layout: &HelpLayout) {
|
fn process(layout: &HelpLayout) {
|
||||||
|
@ -346,6 +366,7 @@ fn copyright(layout: &HelpLayout) {
|
||||||
let tab = layout.tab();
|
let tab = layout.tab();
|
||||||
|
|
||||||
println!("{head}COPYRIGHT{reset}
|
println!("{head}COPYRIGHT{reset}
|
||||||
|
|
||||||
{sub_text}Copyright (C) 2023 - Xavier R.M.
|
{sub_text}Copyright (C) 2023 - Xavier R.M.
|
||||||
|
|
||||||
{tab}This program may be freely redistributed under
|
{tab}This program may be freely redistributed under
|
||||||
|
@ -369,7 +390,7 @@ pub fn print_version(mut args: Arguments) {
|
||||||
[0m[38;2;76;67;47mA[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;227;202;134mC[0m[38;2;234;216;99m#[0m[38;2;241;229;68m#[0m[38;2;243;232;67m#[0m[38;2;238;222;99m#[0m[38;2;231;209;137m#[0m[38;2;230;206;146mC[0m[38;2;230;206;146mC[0m[38;2;230;206;146mC[0m[38;2;230;206;146mC[0m[38;2;230;206;146mC[0m[38;2;234;216;169m#[0m[38;2;249;249;248m#[0m[38;2;249;249;249m#[0m[38;2;249;249;249m#[0m[38;2;249;249;249m#[0m[38;2;237;222;184m#[0m[38;2;230;202;139mC[0m[38;2;240;227;197m#[0m[38;2;249;249;249m#[0m[38;2;249;249;249m#[0m[38;2;249;249;249m#[0m[38;2;249;249;248m#[0m[38;2;233;210;158m#[0m[38;2;229;201;137mC[0m[38;2;235;218;175m#[0m[38;2;236;223;187m#[0m[38;2;232;214;165m#[0m[38;2;227;205;143mC[0m[38;2;223;198;126mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;112;99;64mP[0m
|
[0m[38;2;76;67;47mA[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;227;202;134mC[0m[38;2;234;216;99m#[0m[38;2;241;229;68m#[0m[38;2;243;232;67m#[0m[38;2;238;222;99m#[0m[38;2;231;209;137m#[0m[38;2;230;206;146mC[0m[38;2;230;206;146mC[0m[38;2;230;206;146mC[0m[38;2;230;206;146mC[0m[38;2;230;206;146mC[0m[38;2;234;216;169m#[0m[38;2;249;249;248m#[0m[38;2;249;249;249m#[0m[38;2;249;249;249m#[0m[38;2;249;249;249m#[0m[38;2;237;222;184m#[0m[38;2;230;202;139mC[0m[38;2;240;227;197m#[0m[38;2;249;249;249m#[0m[38;2;249;249;249m#[0m[38;2;249;249;249m#[0m[38;2;249;249;248m#[0m[38;2;233;210;158m#[0m[38;2;229;201;137mC[0m[38;2;235;218;175m#[0m[38;2;236;223;187m#[0m[38;2;232;214;165m#[0m[38;2;227;205;143mC[0m[38;2;223;198;126mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;112;99;64mP[0m
|
||||||
[0m[38;2;76;67;47mA[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;227;204;130mC[0m[38;2;236;220;89m#[0m[38;2;246;238;45m#[0m[38;2;250;244;31m#[0m[38;2;246;238;51m#[0m[38;2;242;230;73m#[0m[38;2;234;214;123m#[0m[38;2;230;206;146mC[0m[38;2;230;206;147mC[0m[38;2;236;220;181m#[0m[38;2;241;231;207m#[0m[38;2;241;231;208m#[0m[38;2;236;221;184m#[0m[38;2;228;204;143mC[0m[38;2;228;202;138mC[0m[38;2;230;204;144mC[0m[38;2;237;221;182m#[0m[38;2;238;227;196m#[0m[38;2;234;219;178m#[0m[38;2;229;209;152m#[0m[38;2;223;197;124mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;112;99;64mP[0m
|
[0m[38;2;76;67;47mA[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;227;204;130mC[0m[38;2;236;220;89m#[0m[38;2;246;238;45m#[0m[38;2;250;244;31m#[0m[38;2;246;238;51m#[0m[38;2;242;230;73m#[0m[38;2;234;214;123m#[0m[38;2;230;206;146mC[0m[38;2;230;206;147mC[0m[38;2;236;220;181m#[0m[38;2;241;231;207m#[0m[38;2;241;231;208m#[0m[38;2;236;221;184m#[0m[38;2;228;204;143mC[0m[38;2;228;202;138mC[0m[38;2;230;204;144mC[0m[38;2;237;221;182m#[0m[38;2;238;227;196m#[0m[38;2;234;219;178m#[0m[38;2;229;209;152m#[0m[38;2;223;197;124mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;112;99;64mP[0m
|
||||||
[0m[38;2;76;67;47mA[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;230;209;117mC[0m[38;2;240;228;70m#[0m[38;2;244;234;58m#[0m[38;2;230;207;134mC[0m[38;2;228;203;141mC[0m[38;2;227;202;139mC[0m[38;2;226;202;138mC[0m[38;2;226;201;136mC[0m[38;2;225;200;133mC[0m[38;2;225;199;131mC[0m[38;2;224;198;128mC[0m[38;2;224;198;126mC[0m[38;2;223;197;124mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;112;99;64mP[0m Website: https://pacwrap.sapphirus.org/
|
[0m[38;2;76;67;47mA[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;230;209;117mC[0m[38;2;240;228;70m#[0m[38;2;244;234;58m#[0m[38;2;230;207;134mC[0m[38;2;228;203;141mC[0m[38;2;227;202;139mC[0m[38;2;226;202;138mC[0m[38;2;226;201;136mC[0m[38;2;225;200;133mC[0m[38;2;225;199;131mC[0m[38;2;224;198;128mC[0m[38;2;224;198;126mC[0m[38;2;223;197;124mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;112;99;64mP[0m Website: https://pacwrap.sapphirus.org/
|
||||||
[0m[38;2;76;67;47mA[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;225;199;132mC[0m[38;2;224;198;128mC[0m[38;2;223;197;125mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;112;99;63mP[0m Github: https;//git.sapphirus.org/
|
[0m[38;2;76;67;47mA[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;225;199;132mC[0m[38;2;224;198;128mC[0m[38;2;223;197;125mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;112;99;63mP[0m Github: https://github.com/sapphirusberyl/pacwrap
|
||||||
[0m[38;2;76;67;47mA[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;224;198;128mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;112;99;63mP[0m
|
[0m[38;2;76;67;47mA[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;224;198;128mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;112;99;63mP[0m
|
||||||
[0m[38;2;56;50;35mA[0m[38;2;218;194;133mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;224;198;128mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;112;99;63mP[0m
|
[0m[38;2;56;50;35mA[0m[38;2;218;194;133mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;224;198;128mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;112;99;63mP[0m
|
||||||
[0m[38;2;31;27;20mR[0m[38;2;141;125;87mP[0m[38;2;221;197;135mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;224;198;128mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;116;103;66mP[0m This program may be freely redistributed under
|
[0m[38;2;31;27;20mR[0m[38;2;141;125;87mP[0m[38;2;221;197;135mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;226;201;137mC[0m[38;2;224;198;128mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;223;197;123mC[0m[38;2;116;103;66mP[0m This program may be freely redistributed under
|
||||||
|
|
53
src/sync.rs
53
src/sync.rs
|
@ -63,19 +63,24 @@ pub fn synchronize(mut args: Arguments) {
|
||||||
TransactionType::Upgrade(u > 0, y > 0, y > 1)
|
TransactionType::Upgrade(u > 0, y > 0, y > 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(instype) = create_type(&mut args) {
|
match create_type(&mut args) {
|
||||||
if let TransactionType::Upgrade(upgrade, refresh, _) = action {
|
Ok(option) => if let Some(instype) = option {
|
||||||
if ! upgrade {
|
if let TransactionType::Upgrade(upgrade, refresh, _) = action {
|
||||||
print_help_error("--upgrade/-u not supplied with --create/-c.");
|
if ! upgrade {
|
||||||
} else if ! refresh {
|
print_help_error("--upgrade/-u not supplied with --create/-c.");
|
||||||
print_help_error("--refresh/-y not supplied with --create/-c.");
|
} else if ! refresh {
|
||||||
|
print_help_error("--refresh/-y not supplied with --create/-c.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
create(instype, args.targets());
|
create(instype, args.targets());
|
||||||
|
},
|
||||||
|
Err(error) => print_help_error(error),
|
||||||
}
|
}
|
||||||
|
|
||||||
aggregator::upgrade(action, &mut args, &mut cache, &mut logger).aggregate(&mut InstanceCache::new());
|
match aggregator::upgrade(action, &mut args, &mut cache, &mut logger) {
|
||||||
|
Ok(ag) => ag.aggregate(&mut InstanceCache::new()), Err(e) => print_help_error(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove(mut args: Arguments) {
|
pub fn remove(mut args: Arguments) {
|
||||||
|
@ -96,10 +101,12 @@ pub fn remove(mut args: Arguments) {
|
||||||
TransactionType::Remove(recursive > 0 , cascade, recursive > 1)
|
TransactionType::Remove(recursive > 0 , cascade, recursive > 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
aggregator::remove(action, &mut args, &mut cache, &mut logger).aggregate(&mut InstanceCache::new());
|
match aggregator::remove(action, &mut args, &mut cache, &mut logger) {
|
||||||
|
Ok(ag) => ag.aggregate(&mut InstanceCache::new()), Err(e) => print_help_error(e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_type(args: &mut Arguments) -> Option<InstanceType> {
|
fn create_type<'a>(args: &mut Arguments) -> Result<Option<InstanceType>, &'a str> {
|
||||||
let mut instype = None;
|
let mut instype = None;
|
||||||
let mut create = false;
|
let mut create = false;
|
||||||
|
|
||||||
|
@ -108,14 +115,28 @@ fn create_type(args: &mut Arguments) -> Option<InstanceType> {
|
||||||
while let Some(arg) = args.next() {
|
while let Some(arg) = args.next() {
|
||||||
match arg {
|
match arg {
|
||||||
Operand::Short('c') | Operand::Long("create") => create = true,
|
Operand::Short('c') | Operand::Long("create") => create = true,
|
||||||
Operand::Short('b') | Operand::Long("base") => instype = Some(InstanceType::BASE),
|
Operand::Short('b') | Operand::Long("base") => match instype {
|
||||||
Operand::Short('d') | Operand::Long("slice") => instype = Some(InstanceType::DEP),
|
None => instype = Some(InstanceType::BASE),
|
||||||
Operand::Short('r') | Operand::Long("root") => instype = Some(InstanceType::ROOT),
|
Some(_) => Err("Multiple container types cannot be assigned to a container.")?,
|
||||||
|
},
|
||||||
|
Operand::Short('d') | Operand::Long("slice") => match instype {
|
||||||
|
None => instype = Some(InstanceType::DEP),
|
||||||
|
Some(_) => Err("Multiple container types cannot be assigned to a container.")?,
|
||||||
|
},
|
||||||
|
Operand::Short('r') | Operand::Long("root") => match instype {
|
||||||
|
None => instype = Some(InstanceType::ROOT),
|
||||||
|
Some(_) => Err("Multiple container types cannot be assigned to a container.")?,
|
||||||
|
},
|
||||||
_ => continue,
|
_ => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if create { instype } else { None }
|
match create {
|
||||||
|
true => match instype {
|
||||||
|
None => Err("Instance type not specified"), Some(_) => Ok(instype),
|
||||||
|
},
|
||||||
|
false => Ok(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create(instype: InstanceType, mut targets: Vec<&str>) {
|
pub fn create(instype: InstanceType, mut targets: Vec<&str>) {
|
||||||
|
@ -199,7 +220,7 @@ pub fn query(mut arguments: Arguments) {
|
||||||
Operand::Short('e') | Operand::Long("explicit") => explicit = true,
|
Operand::Short('e') | Operand::Long("explicit") => explicit = true,
|
||||||
Operand::Short('q') | Operand::Long("quiet") => quiet = true,
|
Operand::Short('q') | Operand::Long("quiet") => quiet = true,
|
||||||
Operand::LongPos("target", t) | Operand::ShortPos(_, t) => target = t,
|
Operand::LongPos("target", t) | Operand::ShortPos(_, t) => target = t,
|
||||||
_ => arguments.invalid_operand(),
|
_ => print_help_error(arguments.invalid_operand()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,7 @@ use crate::sync::{self,
|
||||||
use crate::config::{InstanceHandle,
|
use crate::config::{InstanceHandle,
|
||||||
InstanceType::ROOT,
|
InstanceType::ROOT,
|
||||||
cache::InstanceCache};
|
cache::InstanceCache};
|
||||||
use crate::utils::{Arguments, print_help_error};
|
use crate::utils::{arguments::Operand, Arguments};
|
||||||
use crate::utils::arguments::Operand;
|
|
||||||
use super::{
|
use super::{
|
||||||
Transaction,
|
Transaction,
|
||||||
TransactionHandle,
|
TransactionHandle,
|
||||||
|
@ -190,7 +189,7 @@ impl <'a>TransactionAggregator<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove<'a>(action_type: TransactionType, args: &'a mut Arguments, inscache: &'a mut InstanceCache, log: &'a mut Logger) -> TransactionAggregator<'a> {
|
pub fn remove<'a>(action_type: TransactionType, args: &'a mut Arguments, inscache: &'a mut InstanceCache, log: &'a mut Logger) -> Result<TransactionAggregator<'a>, String> {
|
||||||
let mut action_flags = TransactionFlags::NONE;
|
let mut action_flags = TransactionFlags::NONE;
|
||||||
let mut targets = Vec::new();
|
let mut targets = Vec::new();
|
||||||
let mut queue: HashMap<Rc<str>,Vec<Rc<str>>> = HashMap::new();
|
let mut queue: HashMap<Rc<str>,Vec<Rc<str>>> = HashMap::new();
|
||||||
|
@ -199,7 +198,7 @@ pub fn remove<'a>(action_type: TransactionType, args: &'a mut Arguments, inscach
|
||||||
args.set_index(1);
|
args.set_index(1);
|
||||||
|
|
||||||
if let Operand::None = args.next().unwrap_or_default() {
|
if let Operand::None = args.next().unwrap_or_default() {
|
||||||
print_help_error("Operation not specified.");
|
Err("Operation not specified.")?
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Some(arg) = args.next() {
|
while let Some(arg) = args.next() {
|
||||||
|
@ -228,12 +227,12 @@ pub fn remove<'a>(action_type: TransactionType, args: &'a mut Arguments, inscach
|
||||||
None => { queue.insert(current_target.into(), vec!(package.into())); },
|
None => { queue.insert(current_target.into(), vec!(package.into())); },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => args.invalid_operand(),
|
_ => Err(args.invalid_operand())?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if current_target == "" {
|
if current_target == "" {
|
||||||
print_help_error("Target not specified");
|
Err("Target not specified")?
|
||||||
}
|
}
|
||||||
|
|
||||||
let current_target = Some(current_target);
|
let current_target = Some(current_target);
|
||||||
|
@ -244,7 +243,7 @@ pub fn remove<'a>(action_type: TransactionType, args: &'a mut Arguments, inscach
|
||||||
inscache.populate();
|
inscache.populate();
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionAggregator {
|
Ok(TransactionAggregator {
|
||||||
queried: Vec::new(),
|
queried: Vec::new(),
|
||||||
updated: Vec::new(),
|
updated: Vec::new(),
|
||||||
pkg_queue: queue,
|
pkg_queue: queue,
|
||||||
|
@ -255,10 +254,10 @@ pub fn remove<'a>(action_type: TransactionType, args: &'a mut Arguments, inscach
|
||||||
logger: log,
|
logger: log,
|
||||||
flags: action_flags,
|
flags: action_flags,
|
||||||
target: current_target,
|
target: current_target,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn upgrade<'a>(action_type: TransactionType, args: &'a mut Arguments, inscache: &'a mut InstanceCache, log: &'a mut Logger) -> TransactionAggregator<'a> {
|
pub fn upgrade<'a>(action_type: TransactionType, args: &'a mut Arguments, inscache: &'a mut InstanceCache, log: &'a mut Logger) -> Result<TransactionAggregator<'a>, String> {
|
||||||
let mut action_flags = TransactionFlags::NONE;
|
let mut action_flags = TransactionFlags::NONE;
|
||||||
let mut targets = Vec::new();
|
let mut targets = Vec::new();
|
||||||
let mut queue: HashMap<Rc<str>,Vec<Rc<str>>> = HashMap::new();
|
let mut queue: HashMap<Rc<str>,Vec<Rc<str>>> = HashMap::new();
|
||||||
|
@ -269,7 +268,7 @@ pub fn upgrade<'a>(action_type: TransactionType, args: &'a mut Arguments, inscac
|
||||||
args.set_index(2);
|
args.set_index(2);
|
||||||
|
|
||||||
if let Operand::None = args.next().unwrap_or_default() {
|
if let Operand::None = args.next().unwrap_or_default() {
|
||||||
print_help_error("Operation not specified.");
|
Err("Operation not specified.")?
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Some(arg) = args.next() {
|
while let Some(arg) = args.next() {
|
||||||
|
@ -307,15 +306,14 @@ pub fn upgrade<'a>(action_type: TransactionType, args: &'a mut Arguments, inscac
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Operand::None => println!("none"),
|
_ => Err(args.invalid_operand())?,
|
||||||
_ => args.invalid_operand(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let current_target = match target_only {
|
let current_target = match target_only {
|
||||||
true => {
|
true => {
|
||||||
if current_target == "" {
|
if current_target == "" {
|
||||||
print_help_error("Target not specified");
|
Err("Target not specified")?
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(current_target)
|
Some(current_target)
|
||||||
|
@ -329,7 +327,7 @@ pub fn upgrade<'a>(action_type: TransactionType, args: &'a mut Arguments, inscac
|
||||||
inscache.populate();
|
inscache.populate();
|
||||||
}
|
}
|
||||||
|
|
||||||
TransactionAggregator {
|
Ok(TransactionAggregator {
|
||||||
queried: Vec::new(),
|
queried: Vec::new(),
|
||||||
updated: Vec::new(),
|
updated: Vec::new(),
|
||||||
pkg_queue: queue,
|
pkg_queue: queue,
|
||||||
|
@ -340,5 +338,5 @@ pub fn upgrade<'a>(action_type: TransactionType, args: &'a mut Arguments, inscac
|
||||||
logger: log,
|
logger: log,
|
||||||
flags: action_flags,
|
flags: action_flags,
|
||||||
target: current_target,
|
target: current_target,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,10 +105,10 @@ impl<'a> Arguments<'a> {
|
||||||
self.cur = index;
|
self.cur = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn invalid_operand(&self) {
|
pub fn invalid_operand(&self) -> String {
|
||||||
match self.operands.get(self.cur) {
|
match self.operands.get(self.cur) {
|
||||||
Some(oper) => print_help_error(&format!("Invalid option -- '{}'", oper)),
|
Some(oper) => format!("Invalid option -- '{}'", oper),
|
||||||
None => print_help_error(&format!("Operation not specified.")),
|
None => format!("Operation not specified."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue