cli: Add `rad config` command
Displays the current configuration. Also move to our tree-sitter highlighter for pretty-printing JSON and remove the `json-color` dependency.
This commit is contained in:
parent
59a08f21a4
commit
ad7a3addb6
|
|
@ -1668,17 +1668,6 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "json-color"
|
|
||||||
version = "0.7.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e6dc8c55175cad7234a98cc3e31ba3009e276800271692ed3ad2c2f1c574b6e8"
|
|
||||||
dependencies = [
|
|
||||||
"colored",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "keccak"
|
name = "keccak"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
|
|
@ -2298,7 +2287,6 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
"git-ref-format",
|
"git-ref-format",
|
||||||
"json-color",
|
|
||||||
"lexopt",
|
"lexopt",
|
||||||
"localtime",
|
"localtime",
|
||||||
"log",
|
"log",
|
||||||
|
|
@ -2326,6 +2314,7 @@ dependencies = [
|
||||||
"tree-sitter-go",
|
"tree-sitter-go",
|
||||||
"tree-sitter-highlight",
|
"tree-sitter-highlight",
|
||||||
"tree-sitter-html",
|
"tree-sitter-html",
|
||||||
|
"tree-sitter-json",
|
||||||
"tree-sitter-md",
|
"tree-sitter-md",
|
||||||
"tree-sitter-python",
|
"tree-sitter-python",
|
||||||
"tree-sitter-ruby",
|
"tree-sitter-ruby",
|
||||||
|
|
@ -3540,6 +3529,16 @@ dependencies = [
|
||||||
"tree-sitter",
|
"tree-sitter",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tree-sitter-json"
|
||||||
|
version = "0.20.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "50d82d2e33ee675dc71289e2ace4f8f9cf96d36d81400e9dae5ea61edaf5dea6"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"tree-sitter",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tree-sitter-md"
|
name = "tree-sitter-md"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
|
@ -3592,9 +3591,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tree-sitter-typescript"
|
name = "tree-sitter-typescript"
|
||||||
version = "0.20.2"
|
version = "0.20.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "079c695c32d39ad089101c66393aeaca30e967fba3486a91f573d2f0e12d290a"
|
checksum = "a75049f0aafabb2aac205d7bb24da162b53dcd0cfb326785f25a2f32efa8071a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"tree-sitter",
|
"tree-sitter",
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ path = "src/main.rs"
|
||||||
anyhow = { version = "1" }
|
anyhow = { version = "1" }
|
||||||
chrono = { version = "0.4.26", default-features = false, features = ["clock", "std"] }
|
chrono = { version = "0.4.26", default-features = false, features = ["clock", "std"] }
|
||||||
git-ref-format = { version = "0.3.0", features = ["macro"] }
|
git-ref-format = { version = "0.3.0", features = ["macro"] }
|
||||||
json-color = { version = "0.7" }
|
|
||||||
lexopt = { version = "0.2" }
|
lexopt = { version = "0.2" }
|
||||||
localtime = { version = "1.2.0" }
|
localtime = { version = "1.2.0" }
|
||||||
log = { version = "0.4", features = ["std"] }
|
log = { version = "0.4", features = ["std"] }
|
||||||
|
|
@ -32,8 +31,9 @@ thiserror = { version = "1" }
|
||||||
timeago = { version = "0.3", default-features = false }
|
timeago = { version = "0.3", default-features = false }
|
||||||
tree-sitter = { version = "0.20.0" }
|
tree-sitter = { version = "0.20.0" }
|
||||||
tree-sitter-highlight = { version = "0.20" }
|
tree-sitter-highlight = { version = "0.20" }
|
||||||
|
tree-sitter-json = { version = "0.20.1" }
|
||||||
tree-sitter-rust = { version = "0.20" }
|
tree-sitter-rust = { version = "0.20" }
|
||||||
tree-sitter-typescript = { version = "0.20" }
|
tree-sitter-typescript = { version = "0.20.3" }
|
||||||
# N.b. This crate has a C++ token scanner that causes problems when building
|
# N.b. This crate has a C++ token scanner that causes problems when building
|
||||||
# for the musl target. Hence it is optional for now.
|
# for the musl target. Hence it is optional for now.
|
||||||
tree-sitter-html = { version = "0.19", optional = true }
|
tree-sitter-html = { version = "0.19", optional = true }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
The `rad config` command is used to manage the local user configuration.
|
||||||
|
In its simplest form, `rad config` prints the current configuration.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ rad config
|
||||||
|
{
|
||||||
|
"publicExplorer": "https://app.radicle.xyz/nodes/$host/$rid",
|
||||||
|
"preferredSeeds": [],
|
||||||
|
"cli": {
|
||||||
|
"hints": false
|
||||||
|
},
|
||||||
|
"node": {
|
||||||
|
"alias": "alice",
|
||||||
|
"listen": [],
|
||||||
|
"peers": {
|
||||||
|
"type": "dynamic",
|
||||||
|
"target": 8
|
||||||
|
},
|
||||||
|
"connect": [],
|
||||||
|
"externalAddresses": [],
|
||||||
|
"network": "main",
|
||||||
|
"relay": true,
|
||||||
|
"limits": {
|
||||||
|
"routingMaxSize": 1000,
|
||||||
|
"routingMaxAge": 604800,
|
||||||
|
"gossipMaxAge": 1209600,
|
||||||
|
"fetchConcurrency": 1,
|
||||||
|
"rate": {
|
||||||
|
"inbound": {
|
||||||
|
"fillRate": 0.2,
|
||||||
|
"capacity": 32
|
||||||
|
},
|
||||||
|
"outbound": {
|
||||||
|
"fillRate": 1.0,
|
||||||
|
"capacity": 64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"policy": "block",
|
||||||
|
"scope": "trusted"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -10,6 +10,8 @@ pub mod rad_clean;
|
||||||
pub mod rad_clone;
|
pub mod rad_clone;
|
||||||
#[path = "commands/cob.rs"]
|
#[path = "commands/cob.rs"]
|
||||||
pub mod rad_cob;
|
pub mod rad_cob;
|
||||||
|
#[path = "commands/config.rs"]
|
||||||
|
pub mod rad_config;
|
||||||
#[path = "commands/diff.rs"]
|
#[path = "commands/diff.rs"]
|
||||||
pub mod rad_diff;
|
pub mod rad_diff;
|
||||||
#[path = "commands/fork.rs"]
|
#[path = "commands/fork.rs"]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
#![allow(clippy::or_fun_call)]
|
||||||
|
use std::ffi::OsString;
|
||||||
|
|
||||||
|
use anyhow::anyhow;
|
||||||
|
|
||||||
|
use crate::terminal as term;
|
||||||
|
use crate::terminal::args::{Args, Error, Help};
|
||||||
|
use crate::terminal::Element as _;
|
||||||
|
|
||||||
|
pub const HELP: Help = Help {
|
||||||
|
name: "config",
|
||||||
|
description: "Manage your local radicle configuration",
|
||||||
|
version: env!("CARGO_PKG_VERSION"),
|
||||||
|
usage: r#"
|
||||||
|
Usage
|
||||||
|
|
||||||
|
rad config [<option>...]
|
||||||
|
|
||||||
|
If no argument is specified, prints the current radicle configuration as JSON.
|
||||||
|
|
||||||
|
Options
|
||||||
|
|
||||||
|
--help Print help
|
||||||
|
|
||||||
|
"#,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Options {}
|
||||||
|
|
||||||
|
impl Args for Options {
|
||||||
|
fn from_args(args: Vec<OsString>) -> anyhow::Result<(Self, Vec<OsString>)> {
|
||||||
|
use lexopt::prelude::*;
|
||||||
|
|
||||||
|
let mut parser = lexopt::Parser::from_args(args);
|
||||||
|
|
||||||
|
#[allow(clippy::never_loop)]
|
||||||
|
while let Some(arg) = parser.next()? {
|
||||||
|
match arg {
|
||||||
|
Long("help") | Short('h') => {
|
||||||
|
return Err(Error::Help.into());
|
||||||
|
}
|
||||||
|
_ => return Err(anyhow!(arg.unexpected())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok((Options {}, vec![]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(_options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||||
|
let profile = ctx.profile()?;
|
||||||
|
let path = profile.home.config();
|
||||||
|
let output = term::json::to_pretty(&profile.config, path.as_path())?;
|
||||||
|
|
||||||
|
output.print();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
#![allow(clippy::or_fun_call)]
|
#![allow(clippy::or_fun_call)]
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use anyhow::{anyhow, Context as _};
|
use anyhow::{anyhow, Context as _};
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use json_color::{Color, Colorizer};
|
|
||||||
|
|
||||||
use radicle::identity::Id;
|
use radicle::identity::Id;
|
||||||
use radicle::identity::Identity;
|
use radicle::identity::Identity;
|
||||||
|
|
@ -14,9 +13,11 @@ use radicle::node::tracking::Policy;
|
||||||
use radicle::node::AliasStore as _;
|
use radicle::node::AliasStore as _;
|
||||||
use radicle::storage::refs::RefsAt;
|
use radicle::storage::refs::RefsAt;
|
||||||
use radicle::storage::{ReadRepository, ReadStorage};
|
use radicle::storage::{ReadRepository, ReadStorage};
|
||||||
|
use radicle_term::Element;
|
||||||
|
|
||||||
use crate::terminal as term;
|
use crate::terminal as term;
|
||||||
use crate::terminal::args::{Args, Error, Help};
|
use crate::terminal::args::{Args, Error, Help};
|
||||||
|
use crate::terminal::json;
|
||||||
|
|
||||||
pub const HELP: Help = Help {
|
pub const HELP: Help = Help {
|
||||||
name: "inspect",
|
name: "inspect",
|
||||||
|
|
@ -154,16 +155,10 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||||
refs(&repo)?;
|
refs(&repo)?;
|
||||||
}
|
}
|
||||||
Target::Payload => {
|
Target::Payload => {
|
||||||
println!(
|
json::to_pretty(&project.payload, Path::new("radicle.json"))?.print();
|
||||||
"{}",
|
|
||||||
colorizer().colorize_json_str(&serde_json::to_string_pretty(&project.payload)?)?
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Target::Identity => {
|
Target::Identity => {
|
||||||
println!(
|
json::to_pretty(&project.doc, Path::new("radicle.json"))?.print();
|
||||||
"{}",
|
|
||||||
colorizer().colorize_json_str(&serde_json::to_string_pretty(&project.doc)?)?
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Target::Sigrefs => {
|
Target::Sigrefs => {
|
||||||
for remote in repo.remote_ids()? {
|
for remote in repo.remote_ids()? {
|
||||||
|
|
@ -265,11 +260,10 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||||
}
|
}
|
||||||
term::blank();
|
term::blank();
|
||||||
}
|
}
|
||||||
|
for line in json::to_pretty(&doc, Path::new("radicle.json"))? {
|
||||||
let json = colorizer().colorize_json_str(&serde_json::to_string_pretty(&doc)?)?;
|
|
||||||
for line in json.lines() {
|
|
||||||
println!(" {line}");
|
println!(" {line}");
|
||||||
}
|
}
|
||||||
|
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -281,17 +275,6 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used for JSON Colorizing
|
|
||||||
fn colorizer() -> Colorizer {
|
|
||||||
Colorizer::new()
|
|
||||||
.null(Color::Cyan)
|
|
||||||
.boolean(Color::Cyan)
|
|
||||||
.number(Color::Magenta)
|
|
||||||
.string(Color::Green)
|
|
||||||
.key(Color::Blue)
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn refs(repo: &radicle::storage::git::Repository) -> anyhow::Result<()> {
|
fn refs(repo: &radicle::storage::git::Repository) -> anyhow::Result<()> {
|
||||||
let mut refs = Vec::new();
|
let mut refs = Vec::new();
|
||||||
for r in repo.references()? {
|
for r in repo.references()? {
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,13 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option<anyhow::Error>>
|
||||||
args.to_vec(),
|
args.to_vec(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
"config" => {
|
||||||
|
term::run_command_args::<rad_config::Options, _>(
|
||||||
|
rad_config::HELP,
|
||||||
|
rad_config::run,
|
||||||
|
args.to_vec(),
|
||||||
|
);
|
||||||
|
}
|
||||||
"diff" => {
|
"diff" => {
|
||||||
term::run_command_args::<rad_diff::Options, _>(
|
term::run_command_args::<rad_diff::Options, _>(
|
||||||
rad_diff::HELP,
|
rad_diff::HELP,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ pub use io::signer;
|
||||||
pub mod comment;
|
pub mod comment;
|
||||||
pub mod highlight;
|
pub mod highlight;
|
||||||
pub mod issue;
|
pub mod issue;
|
||||||
|
pub mod json;
|
||||||
pub mod patch;
|
pub mod patch;
|
||||||
|
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ const HIGHLIGHTS: &[&str] = &[
|
||||||
"float.literal",
|
"float.literal",
|
||||||
"keyword",
|
"keyword",
|
||||||
"label",
|
"label",
|
||||||
|
"number",
|
||||||
"operator",
|
"operator",
|
||||||
"property",
|
"property",
|
||||||
"punctuation",
|
"punctuation",
|
||||||
|
|
@ -72,12 +73,14 @@ impl Theme {
|
||||||
"keyword" => self.color("red"),
|
"keyword" => self.color("red"),
|
||||||
"comment" => self.color("grey"),
|
"comment" => self.color("grey"),
|
||||||
"constant" => self.color("orange"),
|
"constant" => self.color("orange"),
|
||||||
|
"number" => self.color("blue"),
|
||||||
"string" => self.color("teal"),
|
"string" => self.color("teal"),
|
||||||
|
"string.special" => self.color("green"),
|
||||||
"function" => self.color("purple"),
|
"function" => self.color("purple"),
|
||||||
"operator" => self.color("blue"),
|
"operator" => self.color("blue"),
|
||||||
// Eg. `true` and `false` in rust.
|
// Eg. `true` and `false` in rust.
|
||||||
"constant.builtin" => self.color("blue"),
|
"constant.builtin" => self.color("blue"),
|
||||||
"type.builtin" => self.color("cyan"),
|
"type.builtin" => self.color("teal"),
|
||||||
"punctuation.bracket" | "punctuation.delimiter" => term::Color::default(),
|
"punctuation.bracket" | "punctuation.delimiter" => term::Color::default(),
|
||||||
// Eg. the '#' in Markdown titles.
|
// Eg. the '#' in Markdown titles.
|
||||||
"punctuation.special" => self.color("dim"),
|
"punctuation.special" => self.color("dim"),
|
||||||
|
|
@ -124,14 +127,17 @@ impl Builder {
|
||||||
for event in highlights {
|
for event in highlights {
|
||||||
match event? {
|
match event? {
|
||||||
ts::HighlightEvent::Source { start, end } => {
|
ts::HighlightEvent::Source { start, end } => {
|
||||||
let range = &code[start..end];
|
for (i, byte) in code.iter().enumerate().skip(start).take(end - start) {
|
||||||
|
|
||||||
for byte in range {
|
|
||||||
if *byte == b'\n' {
|
if *byte == b'\n' {
|
||||||
self.advance();
|
self.advance();
|
||||||
// Start on new line.
|
// Start on new line.
|
||||||
self.lines.push(term::Line::from(self.line.clone()));
|
self.lines.push(term::Line::from(self.line.clone()));
|
||||||
self.line.clear();
|
self.line.clear();
|
||||||
|
} else if i == code.len() - 1 {
|
||||||
|
// File has no `\n` at the end.
|
||||||
|
self.label.push(*byte);
|
||||||
|
self.advance();
|
||||||
|
self.lines.push(term::Line::from(self.line.clone()));
|
||||||
} else {
|
} else {
|
||||||
// Add to existing label.
|
// Add to existing label.
|
||||||
self.label.push(*byte);
|
self.label.push(*byte);
|
||||||
|
|
@ -140,10 +146,11 @@ impl Builder {
|
||||||
}
|
}
|
||||||
ts::HighlightEvent::HighlightStart(h) => {
|
ts::HighlightEvent::HighlightStart(h) => {
|
||||||
let name = HIGHLIGHTS[h.0];
|
let name = HIGHLIGHTS[h.0];
|
||||||
|
let style =
|
||||||
|
term::Style::default().fg(theme.highlight(name).unwrap_or_default());
|
||||||
|
|
||||||
self.advance();
|
self.advance();
|
||||||
self.styles
|
self.styles.push(style);
|
||||||
.push(term::Style::default().fg(theme.highlight(name).unwrap_or_default()));
|
|
||||||
}
|
}
|
||||||
ts::HighlightEvent::HighlightEnd => {
|
ts::HighlightEvent::HighlightEnd => {
|
||||||
self.advance();
|
self.advance();
|
||||||
|
|
@ -193,7 +200,8 @@ impl Highlighter {
|
||||||
fn detect(&mut self, path: &Path, _code: &[u8]) -> Option<&mut ts::HighlightConfiguration> {
|
fn detect(&mut self, path: &Path, _code: &[u8]) -> Option<&mut ts::HighlightConfiguration> {
|
||||||
match path.extension().and_then(|e| e.to_str()) {
|
match path.extension().and_then(|e| e.to_str()) {
|
||||||
Some("rs") => self.config("rust"),
|
Some("rs") => self.config("rust"),
|
||||||
Some("ts" | "js" | "json") => self.config("typescript"),
|
Some("ts" | "js") => self.config("typescript"),
|
||||||
|
Some("json") => self.config("json"),
|
||||||
Some("sh" | "bash") => self.config("shell"),
|
Some("sh" | "bash") => self.config("shell"),
|
||||||
Some("md" | "markdown") => self.config("markdown"),
|
Some("md" | "markdown") => self.config("markdown"),
|
||||||
Some("go") => self.config("go"),
|
Some("go") => self.config("go"),
|
||||||
|
|
@ -220,6 +228,15 @@ impl Highlighter {
|
||||||
)
|
)
|
||||||
.expect("Highlighter::config: highlight configuration must be valid")
|
.expect("Highlighter::config: highlight configuration must be valid")
|
||||||
})),
|
})),
|
||||||
|
"json" => Some(self.configs.entry(language).or_insert_with(|| {
|
||||||
|
ts::HighlightConfiguration::new(
|
||||||
|
tree_sitter_json::language(),
|
||||||
|
tree_sitter_json::HIGHLIGHT_QUERY,
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
.expect("Highlighter::config: highlight configuration must be valid")
|
||||||
|
})),
|
||||||
"typescript" => Some(self.configs.entry(language).or_insert_with(|| {
|
"typescript" => Some(self.configs.entry(language).or_insert_with(|| {
|
||||||
ts::HighlightConfiguration::new(
|
ts::HighlightConfiguration::new(
|
||||||
tree_sitter_typescript::language_typescript(),
|
tree_sitter_typescript::language_typescript(),
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use crate::terminal as term;
|
||||||
|
|
||||||
|
/// Pretty-print a JSON value with syntax highlighting.
|
||||||
|
pub fn to_pretty(value: &impl serde::Serialize, path: &Path) -> anyhow::Result<Vec<term::Line>> {
|
||||||
|
let json = serde_json::to_string_pretty(&value)?;
|
||||||
|
let mut highlighter = term::highlight::Highlighter::default();
|
||||||
|
|
||||||
|
if let Some(highlighted) = highlighter.highlight(path, json.as_bytes())? {
|
||||||
|
Ok(highlighted)
|
||||||
|
} else {
|
||||||
|
Ok(json.split('\n').map(term::Line::new).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -193,6 +193,21 @@ fn rad_inspect() {
|
||||||
test("examples/rad-inspect-noauth.md", working.path(), None, []).unwrap();
|
test("examples/rad-inspect-noauth.md", working.path(), None, []).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rad_config() {
|
||||||
|
let mut environment = Environment::new();
|
||||||
|
let profile = environment.profile("alice");
|
||||||
|
let working = tempfile::tempdir().unwrap();
|
||||||
|
|
||||||
|
test(
|
||||||
|
"examples/rad-config.md",
|
||||||
|
working.path(),
|
||||||
|
Some(&profile.home),
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rad_checkout() {
|
fn rad_checkout() {
|
||||||
let mut environment = Environment::new();
|
let mut environment = Environment::new();
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,7 @@ impl Environment {
|
||||||
node: node::Config::new(alias.clone()),
|
node: node::Config::new(alias.clone()),
|
||||||
cli: cli::Config { hints: false },
|
cli: cli::Config { hints: false },
|
||||||
public_explorer: profile::Explorer::default(),
|
public_explorer: profile::Explorer::default(),
|
||||||
|
preferred_seeds: vec![],
|
||||||
};
|
};
|
||||||
config.write(&home.config()).unwrap();
|
config.write(&home.config()).unwrap();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -291,6 +291,26 @@ impl Element for Line {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Element for Vec<Line> {
|
||||||
|
fn size(&self, parent: Constraint) -> Size {
|
||||||
|
let width = self
|
||||||
|
.iter()
|
||||||
|
.map(|e| e.columns(parent))
|
||||||
|
.max()
|
||||||
|
.unwrap_or_default();
|
||||||
|
let height = self.len();
|
||||||
|
|
||||||
|
Size::new(width, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&self, parent: Constraint) -> Vec<Line> {
|
||||||
|
self.iter()
|
||||||
|
.cloned()
|
||||||
|
.flat_map(|l| l.render(parent))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for Line {
|
impl fmt::Display for Line {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
for item in &self.items {
|
for item in &self.items {
|
||||||
|
|
|
||||||
|
|
@ -163,11 +163,6 @@ pub enum ConfigError {
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// Node configuration.
|
|
||||||
pub node: node::Config,
|
|
||||||
/// CLI configuration.
|
|
||||||
#[serde(default)]
|
|
||||||
pub cli: cli::Config,
|
|
||||||
/// Public explorer. This is used for generating links.
|
/// Public explorer. This is used for generating links.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub public_explorer: Explorer,
|
pub public_explorer: Explorer,
|
||||||
|
|
@ -175,16 +170,21 @@ pub struct Config {
|
||||||
/// and in other situations when a seed needs to be chosen.
|
/// and in other situations when a seed needs to be chosen.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub preferred_seeds: Vec<node::config::ConnectAddress>,
|
pub preferred_seeds: Vec<node::config::ConnectAddress>,
|
||||||
|
/// CLI configuration.
|
||||||
|
#[serde(default)]
|
||||||
|
pub cli: cli::Config,
|
||||||
|
/// Node configuration.
|
||||||
|
pub node: node::Config,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
/// Create a new, default configuration.
|
/// Create a new, default configuration.
|
||||||
pub fn new(alias: Alias) -> Self {
|
pub fn new(alias: Alias) -> Self {
|
||||||
Self {
|
Self {
|
||||||
node: node::Config::new(alias),
|
|
||||||
cli: cli::Config::default(),
|
|
||||||
public_explorer: Explorer::default(),
|
public_explorer: Explorer::default(),
|
||||||
preferred_seeds: vec![node::config::seeds::RADICLE_COMMUNITY_NODE.clone()],
|
preferred_seeds: vec![node::config::seeds::RADICLE_COMMUNITY_NODE.clone()],
|
||||||
|
cli: cli::Config::default(),
|
||||||
|
node: node::Config::new(alias),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue