Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ mirror = "https://github.com/tldr-pages/tldr/releases/latest/download"
# Automatically update the cache if it's older than max_age hours.
auto_update = true
max_age = 336 # 336 hours = 2 weeks
# Defers cache automatic update until after displaying the page.
defer_auto_update = false
# Specify a list of desired page languages. If it's empty, languages specified in
# the LANG and LANGUAGE environment variables are downloaded.
# English is implied and will always be downloaded.
Expand Down
7 changes: 5 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ pub struct CacheConfig {
/// Automatically update the cache
/// if it is older than `max_age` hours.
pub auto_update: bool,
/// Perform the automatic update after the page is shown.
pub defer_auto_update: bool,
/// Max cache age in hours.
max_age: u64,
/// Languages to download.
Expand All @@ -242,6 +244,7 @@ impl Default for CacheConfig {
dir: Cache::locate(),
mirror: Cow::Borrowed("https://github.com/tldr-pages/tldr/releases/latest/download"),
auto_update: true,
defer_auto_update: false,
// 2 weeks
max_age: 24 * 7 * 2,
languages: vec![],
Expand Down Expand Up @@ -331,10 +334,10 @@ impl Config {
})?)?)
}

pub fn new(cli_config_path: Option<PathBuf>) -> Result<Self> {
pub fn new(cli_config_path: Option<&Path>) -> Result<Self> {
let cfg_res = if let Some(path) = cli_config_path {
if path.is_file() {
Self::parse(&path)
Self::parse(path)
} else {
warnln!("'{}': not a file, ignoring --config", path.display());
Ok(Self::default())
Expand Down
9 changes: 7 additions & 2 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,14 @@ impl Error {
Error::new("could not parse the checksum file").kind(ErrorKind::Download)
}

pub fn desc_page_does_not_exist() -> String {
pub fn desc_page_does_not_exist(try_update: bool) -> String {
let e = if try_update {
"Try running 'tldr --update'.\n\n"
} else {
"\n\n"
};
format!(
"Try running 'tldr --update'.\n\n\
"{e}\
If the page does not exist, you can create an issue here:\n\
{}\n\
or document it yourself and create a pull request here:\n\
Expand Down
108 changes: 67 additions & 41 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ fn main() -> ExitCode {
}
}

fn include_cli_in_config(cfg: &mut Config, cli: &Cli) {
cfg.output.compact = !cli.no_compact && (cli.compact || cfg.output.compact);
cfg.output.raw_markdown = !cli.no_raw && (cli.raw || cfg.output.raw_markdown);
match (cli.short_options, cli.long_options) {
(false, false) => {}
(true, true) => cfg.output.option_style = OptionStyle::Both,
(true, false) => cfg.output.option_style = OptionStyle::Short,
(false, true) => cfg.output.option_style = OptionStyle::Long,
}
}

fn run() -> Result<()> {
let cli = Cli::parse();

Expand All @@ -45,15 +56,8 @@ fn run() -> Result<()> {

init_color(cli.color);

let mut cfg = Config::new(cli.config)?;
cfg.output.compact = !cli.no_compact && (cli.compact || cfg.output.compact);
cfg.output.raw_markdown = !cli.no_raw && (cli.raw || cfg.output.raw_markdown);
cfg.output.option_style = match (cli.short_options, cli.long_options) {
(false, false) => cfg.output.option_style,
(true, true) => OptionStyle::Both,
(true, false) => OptionStyle::Short,
(false, true) => OptionStyle::Long,
};
let mut cfg = Config::new(cli.config.as_deref())?;
include_cli_in_config(&mut cfg, &cli);

if let Some(path) = cli.render {
return PageRenderer::print(&path, &cfg);
Expand All @@ -74,6 +78,9 @@ fn run() -> Result<()> {
return cache.update(&cfg.cache.mirror, &mut cfg.cache.languages);
}

// Update after displaying the page?
let mut update_later = false;

if !cache.subdir_exists(cache::ENGLISH_DIR) {
if cli.offline {
return Err(Error::offline_no_cache());
Expand All @@ -88,6 +95,9 @@ fn run() -> Result<()> {
warnln!(
"cache is stale (last update: {age} ago). Run tldr without --offline to update."
);
} else if cfg.cache.defer_auto_update {
infoln!("cache is stale (last update: {age} ago), update has been deferred");
update_later = true;
} else {
infoln!("cache is stale (last update: {age} ago), updating...");
cache
Expand All @@ -106,41 +116,57 @@ fn run() -> Result<()> {
};

if cli.list {
return cache.list_for(platform);
}
if cli.list_all {
return cache.list_all();
}
if cli.info {
return cache.info(&cfg);
}
if cli.list_platforms {
return cache.list_platforms();
}
if cli.list_languages {
return cache.list_languages();
}

let page_name = cli.page.join("-").to_lowercase();
let page_paths = cache.find(&page_name, &languages, platform)?;
cache.list_for(platform)?;
} else if cli.list_all {
cache.list_all()?;
} else if cli.info {
cache.info(&cfg)?;
} else if cli.list_platforms {
cache.list_platforms()?;
} else if cli.list_languages {
cache.list_languages()?;
} else {
let page_name = cli.page.join("-").to_lowercase();
let mut page_paths = cache.find(&page_name, &languages, platform)?;
let forced_update_no_page = update_later && page_paths.is_empty();
if forced_update_no_page {
// Since the page hasn't been found and the cache is stale, disregard the defer option.
warnln!("page not found, updating now...");
cache
.update(&cfg.cache.mirror, &mut cfg.cache.languages)
.map_err(|e| e.describe(Error::DESC_AUTO_UPDATE_ERR))?;
page_paths = cache.find(&page_name, &languages, platform)?;
// Reset the defer flag in order not to update twice.
update_later = false;
}

if page_paths.is_empty() {
let mut e = Error::new("page not found.");
return if languages_are_from_cli {
e = e.describe("Try running tldr without --language.");
if page_paths.is_empty() {
let mut e = Error::new("page not found.");
return if languages_are_from_cli {
e = e.describe("Try running tldr without --language.");

if !languages
.iter()
.all(|x| cache.subdir_exists(&format!("pages.{x}")))
{
e = e.describe(Error::DESC_LANG_NOT_INSTALLED);
}

Err(e)
} else {
// If the cache has been updated, don't suggest running 'tldr --update'.
Err(e.describe(Error::desc_page_does_not_exist(!forced_update_no_page)))
};
}

if !languages
.iter()
.all(|x| cache.subdir_exists(&format!("pages.{x}")))
{
e = e.describe(Error::DESC_LANG_NOT_INSTALLED);
}
PageRenderer::print_cache_result(&page_paths, &cfg)?;
}

Err(e)
} else {
Err(e.describe(Error::desc_page_does_not_exist()))
};
if update_later {
cache
.update(&cfg.cache.mirror, &mut cfg.cache.languages)
.map_err(|e| e.describe(Error::DESC_AUTO_UPDATE_ERR))?;
}

PageRenderer::print_cache_result(&page_paths, &cfg)
Ok(())
}