diff --git a/docs/src/content/docs/guides/self-hosting-registries.mdx b/docs/src/content/docs/guides/self-hosting-registries.mdx
index 82dfa38..f51ffcc 100644
--- a/docs/src/content/docs/guides/self-hosting-registries.mdx
+++ b/docs/src/content/docs/guides/self-hosting-registries.mdx
@@ -19,10 +19,10 @@ To create an index, create a new repository and add a `config.toml` file with
the following content:
```toml title="config.toml"
-# The URL of the registry API
+# the URL of the registry API
api = "https://registry.acme.local/"
-# Package download URL (optional)
+# package download URL (optional)
download = "{API_URL}/v0/packages/{PACKAGE}/{PACKAGE_VERSION}/{PACKAGE_TARGET}"
# the client ID of the GitHub OAuth app (optional)
@@ -33,13 +33,16 @@ git_allowed = true
# whether to allow packages which depend on packages from other registries
# (default: false)
-other_registries_allowed = true
+other_registries_allowed = ["https://git.acme.local/index"]
# whether to allow packages with Wally dependencies (default: false)
wally_allowed = false
# the maximum size of the archive in bytes (default: 4MB)
max_archive_size = 4194304
+
+# the scripts packages present in the `init` command selection by default
+scripts_packages = ["pesde/scripts_rojo"]
```
- **api**: The URL of the registry API. See below for more information.
@@ -60,18 +63,24 @@ max_archive_size = 4194304
- **github_oauth_client_id**: This is required if you use GitHub OAuth for
authentication. See below for more information.
-- **git_allowed**: Whether to allow packages with Git dependencies. This is
- optional and defaults to `false`.
+- **git_allowed**: Whether to allow packages with Git dependencies. This can be
+ either a bool or a list of allowed repository URLs. This is optional and
+ defaults to `false`.
- **other_registries_allowed**: Whether to allow packages which depend on
- packages from other registries. This is optional and defaults to `false`.
+ packages from other registries. This can be either a bool or a list of
+ allowed index repository URLs. This is optional and defaults to `false`.
-- **wally_allowed**: Whether to allow packages with Wally dependencies. This is
+- **wally_allowed**: Whether to allow packages with Wally dependencies. This can
+ be either a bool or a list of allowed index repository URLs. This is
optional and defaults to `false`.
- **max_archive_size**: The maximum size of the archive in bytes. This is
optional and defaults to `4194304` (4MB).
+- **scripts_packages**: The scripts packages present in the `init` command
+ selection by default. This is optional and defaults to none.
+
You should then push this repository to [GitHub](https://github.com/).
## Configuring the registry
@@ -88,8 +97,8 @@ has access to the index repository. We recommend using a separate account
for this purpose.
diff --git a/registry/src/endpoints/publish_version.rs b/registry/src/endpoints/publish_version.rs
index 929ddbf..42b21e2 100644
--- a/registry/src/endpoints/publish_version.rs
+++ b/registry/src/endpoints/publish_version.rs
@@ -304,7 +304,7 @@ pub async fn publish_package(
.filter(|index| match gix::Url::try_from(*index) {
Ok(url) => config
.other_registries_allowed
- .is_allowed(source.repo_url().clone(), url),
+ .is_allowed_or_same(source.repo_url().clone(), url),
Err(_) => false,
})
.is_none()
@@ -315,16 +315,13 @@ pub async fn publish_package(
}
}
DependencySpecifiers::Wally(specifier) => {
- if !config.wally_allowed {
- return Err(Error::InvalidArchive(
- "wally dependencies are not allowed".into(),
- ));
- }
-
if specifier
.index
- .as_ref()
- .filter(|index| index.parse::().is_ok())
+ .as_deref()
+ .filter(|index| match gix::Url::try_from(*index) {
+ Ok(url) => config.wally_allowed.is_allowed(url),
+ Err(_) => false,
+ })
.is_none()
{
return Err(Error::InvalidArchive(format!(
@@ -332,15 +329,15 @@ pub async fn publish_package(
)));
}
}
- DependencySpecifiers::Git(_) => {
- if !config.git_allowed {
+ DependencySpecifiers::Git(specifier) => {
+ if !config.git_allowed.is_allowed(specifier.repo.clone()) {
return Err(Error::InvalidArchive(
"git dependencies are not allowed".into(),
));
}
}
DependencySpecifiers::Workspace(_) => {
- // workspace specifiers are to be transformed into Pesde specifiers by the sender
+ // workspace specifiers are to be transformed into pesde specifiers by the sender
return Err(Error::InvalidArchive(
"non-transformed workspace dependency".into(),
));
diff --git a/src/cli/commands/publish.rs b/src/cli/commands/publish.rs
index 855643b..550b1a8 100644
--- a/src/cli/commands/publish.rs
+++ b/src/cli/commands/publish.rs
@@ -9,6 +9,7 @@ use pesde::{
matching_globs_old_behaviour,
scripts::ScriptName,
source::{
+ git_index::GitBasedSource,
pesde::{specifier::PesdeDependencySpecifier, PesdePackageSource},
specifiers::DependencySpecifiers,
traits::PackageSource,
@@ -362,10 +363,6 @@ info: otherwise, the file was deemed unnecessary, if you don't understand why, p
}
}
- #[cfg(feature = "wally-compat")]
- let mut has_wally = false;
- let mut has_git = false;
-
for specifier in manifest
.dependencies
.values_mut()
@@ -389,8 +386,6 @@ info: otherwise, the file was deemed unnecessary, if you don't understand why, p
}
#[cfg(feature = "wally-compat")]
DependencySpecifiers::Wally(specifier) => {
- has_wally = true;
-
let index_name = specifier
.index
.as_deref()
@@ -406,9 +401,7 @@ info: otherwise, the file was deemed unnecessary, if you don't understand why, p
.to_string(),
);
}
- DependencySpecifiers::Git(_) => {
- has_git = true;
- }
+ DependencySpecifiers::Git(_) => {}
DependencySpecifiers::Workspace(spec) => {
let pkg_ref = WorkspacePackageSource
.resolve(spec, project, target_kind, &mut HashSet::new())
@@ -570,8 +563,7 @@ info: otherwise, the file was deemed unnecessary, if you don't understand why, p
.get(&self.index)
.context(format!("missing index {}", self.index))?;
let source = PesdePackageSource::new(index_url.clone());
- source
- .refresh(project)
+ PackageSource::refresh(&source, project)
.await
.context("failed to refresh source")?;
let config = source
@@ -587,15 +579,31 @@ info: otherwise, the file was deemed unnecessary, if you don't understand why, p
);
}
- manifest.all_dependencies().context("dependency conflict")?;
+ let deps = manifest.all_dependencies().context("dependency conflict")?;
- if !config.git_allowed && has_git {
- anyhow::bail!("git dependencies are not allowed on this index");
- }
-
- #[cfg(feature = "wally-compat")]
- if !config.wally_allowed && has_wally {
- anyhow::bail!("wally dependencies are not allowed on this index");
+ if let Some((disallowed, _)) = deps.iter().find(|(_, (spec, _))| match spec {
+ DependencySpecifiers::Pesde(spec) => {
+ !config.other_registries_allowed.is_allowed_or_same(
+ source.repo_url().clone(),
+ manifest
+ .indices
+ .get(spec.index.as_deref().unwrap_or(DEFAULT_INDEX_NAME))
+ .unwrap()
+ .clone(),
+ )
+ }
+ DependencySpecifiers::Git(spec) => !config.git_allowed.is_allowed(spec.repo.clone()),
+ #[cfg(feature = "wally-compat")]
+ DependencySpecifiers::Wally(spec) => !config.wally_allowed.is_allowed(
+ manifest
+ .wally_indices
+ .get(spec.index.as_deref().unwrap_or(DEFAULT_INDEX_NAME))
+ .unwrap()
+ .clone(),
+ ),
+ _ => false,
+ }) {
+ anyhow::bail!("dependency `{disallowed}` is not allowed on this index");
}
if self.dry_run {
diff --git a/src/source/pesde/mod.rs b/src/source/pesde/mod.rs
index 45816ae..a39037c 100644
--- a/src/source/pesde/mod.rs
+++ b/src/source/pesde/mod.rs
@@ -274,22 +274,30 @@ impl Default for AllowedRegistries {
}
}
-impl AllowedRegistries {
- /// Whether the given URL is allowed
- pub fn is_allowed(&self, mut this: Url, mut external: Url) -> bool {
- // strip .git suffix to allow for more flexible matching
- this.path = this.path.strip_suffix(b".git").unwrap_or(&this.path).into();
- external.path = external
- .path
- .strip_suffix(b".git")
- .unwrap_or(&external.path)
- .into();
+// strips .git suffix to allow for more flexible matching
+fn simplify_url(mut url: Url) -> Url {
+ url.path = url.path.strip_suffix(b".git").unwrap_or(&url.path).into();
+ url
+}
- this == external
- || (match self {
- Self::All(all) => *all,
- Self::Specific(urls) => urls.contains(&this) || urls.contains(&external),
- })
+impl AllowedRegistries {
+ fn _is_allowed(&self, url: &Url) -> bool {
+ match self {
+ Self::All(all) => *all,
+ Self::Specific(urls) => urls.contains(url),
+ }
+ }
+
+ /// Whether the given URL is allowed
+ pub fn is_allowed(&self, url: Url) -> bool {
+ self._is_allowed(&simplify_url(url))
+ }
+
+ /// Whether the given URL is allowed, or is the same as the given URL
+ pub fn is_allowed_or_same(&self, this: Url, external: Url) -> bool {
+ let this = simplify_url(this);
+ let external = simplify_url(external);
+ (this == external) || self._is_allowed(&external) || self._is_allowed(&this)
}
}
@@ -302,13 +310,13 @@ pub struct IndexConfig {
pub download: Option,
/// Whether Git is allowed as a source for publishing packages
#[serde(default)]
- pub git_allowed: bool,
+ pub git_allowed: AllowedRegistries,
/// Whether other registries are allowed as a source for publishing packages
#[serde(default)]
pub other_registries_allowed: AllowedRegistries,
/// Whether Wally is allowed as a source for publishing packages
#[serde(default)]
- pub wally_allowed: bool,
+ pub wally_allowed: AllowedRegistries,
/// The OAuth client ID for GitHub
#[serde(default)]
pub github_oauth_client_id: Option,