Compare commits

...

1 Commits

Author SHA1 Message Date
MrSubidubi
931285eba5 Support multiple snippets locations per extension 2025-12-29 17:43:31 +01:00
4 changed files with 55 additions and 23 deletions

View File

@@ -711,7 +711,7 @@ mod tests {
use indoc::indoc;
use crate::{
ExtensionManifest,
ExtensionManifest, ExtensionSnippets,
extension_builder::{file_newer_than_deps, populate_defaults},
};
@@ -785,7 +785,9 @@ mod tests {
assert_eq!(
manifest.snippets,
Some(PathBuf::from_str("./snippets/snippets.json").unwrap())
Some(ExtensionSnippets::Single(
PathBuf::from_str("./snippets/snippets.json").unwrap()
))
)
}
@@ -820,7 +822,9 @@ mod tests {
assert_eq!(
manifest.snippets,
Some(PathBuf::from_str("snippets.json").unwrap())
Some(ExtensionSnippets::Single(
PathBuf::from_str("snippets.json").unwrap()
))
)
}
}

View File

@@ -53,6 +53,28 @@ impl SchemaVersion {
}
}
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ExtensionSnippets {
Single(PathBuf),
Multiple(Vec<PathBuf>),
}
impl ExtensionSnippets {
pub fn paths(&self) -> impl Iterator<Item = &PathBuf> {
match self {
ExtensionSnippets::Single(path) => std::slice::from_ref(path).iter(),
ExtensionSnippets::Multiple(paths) => paths.iter(),
}
}
}
impl From<&str> for ExtensionSnippets {
fn from(value: &str) -> Self {
ExtensionSnippets::Single(value.into())
}
}
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
pub struct ExtensionManifest {
pub id: Arc<str>,
@@ -86,7 +108,7 @@ pub struct ExtensionManifest {
#[serde(default)]
pub slash_commands: BTreeMap<Arc<str>, SlashCommandManifestEntry>,
#[serde(default)]
pub snippets: Option<PathBuf>,
pub snippets: Option<ExtensionSnippets>,
#[serde(default)]
pub capabilities: Vec<ExtensionCapability>,
#[serde(default, skip_serializing_if = "BTreeMap::is_empty")]

View File

@@ -306,22 +306,26 @@ async fn copy_extension_resources(
}
}
if let Some(snippets_path) = manifest.snippets.as_ref() {
let parent = snippets_path.parent();
if let Some(parent) = parent.filter(|p| p.components().next().is_some()) {
fs::create_dir_all(output_dir.join(parent))?;
if let Some(snippets) = manifest.snippets.as_ref() {
for snippets_path in snippets.paths() {
let parent = snippets_path.parent();
if let Some(parent) = parent.filter(|p| p.components().next().is_some()) {
fs::create_dir_all(output_dir.join(parent))?;
}
copy_recursive(
fs.as_ref(),
&extension_path.join(&snippets_path),
&output_dir.join(&snippets_path),
CopyOptions {
overwrite: true,
ignore_if_exists: false,
},
)
.await
.with_context(|| {
format!("failed to copy snippets from '{}'", snippets_path.display())
})?;
}
copy_recursive(
fs.as_ref(),
&extension_path.join(&snippets_path),
&output_dir.join(&snippets_path),
CopyOptions {
overwrite: true,
ignore_if_exists: false,
},
)
.await
.with_context(|| format!("failed to copy snippets from '{}'", snippets_path.display()))?;
}
Ok(())

View File

@@ -1261,10 +1261,12 @@ impl ExtensionStore {
(path, icons_root_path)
},
));
snippets_to_add.extend(extension.manifest.snippets.iter().map(|snippets_path| {
let mut path = self.installed_dir.clone();
path.extend([Path::new(extension_id.as_ref()), snippets_path.as_path()]);
path
snippets_to_add.extend(extension.manifest.snippets.iter().flat_map(|snippets| {
snippets.paths().map(|snippets_path| {
let mut path = self.installed_dir.clone();
path.extend([Path::new(extension_id.as_ref()), snippets_path.as_path()]);
path
})
}));
}