Skip to content

Commit

Permalink
chore: now store architecture as an enum
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickjcasey authored and alilleybrinker committed Sep 3, 2024
1 parent 55fe6f5 commit 34e04af
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 43 deletions.
6 changes: 3 additions & 3 deletions hipcheck/src/cache/plugin_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};

use pathbuf::pathbuf;

use crate::plugin::{PluginArch, PluginName, PluginPublisher, PluginVersion};
use crate::plugin::{PluginName, PluginPublisher, PluginVersion, SupportedArch};

/// Plugins are stored with the following format `<path_to_plugin_cache>/<publisher>/<plugin_name>/<version>/<arch>`
pub struct HcPluginCache {
Expand All @@ -23,12 +23,12 @@ impl HcPluginCache {
publisher: &PluginPublisher,
name: &PluginName,
version: &PluginVersion,
arch: &PluginArch,
arch: SupportedArch,
) -> PathBuf {
self.path
.join(&publisher.0)
.join(&name.0)
.join(&version.0)
.join(&arch.0)
.join(arch.to_string())
}
}
19 changes: 9 additions & 10 deletions hipcheck/src/plugin/download_manifest.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use super::plugin_manifest::PluginArch;
use super::{extract_data, PluginName, PluginPublisher, PluginVersion};
use crate::cache::plugin_cache::HcPluginCache;
use crate::context::Context;
use crate::plugin::retrieval::{download_plugin, extract_plugin};
use crate::plugin::supported_arch::SupportedArch;
use crate::plugin::ParseKdlNode;
use crate::string_newtype_parse_kdl_node;
use crate::util::http::agent::agent;
Expand Down Expand Up @@ -217,9 +217,8 @@ pub struct DownloadManifestEntry {
/// A `SemVer` version of the plugin. Not a version requirement as in the plugin manifest file,
/// but only a specific concrete version
pub version: PluginVersion,
// TODO: make this a target-triple enum?
/// The target architecture for a plugin
pub arch: String,
pub arch: SupportedArch,
/// The URL of the archive file to download containing the plugin executable artifact and
/// plugin manifest.
pub url: url::Url,
Expand All @@ -245,7 +244,7 @@ impl ParseKdlNode for DownloadManifestEntry {
// Per RFD #0004, version is of type String
let version = PluginVersion(node.get("version")?.value().as_string()?.to_string());
// Per RFD #0004, arch is of type String
let arch = node.get("arch")?.value().as_string()?.to_string();
let arch = SupportedArch::from_str(node.get("arch")?.value().as_string()?).ok()?;

// there should be one child for each plugin and it should contain the url, hash, compress
// and size information
Expand Down Expand Up @@ -276,7 +275,7 @@ impl DownloadManifestEntry {
publisher: &PluginPublisher,
name: &PluginName,
version: &PluginVersion,
arch: &PluginArch,
arch: SupportedArch,
) -> Result<(), Error> {
// currently plugins are put in HC_CACHE/plugins/<publisher>/<name>/<version>/<arch>
let download_dir = plugin_cache.plugin_download_dir(publisher, name, version, arch);
Expand Down Expand Up @@ -312,7 +311,7 @@ impl DownloadManifestEntry {
publisher.0,
name.0,
version.0,
arch.0
arch
)
})
}
Expand All @@ -338,7 +337,7 @@ impl DownloadManifest {
publisher: &PluginPublisher,
name: &PluginName,
version: &PluginVersion,
arch: &PluginArch,
arch: SupportedArch,
) -> Result<(), Error> {
self.entries.iter().try_for_each(|entry| {
entry.download_and_unpack_plugin(plugin_cache, publisher, name, version, arch)
Expand Down Expand Up @@ -478,7 +477,7 @@ mod test {

let expected_entry = DownloadManifestEntry {
version: PluginVersion(version.to_string()),
arch: arch.to_string(),
arch: SupportedArch::from_str(arch).unwrap(),
url: Url::parse(url).unwrap(),
hash: HashWithDigest::new(
HashAlgorithm::try_from(hash_alg).unwrap(),
Expand Down Expand Up @@ -519,7 +518,7 @@ plugin version="0.1.0" arch="x86_64-apple-darwin" {
assert_eq!(
&DownloadManifestEntry {
version: PluginVersion("0.1.0".to_owned()),
arch: "aarch64-apple-darwin".to_owned(),
arch: SupportedArch::Aarch64AppleDarwin,
url: Url::parse("https://github.com/mitre/hipcheck/releases/download/hipcheck-v3.4.0/hipcheck-aarch64-apple-darwin.tar.xz").unwrap(),
hash: HashWithDigest::new(HashAlgorithm::Sha256, "b8e111e7817c4a1eb40ed50712d04e15b369546c4748be1aa8893b553f4e756b".to_owned()),
compress: Compress::new(ArchiveFormat::TarXz),
Expand All @@ -532,7 +531,7 @@ plugin version="0.1.0" arch="x86_64-apple-darwin" {
assert_eq!(
&DownloadManifestEntry {
version: PluginVersion("0.1.0".to_owned()),
arch: "x86_64-apple-darwin".to_owned(),
arch: SupportedArch::X86_64AppleDarwin,
url: Url::parse("https://github.com/mitre/hipcheck/releases/download/hipcheck-v3.4.0/hipcheck-x86_64-apple-darwin.tar.xz").unwrap(),
hash: HashWithDigest::new(HashAlgorithm::Sha256, "ddb8c6d26dd9a91e11c99b3bd7ee2b9585aedac6e6df614190f1ba2bfe86dc19".to_owned()),
compress: Compress::new(ArchiveFormat::TarXz),
Expand Down
4 changes: 3 additions & 1 deletion hipcheck/src/plugin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ mod kdl_parsing;
mod manager;
mod plugin_manifest;
mod retrieval;
mod supported_arch;
mod types;

pub use crate::plugin::manager::*;
Expand All @@ -11,7 +12,8 @@ pub use download_manifest::{
ArchiveFormat, DownloadManifest, DownloadManifestEntry, HashAlgorithm, HashWithDigest,
};
pub use kdl_parsing::{extract_data, ParseKdlNode};
pub use plugin_manifest::{PluginArch, PluginManifest, PluginName, PluginPublisher, PluginVersion};
pub use plugin_manifest::{PluginManifest, PluginName, PluginPublisher, PluginVersion};
pub use supported_arch::SupportedArch;

use crate::Result;
use futures::future::join_all;
Expand Down
50 changes: 21 additions & 29 deletions hipcheck/src/plugin/plugin_manifest.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use super::extract_data;
use crate::plugin::supported_arch::SupportedArch;
use crate::plugin::ParseKdlNode;
use crate::string_newtype_parse_kdl_node;
use crate::{error::Error, hc_error};
use core::panic;
use kdl::{KdlDocument, KdlEntry, KdlNode, KdlValue};
use petgraph::graphmap::NeighborsDirected;
use std::collections::HashMap;
use std::fmt::write;
use std::{fmt::Display, str::FromStr};

use super::extract_data;

// NOTE: the implementation in this crate was largely derived from RFD #0004

#[derive(Clone, Debug, PartialEq, Eq)]
Expand All @@ -27,26 +28,22 @@ string_newtype_parse_kdl_node!(PluginVersion, "version");
pub struct License(pub String);
string_newtype_parse_kdl_node!(License, "license");

// TODO: target-triple enum
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct PluginArch(pub String);

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Entrypoints(pub HashMap<PluginArch, String>);
pub struct Entrypoints(pub HashMap<SupportedArch, String>);

impl Entrypoints {
pub fn new() -> Self {
Self(HashMap::new())
}

pub fn insert(&mut self, arch: PluginArch, entrypoint: String) -> Result<(), Error> {
match self.0.insert(arch.clone(), entrypoint) {
Some(_duplicate_key) => Err(hc_error!("Multiple entrypoints specified for {}", arch.0)),
pub fn insert(&mut self, arch: SupportedArch, entrypoint: String) -> Result<(), Error> {
match self.0.insert(arch, entrypoint) {
Some(_duplicate_key) => Err(hc_error!("Multiple entrypoints specified for {}", arch)),
None => Ok(()),
}
}

pub fn iter(&self) -> impl Iterator<Item = (&PluginArch, &String)> {
pub fn iter(&self) -> impl Iterator<Item = (&SupportedArch, &String)> {
self.0.iter()
}
}
Expand All @@ -63,13 +60,8 @@ impl ParseKdlNode for Entrypoints {
let mut entrypoints = Entrypoints::new();
for entrypoint_spec in node.children()?.nodes() {
// per RFD #0004, the value for "arch" is of type String
let arch = PluginArch(
entrypoint_spec
.get("arch")?
.value()
.as_string()?
.to_string(),
);
let arch =
SupportedArch::from_str(entrypoint_spec.get("arch")?.value().as_string()?).ok()?;
// per RFD #0004, the actual entrypoint is the first positional arg after "arch" and is
// of type String
let entrypoint = entrypoint_spec
Expand All @@ -78,8 +70,8 @@ impl ParseKdlNode for Entrypoints {
.value()
.as_string()?
.to_string();
if let Err(e) = entrypoints.insert(arch.clone(), entrypoint) {
log::error!("Duplicate entrypoint detected for [{}]", arch.0);
if let Err(e) = entrypoints.insert(arch, entrypoint) {
log::error!("Duplicate entrypoint detected for [{}]", arch);
return None;
}
}
Expand Down Expand Up @@ -291,7 +283,7 @@ mod test {
let mut expected = Entrypoints::new();
expected
.insert(
PluginArch("aarch64-apple-darwin".to_owned()),
SupportedArch::Aarch64AppleDarwin,
"./hc-mitre-affiliation".to_owned(),
)
.unwrap();
Expand Down Expand Up @@ -320,19 +312,19 @@ mod test {
let node = KdlNode::from_str(multiple_entrypoint).unwrap();
let mut expected = Entrypoints::new();
expected.insert(
PluginArch("aarch64-apple-darwin".to_owned()),
SupportedArch::Aarch64AppleDarwin,
"./hc-mitre-affiliation".to_owned(),
);
expected.insert(
PluginArch("x86_64-apple-darwin".to_owned()),
SupportedArch::X86_64AppleDarwin,
"./hc-mitre-affiliation".to_owned(),
);
expected.insert(
PluginArch("x86_64-unknown-linux-gnu".to_owned()),
SupportedArch::X86_64UnknownLinuxGnu,
"./hc-mitre-affiliation".to_owned(),
);
expected.insert(
PluginArch("x86_64-pc-windows-msvc".to_owned()),
SupportedArch::X86_64PcWindowsMsvc,
"./hc-mitre-affiliation".to_owned(),
);
assert_eq!(Entrypoints::parse_node(&node).unwrap(), expected)
Expand Down Expand Up @@ -412,19 +404,19 @@ dependencies {

let mut entrypoints = Entrypoints::new();
entrypoints.insert(
PluginArch("aarch64-apple-darwin".to_owned()),
SupportedArch::Aarch64AppleDarwin,
"./hc-mitre-affiliation".to_owned(),
);
entrypoints.insert(
PluginArch("x86_64-apple-darwin".to_owned()),
SupportedArch::X86_64AppleDarwin,
"./hc-mitre-affiliation".to_owned(),
);
entrypoints.insert(
PluginArch("x86_64-unknown-linux-gnu".to_owned()),
SupportedArch::X86_64UnknownLinuxGnu,
"./hc-mitre-affiliation".to_owned(),
);
entrypoints.insert(
PluginArch("x86_64-pc-windows-msvc".to_owned()),
SupportedArch::X86_64PcWindowsMsvc,
"./hc-mitre-affiliation".to_owned(),
);

Expand Down
44 changes: 44 additions & 0 deletions hipcheck/src/plugin/supported_arch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use std::{fmt::Display, str::FromStr};

use crate::hc_error;

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
/// Officially supported target triples, as of RFD #0004
///
/// NOTE: these architectures correspond to the offically supported Rust platforms
pub enum SupportedArch {
/// Used for macOS running on "Apple Silicon" running on a 64-bit ARM Instruction Set Architecture (ISA)
Aarch64AppleDarwin,
/// Used for macOS running on the Intel 64-bit ISA
X86_64AppleDarwin,
/// Used for Windows running on the Intel 64-bit ISA with the Microsoft Visual Studio Code toolchain for compilation
X86_64PcWindowsMsvc,
/// Used for Linux operating systems running on the Intel 64-bit ISA with a GNU toolchain for compilation
X86_64UnknownLinuxGnu,
}

impl FromStr for SupportedArch {
type Err = crate::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"aarch64-apple-darwin" => Ok(Self::Aarch64AppleDarwin),
"x86_64-apple-darwin" => Ok(Self::X86_64AppleDarwin),
"x86_64-pc-windows-msvc" => Ok(Self::X86_64PcWindowsMsvc),
"x86_64-unknown-linux-gnu" => Ok(Self::X86_64UnknownLinuxGnu),
_ => Err(hc_error!("Error parsing arch '{}'", s)),
}
}
}

impl Display for SupportedArch {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let target_triple = match self {
SupportedArch::Aarch64AppleDarwin => "aarch64-apple-darwin",
SupportedArch::X86_64AppleDarwin => "x86_64-apple-darwin",
SupportedArch::X86_64PcWindowsMsvc => "x86_64-pc-windows-msvc",
SupportedArch::X86_64UnknownLinuxGnu => "x86_64-unknown-linux-gnu",
};
write!(f, "{}", target_triple)
}
}

0 comments on commit 34e04af

Please sign in to comment.