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
6 changes: 6 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ jobs:
target: armv7-unknown-linux-musleabi
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
submodules: true
- name: Install cross
uses: taiki-e/install-action@0aa4f22591557b744fe31e55dbfcdfea74a073f7 # v2
with:
Expand Down Expand Up @@ -96,6 +98,8 @@ jobs:
p12-file-base64: ${{ secrets.APPLE_DEVELOPER_ID_APPLICATION_CERTS_P12 }}
p12-password: ${{ secrets.APPLE_DEVELOPER_ID_APPLICATION_CERTS_P12_PASS }}
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
submodules: true
- name: cache crates
id: cache-crates
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
Expand Down Expand Up @@ -138,6 +142,8 @@ jobs:
target: x86_64-pc-windows-msvc
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
submodules: true
- run: rustup target add ${{matrix.target}}
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2
with:
Expand Down
13 changes: 13 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ jobs:
timeout-minutes: 60
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
submodules: true
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2
with:
shared-key: build
Expand All @@ -54,6 +56,8 @@ jobs:
timeout-minutes: 60
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
submodules: true
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2
with:
shared-key: build
Expand Down Expand Up @@ -82,6 +86,8 @@ jobs:
MISE_CACHE_DIR: ~/.cache/mise
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
submodules: true
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2
with:
shared-key: build
Expand Down Expand Up @@ -118,6 +124,7 @@ jobs:
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.head_ref }}
submodules: true
- uses: taiki-e/install-action@0aa4f22591557b744fe31e55dbfcdfea74a073f7 # v2
with:
tool: cargo-deny,cargo-msrv,cargo-machete
Expand Down Expand Up @@ -155,6 +162,7 @@ jobs:
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.head_ref }}
submodules: true
- run: rustup default nightly
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2
with:
Expand Down Expand Up @@ -185,6 +193,7 @@ jobs:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0
submodules: true
- name: Install build and test dependencies
run: |
sudo apt-get update
Expand Down Expand Up @@ -234,6 +243,8 @@ jobs:
MISE_CACHE_DIR: ~/.cache/mise
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
submodules: true
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2
with:
shared-key: unit
Expand All @@ -253,6 +264,8 @@ jobs:
MISE_CACHE_DIR: ~/.cache/mise
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
submodules: true
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: mise-windows-latest
Expand Down
24 changes: 24 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[submodule "crates/vfox/embedded-plugins/vfox-aapt2"]
path = crates/vfox/embedded-plugins/vfox-aapt2
url = https://github.com/mise-plugins/vfox-aapt2.git
[submodule "crates/vfox/embedded-plugins/vfox-ag"]
path = crates/vfox/embedded-plugins/vfox-ag
url = https://github.com/mise-plugins/vfox-ag.git
[submodule "crates/vfox/embedded-plugins/vfox-android-sdk"]
path = crates/vfox/embedded-plugins/vfox-android-sdk
url = https://github.com/mise-plugins/vfox-android-sdk.git
[submodule "crates/vfox/embedded-plugins/vfox-ant"]
path = crates/vfox/embedded-plugins/vfox-ant
url = https://github.com/mise-plugins/vfox-ant.git
[submodule "crates/vfox/embedded-plugins/vfox-bfs"]
path = crates/vfox/embedded-plugins/vfox-bfs
url = https://github.com/mise-plugins/vfox-bfs.git
[submodule "crates/vfox/embedded-plugins/vfox-bpkg"]
path = crates/vfox/embedded-plugins/vfox-bpkg
url = https://github.com/mise-plugins/vfox-bpkg.git
[submodule "crates/vfox/embedded-plugins/vfox-chicken"]
path = crates/vfox/embedded-plugins/vfox-chicken
url = https://github.com/mise-plugins/vfox-chicken.git
[submodule "crates/vfox/embedded-plugins/vfox-vlang"]
path = crates/vfox/embedded-plugins/vfox-vlang
url = https://github.com/mise-plugins/vfox-vlang.git
3 changes: 2 additions & 1 deletion crates/vfox/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ description = "Interface to vfox plugins"
documentation = "https://docs.rs/vfox"
homepage = "https://github.com/jdx/mise"
repository = "https://github.com/jdx/mise"
include = ["src", "lua", "Cargo.toml", "Cargo.lock", "README.md", "LICENSE"]
include = ["src", "lua", "embedded-plugins", "build.rs", "Cargo.toml", "Cargo.lock", "README.md", "LICENSE"]
build = "build.rs"

[lib]
name = "vfox"
Expand Down
197 changes: 197 additions & 0 deletions crates/vfox/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
use std::collections::BTreeMap;
use std::env;
use std::fs;
use std::path::Path;

fn main() {
codegen_embedded_plugins();
}

/// Convert a path to a string with forward slashes (required for include_str! on Windows)
fn path_to_forward_slashes(path: &Path) -> String {
path.to_string_lossy().replace('\\', "/")
}

fn codegen_embedded_plugins() {
let out_dir = env::var_os("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("embedded_plugins.rs");

let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let embedded_dir = Path::new(&manifest_dir).join("embedded-plugins");

// Tell Cargo to re-run if any embedded plugin files change
println!("cargo:rerun-if-changed=embedded-plugins");

if !embedded_dir.exists() {
// Generate empty implementation if no embedded plugins
let code = r#"
#[derive(Debug)]
pub struct EmbeddedPlugin {
pub metadata: &'static str,
pub hooks: &'static [(&'static str, &'static str)],
pub lib: &'static [(&'static str, &'static str)],
}

pub fn get_embedded_plugin(_name: &str) -> Option<&'static EmbeddedPlugin> {
None
}

pub fn list_embedded_plugins() -> &'static [&'static str] {
&[]
}
"#;
fs::write(&dest_path, code).unwrap();
return;
}

let mut plugins: BTreeMap<String, PluginFiles> = BTreeMap::new();

// Scan for plugin directories
for entry in fs::read_dir(&embedded_dir).unwrap() {
let entry = entry.unwrap();
let path = entry.path();
if !path.is_dir() {
continue;
}

let dir_name = path.file_name().unwrap().to_string_lossy().to_string();
if !dir_name.starts_with("vfox-") {
continue;
}

// Tell Cargo to re-run if this plugin directory changes
println!("cargo:rerun-if-changed={}", path.display());
Comment thread
cursor[bot] marked this conversation as resolved.

let plugin = collect_plugin_files(&path);
plugins.insert(dir_name, plugin);
}

// Generate Rust code
let mut code = String::new();

// Struct definition
code.push_str(
r#"
#[derive(Debug)]
pub struct EmbeddedPlugin {
pub metadata: &'static str,
pub hooks: &'static [(&'static str, &'static str)],
pub lib: &'static [(&'static str, &'static str)],
}

"#,
);

// Generate static instances for each plugin
for (name, files) in &plugins {
let var_name = name.replace('-', "_").to_uppercase();
code.push_str(&format!(
"static {var_name}: EmbeddedPlugin = EmbeddedPlugin {{\n"
));

// Metadata - use absolute path with forward slashes for cross-platform include_str!
let metadata_path = embedded_dir.join(name).join("metadata.lua");
code.push_str(&format!(
" metadata: include_str!(\"{}\"),\n",
path_to_forward_slashes(&metadata_path)
));

// Hooks
code.push_str(" hooks: &[\n");
for hook in &files.hooks {
let hook_path = embedded_dir
.join(name)
.join("hooks")
.join(format!("{}.lua", hook));
code.push_str(&format!(
" (\"{}\", include_str!(\"{}\")),\n",
hook,
path_to_forward_slashes(&hook_path)
));
}
code.push_str(" ],\n");

// Lib files
code.push_str(" lib: &[\n");
for lib in &files.lib {
let lib_path = embedded_dir
.join(name)
.join("lib")
.join(format!("{}.lua", lib));
code.push_str(&format!(
" (\"{}\", include_str!(\"{}\")),\n",
lib,
path_to_forward_slashes(&lib_path)
));
}
code.push_str(" ],\n");

code.push_str("};\n\n");
}

// Generate lookup function
code.push_str("pub fn get_embedded_plugin(name: &str) -> Option<&'static EmbeddedPlugin> {\n");
code.push_str(" match name {\n");
for name in plugins.keys() {
let var_name = name.replace('-', "_").to_uppercase();
let short_name = name.strip_prefix("vfox-").unwrap_or(name);
code.push_str(&format!(
" \"{}\" | \"{}\" => Some(&{}),\n",
name, short_name, var_name
));
}
code.push_str(" _ => None,\n");
code.push_str(" }\n");
code.push_str("}\n\n");

// Generate list function
code.push_str("pub fn list_embedded_plugins() -> &'static [&'static str] {\n");
code.push_str(" &[\n");
for name in plugins.keys() {
code.push_str(&format!(" \"{}\",\n", name));
}
code.push_str(" ]\n");
code.push_str("}\n");

fs::write(&dest_path, code).unwrap();
}

struct PluginFiles {
hooks: Vec<String>,
lib: Vec<String>,
}

fn collect_plugin_files(plugin_dir: &Path) -> PluginFiles {
let mut hooks = Vec::new();
let mut lib = Vec::new();

// Collect hooks
let hooks_dir = plugin_dir.join("hooks");
if hooks_dir.exists() {
for entry in fs::read_dir(&hooks_dir).unwrap() {
let entry = entry.unwrap();
let path = entry.path();
if path.extension().is_some_and(|ext| ext == "lua") {

Copilot AI Dec 17, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pattern is_some_and(|ext| ext == "lua") is repeated for both hooks and lib file collection. Consider extracting a helper function is_lua_file(path: &Path) -> bool to improve maintainability and readability.

Copilot uses AI. Check for mistakes.
let name = path.file_stem().unwrap().to_string_lossy().to_string();
hooks.push(name);
}
}
}
hooks.sort();

// Collect lib files
let lib_dir = plugin_dir.join("lib");
if lib_dir.exists() {
for entry in fs::read_dir(&lib_dir).unwrap() {
let entry = entry.unwrap();
let path = entry.path();
if path.extension().is_some_and(|ext| ext == "lua") {
let name = path.file_stem().unwrap().to_string_lossy().to_string();
lib.push(name);
}
}
}
lib.sort();

PluginFiles { hooks, lib }
}
1 change: 1 addition & 0 deletions crates/vfox/embedded-plugins/vfox-aapt2
Submodule vfox-aapt2 added at 144a5e
1 change: 1 addition & 0 deletions crates/vfox/embedded-plugins/vfox-ag
Submodule vfox-ag added at 1ca4f8
1 change: 1 addition & 0 deletions crates/vfox/embedded-plugins/vfox-android-sdk
Submodule vfox-android-sdk added at 5f8b78
1 change: 1 addition & 0 deletions crates/vfox/embedded-plugins/vfox-ant
Submodule vfox-ant added at 0254eb
1 change: 1 addition & 0 deletions crates/vfox/embedded-plugins/vfox-bfs
Submodule vfox-bfs added at 165106
1 change: 1 addition & 0 deletions crates/vfox/embedded-plugins/vfox-bpkg
Submodule vfox-bpkg added at 365ac7
1 change: 1 addition & 0 deletions crates/vfox/embedded-plugins/vfox-chicken
Submodule vfox-chicken added at 85ce8f
1 change: 1 addition & 0 deletions crates/vfox/embedded-plugins/vfox-vlang
Submodule vfox-vlang added at 61dee7
4 changes: 4 additions & 0 deletions crates/vfox/src/embedded_plugins.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// This module provides access to embedded vfox plugin Lua code.
// The actual code is generated at build time by build.rs

include!(concat!(env!("OUT_DIR"), "/embedded_plugins.rs"));
1 change: 1 addition & 0 deletions crates/vfox/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub use vfox::Vfox;

mod config;
mod context;
pub mod embedded_plugins;
mod error;
mod hooks;
mod http;
Expand Down
Loading
Loading