feat(package): early work in package resolvers

This commit is contained in:
Federico Terzi 2021-08-29 19:16:38 +02:00
parent 03f09e4de8
commit e95fb441bd
6 changed files with 188 additions and 0 deletions

14
Cargo.lock generated
View File

@ -531,6 +531,7 @@ dependencies = [
"espanso-match",
"espanso-migrate",
"espanso-modulo",
"espanso-package",
"espanso-path",
"espanso-render",
"espanso-ui",
@ -741,6 +742,19 @@ dependencies = [
"zip",
]
[[package]]
name = "espanso-package"
version = "0.1.0"
dependencies = [
"anyhow",
"log",
"serde",
"serde_json",
"serde_yaml",
"tempdir",
"thiserror",
]
[[package]]
name = "espanso-path"
version = "0.1.0"

View File

@ -17,4 +17,5 @@ members = [
"espanso-mac-utils",
"espanso-kvs",
"espanso-engine",
"espanso-package",
]

View File

@ -0,0 +1,14 @@
[package]
name = "espanso-package"
version = "0.1.0"
authors = ["Federico Terzi <federico-terzi@users.noreply.github.com>"]
edition = "2018"
[dependencies]
log = "0.4.14"
anyhow = "1.0.38"
thiserror = "1.0.23"
serde = { version = "1.0.123", features = ["derive"] }
serde_json = "1.0.62"
serde_yaml = "0.8.17"
tempdir = "0.3.7"

View File

@ -0,0 +1,61 @@
/*
* This file is part of espanso.
*
* Copyright (C) 2019-2021 Federico Terzi
*
* espanso is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* espanso is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
*/
use std::path::Path;
use anyhow::Result;
use thiserror::Error;
mod resolver;
#[derive(Debug, Default)]
pub struct PackageSpecifier {
pub name: String,
pub version: Option<String>,
// Source information
pub git_repo_url: Option<String>,
pub git_branch: Option<String>,
}
pub trait Package {
// Metadata
fn name(&self) -> &str;
fn title(&self) -> &str;
fn description(&self) -> &str;
fn version(&self) -> &str;
fn author(&self) -> &str;
// Directory containing the package files
fn location(&self) -> &Path;
}
pub trait PackageResolver {
fn download(&self, package: &PackageSpecifier) -> Result<Box<dyn Package>>;
// TODO: fn check update available?
// TODO: fn update
}
// TODO: the git resolver should delete the .git directory
#[derive(Error, Debug)]
pub enum PackageResolutionError {
#[error("package not found")]
PackageNotFound,
}

View File

@ -0,0 +1,78 @@
/*
* This file is part of espanso.
*
* Copyright (C) 2019-2021 Federico Terzi
*
* espanso is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* espanso is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
*/
use crate::{Package, PackageResolver, PackageSpecifier};
use anyhow::{bail, Result, Context};
use std::{path::Path, process::Command};
pub struct GitPackageResolver {}
impl GitPackageResolver {
pub fn new() -> Self {
Self {}
}
fn is_git_installed() -> bool {
if let Ok(output) = Command::new("git").arg("--version").output() {
if output.status.success() {
return true;
}
}
false
}
fn clone_repo(dest_dir: &Path, repo_url: &str, repo_branch: Option<&str>) -> Result<()> {
let mut args = Vec::new();
args.push("clone");
if let Some(branch) = repo_branch {
args.push("-b");
args.push(branch);
}
args.push(repo_url);
let dest_dir_str = dest_dir.to_string_lossy().to_string();
args.push(&dest_dir_str);
let output = Command::new("git").args(&args).output().context("git command reported error")?;
if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
bail!("git command exited with non-zero status: {}", stderr);
} else {
Ok(())
}
}
}
impl PackageResolver for GitPackageResolver {
fn download(&self, package: &PackageSpecifier) -> Result<Box<dyn Package>> {
if !Self::is_git_installed() {
bail!("unable to invoke 'git' command, please make sure it is installed and visible in PATH");
}
// TODO: download repository in temp directory
// TODO: read metadata
todo!()
}
}

View File

@ -0,0 +1,20 @@
/*
* This file is part of espanso.
*
* Copyright (C) 2019-2021 Federico Terzi
*
* espanso is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* espanso is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with espanso. If not, see <https://www.gnu.org/licenses/>.
*/
pub(crate) mod git;