Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display update changelog if requested on self-update #56

Merged
merged 6 commits into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
252 changes: 235 additions & 17 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ cli = [
"dep:console",
"dep:dialoguer",
"dep:indicatif",
"dep:pulldown-cmark-mdcat",
"dep:pulldown-cmark",
"dep:syntect",
"dep:tracing-subscriber",
]

Expand Down Expand Up @@ -85,6 +88,11 @@ clap = { optional = true, version = "4.5", features = ["derive"] }
console = { optional = true, version = "0.15" }
dialoguer = { optional = true, version = "0.11" }
indicatif = { optional = true, version = "0.17" }

pulldown-cmark-mdcat = { optional = true, version = "2.3.0", default-features = false }
pulldown-cmark = { optional = true, version = "0.9.2" }
syntect = { optional = true, version = "5.2.0" }

tracing-subscriber = { optional = true, version = "0.3", features = [
"env-filter",
] }
Expand Down
19 changes: 14 additions & 5 deletions lib/sources/github/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use reqwest::{

use crate::tool::{ToolId, ToolSpec};

use super::{client::create_client, Artifact, ArtifactProvider};
use super::{client::create_client, source::ReleaseArtifact, Artifact, ArtifactProvider};

const BASE_URL: &str = "https://api.github.com";

Expand Down Expand Up @@ -128,7 +128,7 @@ impl GithubProvider {
Fetches the latest release for a given tool.
*/
#[instrument(skip(self), fields(%tool_id), level = "debug")]
pub async fn get_latest_release(&self, tool_id: &ToolId) -> GithubResult<Vec<Artifact>> {
pub async fn get_latest_release(&self, tool_id: &ToolId) -> GithubResult<ReleaseArtifact> {
debug!(id = %tool_id, "fetching latest release for tool");

let url = format!(
Expand All @@ -152,14 +152,20 @@ impl GithubProvider {
.map_err(|e| GithubError::Other(e.to_string()))?;

let tool_spec: ToolSpec = (tool_id.clone(), version).into();
Ok(artifacts_from_release(&release, &tool_spec))
Ok(ReleaseArtifact {
artifacts: artifacts_from_release(&release.clone(), &tool_spec),
changelog: release.changelog,
})
}

/**
Fetches a specific release for a given tool.
*/
#[instrument(skip(self), fields(%tool_spec), level = "debug")]
pub async fn get_specific_release(&self, tool_spec: &ToolSpec) -> GithubResult<Vec<Artifact>> {
pub async fn get_specific_release(
&self,
tool_spec: &ToolSpec,
) -> GithubResult<ReleaseArtifact> {
debug!(spec = %tool_spec, "fetching release for tool");

let url_with_prefix = format!(
Expand Down Expand Up @@ -187,7 +193,10 @@ impl GithubProvider {
Ok(r) => r,
};

Ok(artifacts_from_release(&release, tool_spec))
Ok(ReleaseArtifact {
artifacts: artifacts_from_release(&release.clone(), tool_spec),
changelog: release.changelog,
})
}

/**
Expand Down
2 changes: 2 additions & 0 deletions lib/sources/github/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ pub struct Release {
pub assets: Vec<Asset>,
pub tag_name: String,
pub prerelease: bool,
#[serde(rename = "body")]
pub changelog: Option<String>,
}

#[derive(Debug, Clone, Deserialize)]
Expand Down
10 changes: 8 additions & 2 deletions lib/sources/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ pub struct ArtifactSource {
github: GithubProvider,
}

#[derive(Debug, Clone)]
pub struct ReleaseArtifact {
pub changelog: Option<String>,
pub artifacts: Vec<Artifact>,
}

impl ArtifactSource {
/**
Creates a new artifact source.
Expand Down Expand Up @@ -57,7 +63,7 @@ impl ArtifactSource {

- If the latest release could not be fetched.
*/
pub async fn get_latest_release(&self, id: &ToolId) -> RokitResult<Vec<Artifact>> {
pub async fn get_latest_release(&self, id: &ToolId) -> RokitResult<ReleaseArtifact> {
Ok(match id.provider() {
ArtifactProvider::GitHub => self.github.get_latest_release(id).await?,
})
Expand All @@ -70,7 +76,7 @@ impl ArtifactSource {

- If the specific release could not be fetched.
*/
pub async fn get_specific_release(&self, spec: &ToolSpec) -> RokitResult<Vec<Artifact>> {
pub async fn get_specific_release(&self, spec: &ToolSpec) -> RokitResult<ReleaseArtifact> {
Ok(match spec.provider() {
ArtifactProvider::GitHub => self.github.get_specific_release(spec).await?,
})
Expand Down
8 changes: 4 additions & 4 deletions src/cli/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,13 @@ impl AddSubcommand {
let pt = CliProgressTracker::new_with_message("Fetching", 3);
let (spec, artifact) = match self.tool.clone() {
ToolIdOrSpec::Spec(spec) => {
let artifacts = source.get_specific_release(&spec).await?;
let artifact = find_most_compatible_artifact(&artifacts, &id)?;
let release_artifact = source.get_specific_release(&spec).await?;
let artifact = find_most_compatible_artifact(&release_artifact.artifacts, &id)?;
(spec, artifact)
}
ToolIdOrSpec::Id(id) => {
let artifacts = source.get_latest_release(&id).await?;
let artifact = find_most_compatible_artifact(&artifacts, &id)?;
let release_artifact = source.get_latest_release(&id).await?;
let artifact = find_most_compatible_artifact(&release_artifact.artifacts, &id)?;
(artifact.tool_spec.clone(), artifact)
}
};
Expand Down
5 changes: 3 additions & 2 deletions src/cli/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,11 @@ impl InstallSubcommand {
return anyhow::Ok(tool_spec);
}

let artifacts = source.get_specific_release(&tool_spec).await?;
let release_artifact = source.get_specific_release(&tool_spec).await?;
pt.subtask_completed();

let artifact = find_most_compatible_artifact(&artifacts, tool_spec.id())?;
let artifact =
find_most_compatible_artifact(&release_artifact.artifacts, tool_spec.id())?;
pt.subtask_completed();

let contents = source
Expand Down
71 changes: 63 additions & 8 deletions src/cli/self_update.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
use std::io::{stdout, BufWriter};

use anyhow::{bail, Context, Result};
use clap::Parser;
use console::style;
use console::{style, Style};
use dialoguer::{theme::ColorfulTheme, Confirm};
use pulldown_cmark::{Options, Parser as MarkdownParser};
use pulldown_cmark_mdcat::{
resources::FileResourceHandler, Environment, Settings, TerminalProgram, TerminalSize, Theme,
};
use syntect::parsing::SyntaxSet;

use semver::Version;

use rokit::{storage::Home, tool::ToolId};
Expand Down Expand Up @@ -34,11 +43,17 @@ impl SelfUpdateSubcommand {
pt.task_completed();
pt.update_message("Fetching");

let artifacts = source.get_latest_release(&tool_id).await?;
let release_artifact = source.get_latest_release(&tool_id).await?;

// Skip updating if we are already on the latest version
let version_current = env!("CARGO_PKG_VERSION").parse::<Version>().unwrap();
let version_latest = artifacts.first().unwrap().tool_spec.version().clone();
let version_latest = release_artifact
.artifacts
.first()
.unwrap()
.tool_spec
.version()
.clone();
if version_current >= version_latest && !self.force {
let msg = format!(
"Rokit is already up-to-date! {}\n\n\
Expand All @@ -55,7 +70,7 @@ impl SelfUpdateSubcommand {
pt.task_completed();
pt.update_message("Downloading");

let artifact = find_most_compatible_artifact(&artifacts, &tool_id)
let artifact = find_most_compatible_artifact(&release_artifact.artifacts, &tool_id)
.context("No compatible Rokit artifact was found (WAT???)")?;
let artifact_contents = source
.download_artifact_contents(&artifact)
Expand All @@ -76,10 +91,10 @@ impl SelfUpdateSubcommand {

let storage = home.tool_storage();
storage.replace_rokit_contents(binary_contents).await;
storage
.recreate_all_links()
.await
.context("Failed to create new tool links")?;
// storage
// .recreate_all_links()
// .await
// .context("Failed to create new tool links")?;

// Everything went well, yay!
let msg = format!(
Expand All @@ -91,6 +106,46 @@ impl SelfUpdateSubcommand {
);
pt.finish_with_message(msg);

// If there is a changelog, and the user wants to see it, show it
if let Some(changelog) = release_artifact.changelog {
let to_show_changelog = Confirm::with_theme(&ColorfulTheme {
active_item_prefix: style("📋 ".to_string()),
prompt_style: Style::new(),
..Default::default()
})
.with_prompt("View changelogs for this update?")
.interact_opt()?
.unwrap_or_default();

if to_show_changelog {
println!();
pulldown_cmark_mdcat::push_tty(
&Settings {
terminal_capabilities: TerminalProgram::detect().capabilities(),
terminal_size: TerminalSize::detect()
.context("Failed to detect terminal size")?,
syntax_set: &SyntaxSet::load_defaults_newlines(),
theme: Theme::default(),
},
&Environment::for_local_directory(&tempfile::tempdir()?.path())?,
&FileResourceHandler::new(104_857_600), // TODO: Maybe make this be a DispatchingResourceHandler?
&mut BufWriter::new(stdout()),
MarkdownParser::new_ext(
format!(
"# Changelog - {} v{}\n{}",
tool_id.name(),
version_current,
changelog
)
.as_str(),
Options::ENABLE_FOOTNOTES
| Options::ENABLE_TABLES
| Options::ENABLE_STRIKETHROUGH,
),
)?;
}
}

Ok(())
}
}
2 changes: 1 addition & 1 deletion src/cli/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ impl UpdateSubcommand {
}
};

let artifact = find_most_compatible_artifact(&artifacts, &id)?;
let artifact = find_most_compatible_artifact(&artifacts.artifacts, &id)?;
pt.subtask_completed();

Ok::<_, anyhow::Error>((alias, id, artifact))
Expand Down