Skip to content

Commit

Permalink
re-implement grammar/queries update system (lapce#3341)
Browse files Browse the repository at this point in the history
  • Loading branch information
panekj authored Jul 12, 2024
1 parent 0d0b08d commit 9f120f9
Show file tree
Hide file tree
Showing 11 changed files with 254 additions and 149 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ members = ["lapce-app", "lapce-proxy", "lapce-rpc", "lapce-core"]
[workspace.package]
version = "0.4.0"
edition = "2021"
rust-version = "1.75"
rust-version = "1.77"
license = "Apache-2.0"
homepage = "https://lapce.dev"
authors = ["Dongdong Zhou <dzhou121@gmail.com>"]
Expand All @@ -38,6 +38,7 @@ clap = { version = "4.5.0", default-features = false, features = ["
crossbeam-channel = { version = "0.5.12" }
directories = { version = "4.0.1" }
flate2 = { version = "1.0" }
git2 = { version = "0.19.0", features = ["vendored-openssl"] }
globset = { version = "0.4.14" }
hashbrown = { version = "0.14.5", features = ["serde"] }
im = { version = "15.0.0", features = ["serde"] }
Expand All @@ -50,6 +51,7 @@ once_cell = { version = "1.19" }
parking_lot = { version = "0.12.3" }
rayon = { version = "1.10.0" }
regex = { version = "1.10.5" }
semver = { version = "1.0" }
reqwest = { version = "0.11", features = ["blocking", "json", "socks"] }
serde = { version = "1.0" }
serde_json = { version = "1.0" }
Expand Down
1 change: 1 addition & 0 deletions lapce-app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ reqwest = { workspace = true }
smallvec = { workspace = true }
strum = { workspace = true }
strum_macros = { workspace = true }
semver = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
regex = { workspace = true }
Expand Down
139 changes: 18 additions & 121 deletions lapce-app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use std::{
use anyhow::{anyhow, Result};
use clap::Parser;
use crossbeam_channel::Sender;
use floem::action::show_context_menu;
use floem::{
action::show_context_menu,
cosmic_text::{Style as FontStyle, Weight},
event::{Event, EventListener, EventPropagation},
ext_event::{create_ext_action, create_signal_from_channel},
Expand Down Expand Up @@ -63,7 +63,6 @@ use notify::Watcher;
use serde::{Deserialize, Serialize};
use tracing_subscriber::{filter::Targets, reload::Handle};

use crate::main_split::TabCloseKind;
use crate::{
about, alert,
code_action::CodeActionStatus,
Expand All @@ -88,7 +87,9 @@ use crate::{
keymap::keymap_view,
keypress::keymap::KeyMap,
listener::Listener,
main_split::{SplitContent, SplitData, SplitDirection, SplitMoveDirection},
main_split::{
SplitContent, SplitData, SplitDirection, SplitMoveDirection, TabCloseKind,
},
markdown::MarkdownContent,
palette::{
item::{PaletteItem, PaletteItemContent},
Expand All @@ -107,6 +108,7 @@ use crate::{
workspace::{LapceWorkspace, LapceWorkspaceType},
};

mod grammars;
mod logging;

#[derive(Parser)]
Expand Down Expand Up @@ -3657,21 +3659,19 @@ pub fn launch() {
reset_highlight_configs();
});
std::thread::spawn(move || {
if let Err(e) = fetch_grammars() {
trace!(TraceLevel::ERROR, "failed to fetch grammars: {e}");
}
send(());
});
}

{
let cx = Scope::new();
let send = create_ext_action(cx, |_| {
reset_highlight_configs();
});
std::thread::spawn(move || {
if let Err(e) = fetch_queries() {
trace!(TraceLevel::ERROR, "failed to fetch queries: {e}");
use self::grammars::*;
match find_release().map(|r| describe_release(&r.tag_name)) {
Ok(Ok(release)) => {
if let Err(e) = fetch_grammars(&release) {
trace!(TraceLevel::ERROR, "failed to fetch grammars: {e}");
}
if let Err(e) = fetch_queries(&release) {
trace!(TraceLevel::ERROR, "failed to fetch grammars: {e}");
}
}
Err(e) | Ok(Err(e)) => {
trace!(TraceLevel::ERROR, "failed to obtain release info: {e}");
}
}
send(());
});
Expand Down Expand Up @@ -4035,109 +4035,6 @@ pub fn window_menu(
})),
)
}

fn fetch_grammars() -> Result<()> {
let dir = Directory::grammars_directory()
.ok_or_else(|| anyhow!("can't get grammars directory"))?;
if !dir.exists() {
let _ = std::fs::create_dir(&dir);
}

let url =
"https://api.github.com/repos/lapce/tree-sitter-grammars/releases/latest";
let resp = reqwest::blocking::ClientBuilder::new()
.user_agent("Lapce")
.build()?
.get(url)
.send()?;
if !resp.status().is_success() {
return Err(anyhow!("get release info failed {}", resp.text()?));
}
let current_version =
std::fs::read_to_string(dir.join("version")).unwrap_or_default();
let release: ReleaseInfo = serde_json::from_str(&resp.text()?)?;
if release.tag_name == current_version {
return Ok(());
}

let file_name = format!(
"grammars-{}-{}.zip",
std::env::consts::OS,
std::env::consts::ARCH
);

for asset in &release.assets {
if asset.name == file_name {
let mut resp = reqwest::blocking::get(&asset.browser_download_url)?;
if !resp.status().is_success() {
return Err(anyhow!("download file error {}", resp.text()?));
}
{
let mut out = std::fs::File::create(dir.join(&file_name))?;
resp.copy_to(&mut out)?;
}

let mut archive =
zip::ZipArchive::new(std::fs::File::open(dir.join(&file_name))?)?;
archive.extract(&dir)?;
let _ = std::fs::remove_file(dir.join(&file_name));
std::fs::write(dir.join("version"), release.tag_name)?;
return Ok(());
}
}

Err(anyhow!("can't find support grammars"))
}

fn fetch_queries() -> Result<()> {
let dir = Directory::queries_directory()
.ok_or_else(|| anyhow!("can't get queries directory"))?;
if !dir.exists() {
let _ = std::fs::create_dir(&dir);
}

let url =
"https://api.github.com/repos/lapce/tree-sitter-grammars/releases/latest";
let resp = reqwest::blocking::ClientBuilder::new()
.user_agent("Lapce")
.build()?
.get(url)
.send()?;
if !resp.status().is_success() {
return Err(anyhow!("get release info failed {}", resp.text()?));
}
let current_version =
std::fs::read_to_string(dir.join("version")).unwrap_or_default();
let release: ReleaseInfo = serde_json::from_str(&resp.text()?)?;
if release.tag_name == current_version {
return Ok(());
}

let file_name = "queries.zip";

for asset in &release.assets {
if asset.name == file_name {
let mut resp = reqwest::blocking::get(&asset.browser_download_url)?;
if !resp.status().is_success() {
return Err(anyhow!("download file error {}", resp.text()?));
}
{
let mut out = std::fs::File::create(dir.join(file_name))?;
resp.copy_to(&mut out)?;
}

let mut archive =
zip::ZipArchive::new(std::fs::File::open(dir.join(file_name))?)?;
archive.extract(&dir)?;
let _ = std::fs::remove_file(dir.join(file_name));
std::fs::write(dir.join("version"), release.tag_name)?;
return Ok(());
}
}

Err(anyhow!("can't find support queries"))
}

fn tab_secondary_click(
internal_command: Listener<InternalCommand>,
editor_tab_id: EditorTabId,
Expand Down
135 changes: 135 additions & 0 deletions lapce-app/src/app/grammars.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
use std::{
env,
fs::{self, File},
path::PathBuf,
};

use anyhow::{anyhow, Result};
use lapce_core::directory::Directory;

use crate::{tracing::*, update::ReleaseInfo};

fn get_github_api(url: &str) -> Result<String> {
let resp = reqwest::blocking::ClientBuilder::new()
.user_agent(format!("Lapce/{}", lapce_core::meta::VERSION))
.build()?
.get(url)
.send()?;
if !resp.status().is_success() {
return Err(anyhow!("get release info failed {}", resp.text()?));
}

Ok(resp.text()?)
}

pub fn find_release() -> Result<ReleaseInfo> {
let releases: Vec<ReleaseInfo> = serde_json::from_str(&get_github_api(
"https://api.github.com/repos/lapce/tree-sitter-grammars/releases?per_page=100",
)?)?;

use lapce_core::meta::{ReleaseType, RELEASE, VERSION};

let releases = releases
.into_iter()
.filter_map(|f| {
let tag_name = if f.tag_name.starts_with('v') {
f.tag_name.trim_start_matches('v')
} else {
f.tag_name.as_str()
};

use semver::Version;
use std::cmp::Ordering;

let sv = Version::parse(tag_name).ok()?;
let version = Version::parse(VERSION).ok()?;

if matches!(sv.cmp_precedence(&version), Ordering::Equal)
|| matches!(RELEASE, ReleaseType::Debug | ReleaseType::Nightly)
{
Some(f)
} else {
None
}
})
.collect::<Vec<_>>();

let Some(release) = releases.first() else {
return Err(anyhow!("Couldn't find any release"));
};

Ok(release.to_owned())
}

pub fn describe_release(id: &str) -> Result<ReleaseInfo> {
let url = format!(
"https://api.github.com/repos/lapce/tree-sitter-grammars/releases/{id}"
);

let resp = get_github_api(&url)?;
let release: ReleaseInfo = serde_json::from_str(&resp)?;

Ok(release)
}

pub fn fetch_grammars(release: &ReleaseInfo) -> Result<()> {
let dir = Directory::grammars_directory()
.ok_or_else(|| anyhow!("can't get grammars directory"))?;

let file_name =
format!("grammars-{}-{}.zip", env::consts::OS, env::consts::ARCH);

download_release(dir, release, &file_name)?;

Ok(())
}

pub fn fetch_queries(release: &ReleaseInfo) -> Result<()> {
let dir = Directory::queries_directory()
.ok_or_else(|| anyhow!("can't get queries directory"))?;

let file_name = "queries.zip";

download_release(dir, release, file_name)?;

Ok(())
}

fn download_release(
dir: PathBuf,
release: &ReleaseInfo,
file_name: &str,
) -> Result<()> {
if !dir.exists() {
fs::create_dir(&dir)?;
}

let current_version =
fs::read_to_string(dir.join("version")).unwrap_or_default();

if release.tag_name == current_version {
return Ok(());
}

for asset in &release.assets {
if asset.name == file_name {
let mut resp = reqwest::blocking::get(&asset.browser_download_url)?;
if !resp.status().is_success() {
return Err(anyhow!("download file error {}", resp.text()?));
}
{
let mut out = File::create(dir.join(file_name))?;
resp.copy_to(&mut out)?;
}

let mut archive =
zip::ZipArchive::new(File::open(dir.join(file_name))?)?;
archive.extract(&dir)?;
if let Err(err) = fs::remove_file(dir.join(file_name)) {
trace!(TraceLevel::ERROR, "Failed to remove file: {err}");
};
fs::write(dir.join("version"), release.tag_name.clone())?;
}
}
Ok(())
}
3 changes: 1 addition & 2 deletions lapce-app/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@ use serde_json::Value;
use strum::{EnumMessage, IntoEnumIterator};
use strum_macros::{Display, EnumIter, EnumMessage, EnumString, IntoStaticStr};

use crate::main_split::TabCloseKind;
use crate::{
alert::AlertButton,
debug::RunDebugMode,
doc::Doc,
editor::location::EditorLocation,
editor_tab::EditorTabChild,
id::EditorTabId,
main_split::{SplitDirection, SplitMoveDirection},
main_split::{SplitDirection, SplitMoveDirection, TabCloseKind},
workspace::LapceWorkspace,
};

Expand Down
4 changes: 3 additions & 1 deletion lapce-app/src/tracing.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
// Re-export `tracing` crate under own name to not collide and as convenient import
pub use tracing::{event as trace, instrument, Instrument, Level as TraceLevel};
pub use tracing::{
self, event as trace, instrument, Instrument, Level as TraceLevel,
};
Loading

0 comments on commit 9f120f9

Please sign in to comment.