Mostly just a literal translation to make everything compile, but will need some cleanup to remove ad-hoc configuration logic.
YW6NICQV5LF4V2G77F2RG2ICODTQ2CKIEVBFIQEDATL5I5PFVRKQC
OMTQVGUEGSDJLMQULVJBZUZGHVH5YUABMELWPTD6CQ66P7OACYMAC
WBRT2RLZL3KTBKJ4CPKJMDTPMPBJQFN2ZY4QWNDORVAIB7ATBRQAC
SGFYGAXKCEALV2JOZEVWLUCJSUGAF22FF774PVTQLBVYLB4A3ZCAC
X642QQQTS4X2DENIZT7PGJN2M2FYVFMGGANXSZHJ7LBP6442Z6IAC
NHVLSXLMRBWEXI33YPSKYHRHS7EYUIITMG35EIK6PVHNXFXYDSUQC
56KJGRVOKO3CWJQSVYWD6CV3FBSBD7PMHX6OIAPRYH2253GW2GFQC
SCUBUHIAJXL432QBYNOGDYX2THRCZY3LPY3T3IZG7BYE52ERGFUQC
67GIAQEUQG3KUD7YTYNUWK33BKWPFVNT4YPQMZ3RCALOZ2STDLRQC
Q7LEDPIWGV5LJE3LYXLT74RBKOHEHLL4EJY6N4FDR3B6ZPX3V2UAC
OSWFAKWMXL7N3ZHL74TKXEUDGSBDUHBNFAPI25LUB6RBTQKFC6EQC
S4ZDDHTLHU6XCUOCGWZ3TUZGSB7Q5PIECZ7JKEPZEW4VR2XQ4XXAC
ORZKNFDB7JJGZNMJQ5W4SIYNU3JOGNY7R3B5G53IC72CSLMHKVBQC
DDEUZMXQRYVBGTJWKZY6W4UFSDCLB6JV7VX32AOTY3ZPD7OS6P6QC
K34KD3FTTP3GD7TBEMLPOA2ZCBDTAMSW53RDIN4WRGZD2AAMLEMAC
6YOM7WMHRWVWXNWDT6A3CCQR2VVRR6TAPTM7L4WX5HD2546TPJKQC
U45JUYYGEUYEIF7WNERHP4DUSQ5FUKZIJYF57YH4MPBISNOGC6PAC
CQKIS7KRVEYMB2W2JBYPKEHS6TSOOUFG2TWOBS6XEXBTOAQ5HYHAC
QRFQ24WRFJN3W3SMXC2MHP6RSITUW6O2MHOE7R22RGXGK5XAPVVAC
I24UEJQLCH2SOXA4UHIYWTRDCHSOPU7AFTRUOTX7HZIAV4AZKYEQC
SXEYMYF7P4RZMZ46WPL4IZUTSQ2ATBWYZX7QNVMS3SGOYXYOHAGQC
GKSVBEUW7Q2M4QPKPHOUPGP36AMXMJVGX7KCSNYXEFQZOURGBSMQC
4RV7T4SRYIQLBW3EZFWBO5G65QAVG2GHPI4KMDDZERCX65KQWSPQC
EUZFFJSOWV4PXDFFPDAFBHFUUMOFEU6ST7JH57YYRRR2SEOXLN6QC
WCA7X6W633OI72GFB4QPQKAF3POVTBB5HO2NRSVBJRO5BUJL2ORQC
CCLLB7OIFNFYJZTG3UCI7536TOCWSCSXR67VELSB466R24WLJSDAC
TYAKEAJLABCZQDYAI4YBGIJNQ7HJS4DVULEGPCZOGJPJUYYNR6TAC
H72JG6HLA7U3XFOUMWF6F3NFSWK5B6ZM6J5ZTILRSXBA7IM6H75AC
OPC2VAZDO4HL6K4BBNQP5A5YD2DI6UYI7O7ZQWAGLU7Z662PEOBAC
QCPIBC6MDPFE42KWELKZQ3ORNEOPSBXR7C7H6Z3ZT62RNVBFN73QC
Q7CHNDXNVJCBL2DK7LYZ6KSRFN4KO6TXKEP3GIWDJHB6JPSE3FUQC
CB7UPUQFOUH6M32KXQZL25EV4IH3XSK56RG3OYNRZBBFEABSNCXQC
CXSCA5HNK3BSSUMZ2SZ5XNKSSHC2IFHPC35SMO5WMWVJBYEFSJTQC
SZWBLWZ4LUJZHTSYOIGJMXM7KPCGWJFPKLHYA5MHY7UTPNLZV5KQC
MU6P2JXG6RQEUOUV7HIZNA2734BGUCYMJYXAOLOO2CSGMNKVIH5QC
32G3GOK752NTSULBH6KYGD3ZC2YC4B2X7O73G7BT3AJVMIUIFHXQC
M37JTFEIT6NHRDJOE7K6JWKFJF7327JMZDMX7GC2DQNECZKODBXQC
HJVWPKWVSL5ZXALZOT4BOQUWWNGH62OU6YLSZQQEIOB37QQGHK6AC
TPEH2XNBS5RO4IEVKENVF6P65AH7IX64KK2JAYMSJT3J5GXO67EAC
DWSAYGVEOR4D2EKIICEZUWCRGJTUXQQLOUWMYIFV7XN62K44F4FAC
5Z2Y7VGVHJ7A6UPSEAPFVMIB5J7YHSI6WWHUUUYVLDJ56XSNCXKQC
L4JXJHWXYNCL4QGJXNKKTOKKTAXKKXBJUUY7HFZGEUZ5A2V5H34QC
EVDH2ECTA45JYYLA2UKTDSXCUJYMPT6R3IBKX7LIXW252BELCUAAC
ABQDWHNGSBF2REQDCGXSBFAU4RUMXYAF2KHJ5O3D32M7Z3A3FEDAC
H4AU6QRPRDRFW3V7NN5CJ6DHLEUBYGNLRZ5GYV6ULBGRMOPCJQXQC
76PCXGML77EZWTRI5E6KHLVRAFTJ2AB5YRN5EKOYNAPKTWY2KCGAC
GYXIF25T2BCTCWCQI5DQOF3F4HBWDJUDJUMZ2WLHVBIOYATJTFAQC
JTELS6L36GEOOST2SUNCJIK5TBJDNLQWCF4IRF7QSHMMVCXSSESAC
4KJ45IJLTIE35KQZUSFMFS67RNENG4P2FZMKMULJLGGYMKJUVRSQC
4OJWMSOWWNT5N4W4FDMKBZB5UARCLGV3SRZVKGR4EFAYFUMUHM7AC
WTPFQPO5C3OWNOEIZQSIMAR7O6URYJJNUJSWDZUTWFDDAMNFMTLQC
6FRPUHWKBAWIYN6B6YDFQG2SFWZ6MBBYOYXFUN6DRZ4HPDSKFANQC
DOEG3V7UAVYBKLIPHSNWWONYDORKNJEZL2LD4EWGGUDB2SK6BOFQC
N26HD5PFUNVDSEXAQVOTMSMNPWFHQSZ5PHMGEF2ACC23OWFHTGQQC
YJXRCXOSO2J5BFFR6QKFDVV3RJ5J3QXB4UZ3DVQZLYTF5RJ4TNJAC
44RUBHREQUNI4B36WSV7CUK5CVVIKG2AQOQJQZ7HU3BHY6W6AUEQC
RUBBHYZ7MCLKJIHZ3EWEC3JR3FSKOU4T2NH7KRBG7ECAU4JF3LUAC
JL4WKA5PBKXRNAMETYO4I52QKASQ3COYHH2JKGA7W5YLIRZZH53AC
TI7PCK7JLPU4KYE65XIMBUPPY7DRPVDAETPDFMG3VAQGGDRGQHPQC
LJFJEX43HDS33O5HCRXH7AR3GTQZDHNWHEQBOERDNPNXR3B3XZ3QC
IBLJI7IAS7KNEHONURYUFRAINAMUC65HODM4G7XCRSGVIWJ7O5OQC
VWJ2JL63I5OYZ2HS3N4EKM5TW7HRAF5U3OAHDQIVZINIO73IAE7AC
LZOGKBJXRQJKXHYNNENJFGNLP5SHIXGSV6HDB7UVOP7FSA5EUNCQC
5DVRL6MFXQOCPOZMYSKBERMRRVUTYRL2SRGRTU2MH4IEOFCDKM3QC
A3RM526Y7LUXNYW4TL56YKQ5GVOK2R5D7JJVTSQ6TT5MEXIR6YAAC
FVU3Y2U3R7B6SBA5GJ227NR2JQMMFMDREMW63QODA2EUXU3754ZQC
SLJ3OHD4F6GJGZ3SV2D7DMR3PXYHPSI64X77KZ3RJ24EGEX6ZNQAC
QL6K2ZM35B3NIXEMMCJWUSFXOBQHAGXRDMO7ID5DCKTJH4QJVY7QC
FDEVV5NGUMTEULP25EFYFZEVICWYLGV7XMED25PNKD36DL4NA46AC
U6TQX5Z2NF6GX3SRLUBQGCZ7WAXNYMWWZ2YMADUSG4EWVKNV2BIAC
YQJRT2UBNF2ILSJZQZUZ73J2HOTMARVEEHXEUN5BDXVD7MVBAFPQC
ICEK2JVGXK2GQH7AYKPDFACBLRGZDQQS4Y4AB7K3B7V4C6C6AJPAC
SEWGHUHQEEBJR7UPG3PSU7DSM376R43QEYENAZK325W46DCFMXKAC
HKHMES6TWN5F7VTIC6GRV7ZBUCZ7KQUCSCKIA7PV2T5HKK4FD2FAC
EEBKW7VTILH6AGGV57ZIJ3DJGYHDSYBWGU3C7Q4WWAKSVNUGIYMQC
TFPETWTVADLG2DL7WERHJPGMJVOY4WOKCRWB3NZ3YOOQ4CVAUHBAC
OWJL5HO72US47LCBHUZVH6ONALVEADWMFAMXK5RMDHLXSCCFSFQAC
YN63NUZO4LVJ7XPMURDULTXBVJKW5MVCTZ24R7Z52QMHO3HPDUVQC
EEF5WHUIPNJAD3OQ7XOY4VSDOMRSPMLZ7EWGDRMADGGAY2YYB6OQC
IVLLXQ5ZWZDKHO4TNQG3TPXN34H6Y2WXPAGSO4PWCYNSKUZWOEJQC
367UBQ6KNAKUEWG32R4QRJ6H7IE7NAZFOPTC3ZOE4Z6E44RV3ISQC
VMPAOJS2ZFOLNXALHWSVM5AFENWX6ZUACB45EJV3HXI7DQNAZPHQC
5OGOE4VWS5AIG4U2UYLLIGA3HY6UB7SNQOSESHNXBLET3VQXFBZAC
GLRGFBCWZYQEP6BG2IXYMXVZ5ETPWKNA2YJSIRHBCAAOAHJYT2YQC
6F6AAHK4M2IVS23TVISR5OJSTZXUSEKLOP5BMM7SUHYG2FQNTSGQC
OU6JOR3CDZTH2H3NTGMV3WDIAWPD3VEJI7JRY3VJ7LPDR3QOA52QC
ZBNKSYA6PW4DSPC3NCRUZLVHW2GNXMCSDSAGEIKHGHDGGZRBH7ZQC
KKNMDXAIU7P44JOSAM23T4RUMLBHWGHTQQS4NXS4FIX5IN6OTXPAC
E3DD265TSU5HFAAUYOIYFK5D3GYSPIJSWDVSQX5Q226WPCH43EFQC
I52XSRUH5RVHQBFWVMAQPTUSPAJ4KNVID2RMI3UGCVKFLYUO6WZAC
5BB266P6HPUGYEVR7QNNOA62EFPYPUYJ3UMLE5J3LLYMSUWXANIQC
ZRUPLBBTT4S6S7A3LOAHG4ONYEGPA5CFO4L2XBCNFKK45MWX3BDAC
ZYKNOCXPMKHQKFPUS2EDKSBHQODVMQ6J6OY6PPV26YPLKZGHWNKQC
3OPNBBAUOQ4AAENJ7YI7TCAQ5ZUVNMDPD2AN2KTL3KTOW5A2V6BAC
FCMAW4GOKAFKDTOCMV2LSG4SSSDI7W2NY7BOV2U3HDDHXF3OFEAAC
QWIYNMI5SOTLRPYE4O3AG7R75JXM2TB3ZADU646PG6ACPBGSYUYAC
Y6TBQN7MFWX4SKJM2UGDGR4UMMDEO4TPNNJZKZWHEBTW7MPX4WWQC
let config_path = dot_directory.join(CONFIG_FILE);
let config = if let Ok(config) = std::fs::read(&config_path) {
if let Ok(toml) = toml::from_str(&String::from_utf8(config)?) {
toml
} else {
bail!("Could not read configuration file at {:?}", config_path)
}
} else {
config::Config::default()
};
if let Ok((config, _)) = pijul_config::Global::load() {
let ignore_kinds = config.ignore_kinds.as_ref();
if let Some(kinds) = ignore_kinds.and_then(|x| x.get(kind)) {
for entry in kinds.iter() {
writeln!(dot_ignore, "{}", entry)?;
}
return Ok(());
if let Some(kinds) = config.ignore_kinds.get(kind) {
for entry in kinds.iter() {
writeln!(dot_ignore, "{}", entry)?;
let config = Arc::new(thrussh::client::Config::default());
let mut h = thrussh::client::connect_stream(config, stream, client).await?;
let client_config = Arc::new(thrussh::client::Config::default());
let mut h = thrussh::client::connect_stream(client_config, stream, client).await?;
if let Some(name) = repo.config.remotes.iter().find(|e| e.name() == name) {
name.to_remote(channel, no_cert_check, with_path).await
if let Some(name) = config.remotes.iter().find(|e| e.name() == name) {
name.to_remote(config, channel, no_cert_check, with_path)
.await
let mut remote = if let Ok(repo) = Repository::find_root(None) {
repository(
&repo,
None,
Some(&identity.config.author.username),
&remote,
libpijul::DEFAULT_CHANNEL,
no_cert_check,
false,
)
.await?
} else {
unknown_remote(
None,
Some(&identity.config.author.username),
&remote,
libpijul::DEFAULT_CHANNEL,
no_cert_check,
false,
)
.await?
};
let mut remote = repository(
config,
None,
Some(&identity.config.author.username),
&remote,
libpijul::DEFAULT_CHANNEL,
no_cert_check,
false,
)
.await?;
static THEME: LazyLock<Box<dyn theme::Theme + Send + Sync>> = LazyLock::new(|| {
if let Ok((config, _)) = config::Global::load() {
let color_choice = config.colors.unwrap_or_default();
static THEME: OnceLock<Box<dyn Theme + Send + Sync>> = OnceLock::new();
match color_choice {
Choice::Auto | Choice::Always => Box::<theme::ColorfulTheme>::default(),
Choice::Never => Box::new(theme::SimpleTheme),
}
} else {
Box::<theme::ColorfulTheme>::default()
}
});
pub async fn fix_identities() -> Result<(), anyhow::Error> {
let mut dir = config::global_config_dir().unwrap();
pub async fn fix_identities(config: &pijul_config::Config) -> Result<(), anyhow::Error> {
let config_path = Global::config_file().unwrap();
let mut dir = config_path.parent().unwrap().to_path_buf();
fn from_old_format() -> Result<Self, IdentityParseError> {
let config_dir = config::global_config_dir().unwrap();
let config_path = config_dir.join("config.toml");
fn from_old_format(config: &pijul_config::Config) -> Result<Self, IdentityParseError> {
let config_path = Global::config_file().unwrap();
let config_dir = config_path.parent().unwrap();
let config_path = config_dir.join(pijul_config::CONFIG_FILE);
let config: super::Config = if config_path.exists() {
let mut config_file =
fs::File::open(&config_path).context("Failed to open config file")?;
let mut config_text = String::new();
config_file
.read_to_string(&mut config_text)
.context("Failed to read config file")?;
let config_data: config::Global =
toml::from_str(&config_text).context("Failed to parse config file")?;
let identity_config: IdentityConfig = if config_path.exists() {
let config_path = Global::config_file().unwrap();
let config_text = Global::read_contents(&config_path)?;
let config_data = Global::parse_contents(&config_path, &config_text)?;
pub fn default() -> Result<Self, anyhow::Error> {
let config_path = config::global_config_dir().unwrap().join("config.toml");
let author: Author = if config_path.exists() {
let mut config_file = fs::File::open(&config_path)?;
let mut config_text = String::new();
config_file.read_to_string(&mut config_text)?;
pub fn default(config: &pijul_config::Config) -> Result<Self, anyhow::Error> {
// let config_path = config::global_config_dir().unwrap().join("config.toml");
// let author: Author = if config_path.exists() {
// let mut config_file = fs::File::open(&config_path)?;
// let mut config_text = String::new();
// config_file.read_to_string(&mut config_text)?;
let global_config: config::Global = toml::from_str(&config_text)?;
global_config.author
} else {
Author::default()
};
// let global_config: config::Global = toml::from_str(&config_text)?;
// global_config.author
// } else {
// Author::default()
// };
pub fn decrypt(&self) -> Result<(SKey, Option<String>), anyhow::Error> {
self.credentials.clone().unwrap().decrypt(&self.name)
pub fn decrypt(
&self,
config: &pijul_config::Config,
) -> Result<(SKey, Option<String>), anyhow::Error> {
self.credentials
.clone()
.unwrap()
.decrypt(config, &self.name)
async fn prompt_remote(&mut self) -> Result<(), anyhow::Error> {
self.config.author.username = Input::new()?
async fn prompt_remote(&mut self, config: &pijul_config::Config) -> Result<(), anyhow::Error> {
self.config.author.username = Input::new(config)?
SubCommand::Log(l) => l.run(),
SubCommand::Init(init) => init.run(),
SubCommand::Clone(clone) => clone.run().await,
SubCommand::Record(record) => record.run().await,
SubCommand::Diff(diff) => diff.run(),
SubCommand::Status(status) => status.run(),
SubCommand::Push(push) => push.run().await,
SubCommand::Pull(pull) => pull.run().await,
SubCommand::Change(change) => change.run(),
SubCommand::Log(l) => l.run(&config),
SubCommand::Init(init) => init.run(&config),
SubCommand::Clone(clone) => clone.run(&config).await,
SubCommand::Record(record) => record.run(&config).await,
SubCommand::Diff(diff) => diff.run(&config),
SubCommand::Status(status) => status.run(&config),
SubCommand::Push(push) => push.run(&config).await,
SubCommand::Pull(pull) => pull.run(&config).await,
SubCommand::Change(change) => change.run(&config),
SubCommand::Remote(remote) => remote.run(),
SubCommand::Archive(archive) => archive.run().await,
SubCommand::Credit(credit) => credit.run(),
SubCommand::Tag(tag) => tag.run().await,
SubCommand::Identity(identity_wizard) => identity_wizard.run().await,
SubCommand::Remote(remote) => remote.run(&config),
SubCommand::Archive(archive) => archive.run(&config).await,
SubCommand::Credit(credit) => credit.run(&config),
SubCommand::Tag(tag) => tag.run(&config).await,
SubCommand::Identity(identity_wizard) => identity_wizard.run(&config).await,
let (cfg, _) = pijul_config::Global::load()?;
cfg.unrecord_changes.ok_or_else(|| {
anyhow!(
"Can't determine how many changes to show. \
Please set the `unrecord_changes` option in \
your global config or run `pijul unrecord` \
with the `--show-changes` option."
)
})?
return Err(anyhow!(
"Can't determine how many changes to show. \
Please set the `unrecord_changes` option in \
your config or run `pijul unrecord` \
with the `--show-changes` option."
));
} else if let Some(_dir) = pijul_config::global_config_dir() {
let k = pijul_identity::public_key(&pijul_identity::choose_identity_name().await?)?;
} else {
let identity_name = pijul_identity::choose_identity_name(config).await?;
let k = pijul_identity::public_key(&identity_name)?;
pub fn run(self) -> Result<(), anyhow::Error> {
let reset_overwrites_changes = pijul_config::Global::load()
.ok()
.and_then(|c| c.0.reset_overwrites_changes);
let overwrite_changes = match reset_overwrites_changes.as_ref() {
pub fn run(self, config: &pijul_config::Config) -> Result<(), anyhow::Error> {
let overwrite_changes = match config.reset_overwrites_changes.as_ref() {
debug!("{:?}", repo.config);
} else if let Some(pijul_config::Choice::Never) = pijul_config::Global::load()
.ok()
.and_then(|(global, _)| global.pager)
{
return false;
pub fn run(self) -> Result<(), anyhow::Error> {
let repo = Repository::init(self.path.as_deref(), self.kind.as_deref(), None)?;
pub fn run(self, config: &pijul_config::Config) -> Result<(), anyhow::Error> {
let repo = Repository::init(config, self.path.as_deref(), self.kind.as_deref(), None)?;
Complete::load(&identity_name.unwrap_or(choose_identity_name().await?))?;
let path = config::global_config_dir()
Complete::load(&identity_name.unwrap_or(choose_identity_name(config).await?))?;
let path = Global::config_file()
.unwrap()
.parent()
if let Ok((global, _)) = pijul_config::Global::load() {
match global.colors {
Some(pijul_config::Choice::Always) => colors = true,
Some(pijul_config::Choice::Never) => colors = false,
_ => {}
}
match global.pager {
Some(pijul_config::Choice::Never) => colors = false,
_ => {
super::pager(repo_config_pager);
}
match config.colors {
Some(pijul_config::Choice::Always) => colors = true,
Some(pijul_config::Choice::Never) => colors = false,
_ => {}
}
match config.pager {
Some(pijul_config::Choice::Never) => colors = false,
_ => {
super::pager(config);