diff options
Diffstat (limited to 'vendor/gix-submodule')
-rw-r--r-- | vendor/gix-submodule/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | vendor/gix-submodule/CHANGELOG.md | 179 | ||||
-rw-r--r-- | vendor/gix-submodule/Cargo.toml | 47 | ||||
-rw-r--r-- | vendor/gix-submodule/LICENSE-APACHE | 191 | ||||
-rw-r--r-- | vendor/gix-submodule/LICENSE-MIT | 21 | ||||
-rw-r--r-- | vendor/gix-submodule/src/access.rs | 248 | ||||
-rw-r--r-- | vendor/gix-submodule/src/config.rs | 216 | ||||
-rw-r--r-- | vendor/gix-submodule/src/is_active_platform.rs | 49 | ||||
-rw-r--r-- | vendor/gix-submodule/src/lib.rs | 144 | ||||
-rw-r--r-- | vendor/gix-submodule/tests/file/baseline.rs | 80 | ||||
-rw-r--r-- | vendor/gix-submodule/tests/file/mod.rs | 453 | ||||
-rwxr-xr-x | vendor/gix-submodule/tests/fixtures/basic.sh | 48 | ||||
-rw-r--r-- | vendor/gix-submodule/tests/fixtures/generated-archives/basic.tar.xz | bin | 0 -> 32472 bytes | |||
-rw-r--r-- | vendor/gix-submodule/tests/submodule.rs | 3 |
14 files changed, 1680 insertions, 0 deletions
diff --git a/vendor/gix-submodule/.cargo-checksum.json b/vendor/gix-submodule/.cargo-checksum.json new file mode 100644 index 000000000..6b7ad8938 --- /dev/null +++ b/vendor/gix-submodule/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"CHANGELOG.md":"0aea97d3e31f29941e3a88f4860b893321f455ee0e1244ce08bce0e5446c41a0","Cargo.toml":"7dab80e931c6f5c9fae910a71694c95b229756153f0aff62cfd548d438a3b6e8","LICENSE-APACHE":"cb4780590812826851ba250f90bed0ed19506ec98f6865a0e2e20bbf62391ff9","LICENSE-MIT":"49df47913ab2beafe8dc45607877ae64198bf0eee64aaad3e82ed9e4d27424e8","src/access.rs":"162ad231287795c40681f47eb516b91c706215687ea7ed7d7a98b762feb46d8c","src/config.rs":"2062c34f82e42517ac0d8d2d564643883249f6f44b5e8cc49f00f085ce66b31d","src/is_active_platform.rs":"fa89ba25ae7cde8f0b04bb032a27ad22919aeea7d285c003355cd9ea0d980157","src/lib.rs":"a896e4f0188322673835674b49be1b013f4aefa997fe25f34ad8d4fcc9c8d850","tests/file/baseline.rs":"8d80db5bdfcb0625153617c39fdada700921487a083391822dec4363c33fadb4","tests/file/mod.rs":"aa7b943bf8518e79df663e0de32b0266ac00bae2aa9f9c7653cf6745031a14a1","tests/fixtures/basic.sh":"22a14fd8fac3377b9a7653f60348ba0906777b2ecc23405c4b604c4834e7eec4","tests/fixtures/generated-archives/basic.tar.xz":"f1213af1023577c8c59e1a065530785e28ee10e4e04f731597aebc6a63e3dc86","tests/submodule.rs":"e42d1f34b35a3230f29ae4f04524c113b5059aa5753bbee1818e245888457ddd"},"package":"dd0150e82e9282d3f2ab2dd57a22f9f6c3447b9d9856e5321ac92d38e3e0e2b7"}
\ No newline at end of file diff --git a/vendor/gix-submodule/CHANGELOG.md b/vendor/gix-submodule/CHANGELOG.md new file mode 100644 index 000000000..f5a4ed63e --- /dev/null +++ b/vendor/gix-submodule/CHANGELOG.md @@ -0,0 +1,179 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## 0.4.0 (2023-09-24) + +A maintenance release without user-facing changes. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 1 commit contributed to the release. + - 15 days passed between releases. + - 0 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Prepare changelogs prior to release ([`8a60d5b`](https://github.com/Byron/gitoxide/commit/8a60d5b80877c213c3b646d3061e8a33e0e433ec)) +</details> + +## 0.3.0 (2023-09-08) + +### Bug Fixes (BREAKING) + + - <csr-id-072ee32f693a31161cd6a843da6582d13efbb20b/> use `dyn` trait where possible. + This reduces compile time due to avoiding duplication. + - <csr-id-25c5bcebd4dbc4ac189d8af044ed0352c6188ce8/> `IsActivePlatform::is_active()` now only considers the URL in passed configuration + Previously, it would consider the presence of `url` in the `.gitmodules` file as well, which is + not the way git does it. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 10 commits contributed to the release over the course of 17 calendar days. + - 17 days passed between releases. + - 2 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-transport v0.36.0, gix-protocol v0.39.0, gix-revision v0.21.0, gix-refspec v0.17.0, gix-submodule v0.3.0, gix-worktree v0.25.0, gix-worktree-state v0.2.0, gix v0.53.0 ([`1ff3064`](https://github.com/Byron/gitoxide/commit/1ff30641b8724efd6699d8bef5c71d28454e98b9)) + - Release gix-date v0.8.0, gix-hash v0.13.0, gix-features v0.34.0, gix-actor v0.26.0, gix-object v0.36.0, gix-path v0.10.0, gix-glob v0.12.0, gix-attributes v0.18.0, gix-packetline-blocking v0.16.6, gix-filter v0.4.0, gix-fs v0.6.0, gix-commitgraph v0.20.0, gix-hashtable v0.4.0, gix-revwalk v0.7.0, gix-traverse v0.32.0, gix-worktree-stream v0.4.0, gix-archive v0.4.0, gix-config-value v0.14.0, gix-tempfile v9.0.0, gix-lock v9.0.0, gix-ref v0.36.0, gix-sec v0.10.0, gix-config v0.29.0, gix-prompt v0.7.0, gix-url v0.23.0, gix-credentials v0.19.0, gix-diff v0.35.0, gix-discover v0.24.0, gix-ignore v0.7.0, gix-index v0.24.0, gix-macros v0.1.0, gix-mailmap v0.18.0, gix-negotiate v0.7.0, gix-pack v0.42.0, gix-odb v0.52.0, gix-pathspec v0.2.0, gix-packetline v0.16.6, gix-transport v0.36.0, gix-protocol v0.39.0, gix-revision v0.21.0, gix-refspec v0.17.0, gix-submodule v0.3.0, gix-worktree v0.25.0, gix-worktree-state v0.2.0, gix v0.53.0, safety bump 39 crates ([`8bd0456`](https://github.com/Byron/gitoxide/commit/8bd045676bb2cdc02624ab93e73ff8518064ca38)) + - Prepare changelogs for release ([`375db06`](https://github.com/Byron/gitoxide/commit/375db06a8442378c3f7a922fae38e2a6694d9d04)) + - Merge branch 'optimizations' ([`6135a5e`](https://github.com/Byron/gitoxide/commit/6135a5ea8709646f01da62939a59dd3a9750e007)) + - Add example that tries to trip someone who reads something from the index ([`b35e544`](https://github.com/Byron/gitoxide/commit/b35e544383b9a7571961ff0628ca8db1b232bf52)) + - Merge branch `dyn`ification ([`f658fcc`](https://github.com/Byron/gitoxide/commit/f658fcc52dc2200ae34ca53dc10be97fb9012057)) + - Use `dyn` trait where possible. ([`072ee32`](https://github.com/Byron/gitoxide/commit/072ee32f693a31161cd6a843da6582d13efbb20b)) + - Merge branch 'adjustments-for-cargo' ([`b7560a2`](https://github.com/Byron/gitoxide/commit/b7560a2445b62f888bf5aa2ba4c5a47ae037cb23)) + - `IsActivePlatform::is_active()` now only considers the URL in passed configuration ([`25c5bce`](https://github.com/Byron/gitoxide/commit/25c5bcebd4dbc4ac189d8af044ed0352c6188ce8)) + - Merge branch 'gix-submodule' ([`363ee77`](https://github.com/Byron/gitoxide/commit/363ee77400805f473c9ad66eadad9214e7ab66f4)) +</details> + +## 0.2.0 (2023-08-22) + +<csr-id-229bd4899213f749a7cc124aa2b82a1368fba40f/> + +### Chore + + - <csr-id-229bd4899213f749a7cc124aa2b82a1368fba40f/> don't call crate 'WIP' in manifest anymore. + +### New Features + + - <csr-id-af1cab31fd5ead445c988cce058c136c81229ad1/> TBD a way to learn if submodules are active efficiently + +### Bug Fixes + + - <csr-id-e0d9b09d02f88536b93ab6a31fddf9483881c5c1/> `Modules::is_active()` now counts everything that doesn't match `submodule.active` (if present) as inactive. + - <csr-id-8172f0e0f19e84fdaedceb87399f3fab4a1eb563/> Assure `gix-submodule` works with Rust 1.65. + The previous version of this loop, possibly preferable, ran into + a borrow-check issue that was no more from Rust 1.70 onwards. + +### New Features (BREAKING) + + - <csr-id-3503f4948b42854256c9e8d8336ebe222fee980b/> remove `File::names_and_active_state()` in favor of `File::is_active_platform()`. + With this platform it's possible to make repeated checks to see if a named submodule is active. + - <csr-id-4a443e453285095daccdca0fed9e8486ce7892ab/> make API less error prone by enforcing overrides at instantiation time. + It's made so that overrides can still be applied at a later point. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 13 commits contributed to the release over the course of 4 calendar days. + - 15 days passed between releases. + - 6 commits were understood as [conventional](https://www.conventionalcommits.org). + - 0 issues like '(#ID)' were seen in commit messages + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **Uncategorized** + - Release gix-url v0.22.0, gix-credentials v0.18.0, gix-diff v0.34.0, gix-discover v0.23.0, gix-ignore v0.6.0, gix-bitmap v0.2.7, gix-index v0.22.0, gix-mailmap v0.17.0, gix-negotiate v0.6.0, gix-pack v0.41.0, gix-odb v0.51.0, gix-pathspec v0.1.0, gix-packetline v0.16.5, gix-transport v0.35.0, gix-protocol v0.38.0, gix-revision v0.20.0, gix-refspec v0.16.0, gix-submodule v0.2.0, gix-worktree v0.24.0, gix-worktree-state v0.1.0, gix v0.52.0, gitoxide-core v0.31.0, gitoxide v0.29.0 ([`6c62e74`](https://github.com/Byron/gitoxide/commit/6c62e748240ac0980fc23fdf30f8477dea8b9bc3)) + - Release gix-date v0.7.3, gix-hash v0.12.0, gix-features v0.33.0, gix-actor v0.25.0, gix-object v0.35.0, gix-path v0.9.0, gix-glob v0.11.0, gix-quote v0.4.7, gix-attributes v0.17.0, gix-command v0.2.9, gix-packetline-blocking v0.16.5, gix-filter v0.3.0, gix-fs v0.5.0, gix-commitgraph v0.19.0, gix-hashtable v0.3.0, gix-revwalk v0.6.0, gix-traverse v0.31.0, gix-worktree-stream v0.3.0, gix-archive v0.3.0, gix-config-value v0.13.0, gix-tempfile v8.0.0, gix-lock v8.0.0, gix-ref v0.35.0, gix-sec v0.9.0, gix-config v0.28.0, gix-prompt v0.6.0, gix-url v0.22.0, gix-credentials v0.18.0, gix-diff v0.34.0, gix-discover v0.23.0, gix-ignore v0.6.0, gix-bitmap v0.2.7, gix-index v0.22.0, gix-mailmap v0.17.0, gix-negotiate v0.6.0, gix-pack v0.41.0, gix-odb v0.51.0, gix-pathspec v0.1.0, gix-packetline v0.16.5, gix-transport v0.35.0, gix-protocol v0.38.0, gix-revision v0.20.0, gix-refspec v0.16.0, gix-submodule v0.2.0, gix-worktree v0.24.0, gix-worktree-state v0.1.0, gix v0.52.0, gitoxide-core v0.31.0, gitoxide v0.29.0, safety bump 41 crates ([`30b2761`](https://github.com/Byron/gitoxide/commit/30b27615047692d3ced1b2d9c2ac15a80f79fbee)) + - Update changelogs prior to release ([`f23ea88`](https://github.com/Byron/gitoxide/commit/f23ea8828f2d9ba7559973daca388c9591bcc5fc)) + - Merge branch 'gix-submodule' ([`8f3f358`](https://github.com/Byron/gitoxide/commit/8f3f358800f1fe77d7ba7ebd396a90b692d3c0c1)) + - `Modules::is_active()` now counts everything that doesn't match `submodule.active` (if present) as inactive. ([`e0d9b09`](https://github.com/Byron/gitoxide/commit/e0d9b09d02f88536b93ab6a31fddf9483881c5c1)) + - Just fmt ([`0d258f4`](https://github.com/Byron/gitoxide/commit/0d258f40afcd848509e2b0c7c264e9f346ed1726)) + - Merge branch 'submodule-in-gix' ([`36f7b78`](https://github.com/Byron/gitoxide/commit/36f7b783c67b8a087076a130f5ee9b90b23bc3cc)) + - Remove `File::names_and_active_state()` in favor of `File::is_active_platform()`. ([`3503f49`](https://github.com/Byron/gitoxide/commit/3503f4948b42854256c9e8d8336ebe222fee980b)) + - Make API less error prone by enforcing overrides at instantiation time. ([`4a443e4`](https://github.com/Byron/gitoxide/commit/4a443e453285095daccdca0fed9e8486ce7892ab)) + - Assure `gix-submodule` works with Rust 1.65. ([`8172f0e`](https://github.com/Byron/gitoxide/commit/8172f0e0f19e84fdaedceb87399f3fab4a1eb563)) + - Don't call crate 'WIP' in manifest anymore. ([`229bd48`](https://github.com/Byron/gitoxide/commit/229bd4899213f749a7cc124aa2b82a1368fba40f)) + - Merge branch 'submodule-active' ([`a3afaa4`](https://github.com/Byron/gitoxide/commit/a3afaa42741616a0f1abeef9b54557e7c2b800cb)) + - TBD a way to learn if submodules are active efficiently ([`af1cab3`](https://github.com/Byron/gitoxide/commit/af1cab31fd5ead445c988cce058c136c81229ad1)) +</details> + +## 0.1.0 (2023-08-07) + +<csr-id-f7f136dbe4f86e7dee1d54835c420ec07c96cd78/> +<csr-id-533e887e80c5f7ede8392884562e1c5ba56fb9a8/> +<csr-id-3d8fa8fef9800b1576beab8a5bc39b821157a5ed/> + +The initial release. + +### Commit Statistics + +<csr-read-only-do-not-edit/> + + - 27 commits contributed to the release over the course of 518 calendar days. + - 3 commits were understood as [conventional](https://www.conventionalcommits.org). + - 2 unique issues were worked on: [#301](https://github.com/Byron/gitoxide/issues/301), [#691](https://github.com/Byron/gitoxide/issues/691) + +### Commit Details + +<csr-read-only-do-not-edit/> + +<details><summary>view details</summary> + + * **[#301](https://github.com/Byron/gitoxide/issues/301)** + - Prepare changelog ([`010ab15`](https://github.com/Byron/gitoxide/commit/010ab1542ec447bb2b825335dab322c5bb21a1aa)) + - Add stub for git-submodule ([`3f9bcd8`](https://github.com/Byron/gitoxide/commit/3f9bcd8a0608dbdc5673da055c65d9dc995f03f1)) + * **[#691](https://github.com/Byron/gitoxide/issues/691)** + - Set `rust-version` to 1.64 ([`55066ce`](https://github.com/Byron/gitoxide/commit/55066ce5fd71209abb5d84da2998b903504584bb)) + * **Uncategorized** + - Release gix-glob v0.10.2, gix-date v0.7.2, gix-validate v0.8.0, gix-object v0.34.0, gix-ref v0.34.0, gix-config v0.27.0, gix-commitgraph v0.18.2, gix-revwalk v0.5.0, gix-revision v0.19.0, gix-refspec v0.15.0, gix-submodule v0.1.0, safety bump 18 crates ([`4604f83`](https://github.com/Byron/gitoxide/commit/4604f83ef238dc07c85aaeae097399b67f3cfd0c)) + - Finailize `gix-submodule` changelog ([`cbe8e62`](https://github.com/Byron/gitoxide/commit/cbe8e622b306d072fa8e7f5bf25dc596810a48d2)) + - Set `gix-submodule` to version 0.1.0 ([`931fd1e`](https://github.com/Byron/gitoxide/commit/931fd1ec4416aa4869f097b1a3a2e82744da4c21)) + - Prepare changelogs prior to release of `gix-submodule` ([`f3c4311`](https://github.com/Byron/gitoxide/commit/f3c43110e8d5f16cf87e50821044d8b3edbae235)) + - Merge branch 'submodules' ([`b629f8a`](https://github.com/Byron/gitoxide/commit/b629f8a774931d58c0a9b124fa75f85807c6c5d1)) + - `.gitmodule` file abstraction ([`6a2e6a4`](https://github.com/Byron/gitoxide/commit/6a2e6a436f76c8bbf2487f9967413a51356667a0)) + - Update license field following SPDX 2.1 license expression standard ([`9064ea3`](https://github.com/Byron/gitoxide/commit/9064ea31fae4dc59a56bdd3a06c0ddc990ee689e)) + - Merge branch 'corpus' ([`aa16c8c`](https://github.com/Byron/gitoxide/commit/aa16c8ce91452a3e3063cf1cf0240b6014c4743f)) + - Change MSRV to 1.65 ([`4f635fc`](https://github.com/Byron/gitoxide/commit/4f635fc4429350bae2582d25de86429969d28f30)) + - Merge branch 'main' into auto-clippy ([`3ef5c90`](https://github.com/Byron/gitoxide/commit/3ef5c90aebce23385815f1df674c1d28d58b4b0d)) + - Merge branch 'blinxen/main' ([`9375cd7`](https://github.com/Byron/gitoxide/commit/9375cd75b01aa22a0e2eed6305fe45fabfd6c1ac)) + - Include license files in all crates ([`facaaf6`](https://github.com/Byron/gitoxide/commit/facaaf633f01c857dcf2572c6dbe0a92b7105c1c)) + - Merge branch 'rename-crates' into inform-about-gix-rename ([`c9275b9`](https://github.com/Byron/gitoxide/commit/c9275b99ea43949306d93775d9d78c98fb86cfb1)) + - Adjust to renaming of `git-submodule` to `gix-submodule` ([`2c4a2d0`](https://github.com/Byron/gitoxide/commit/2c4a2d0113d5e60c50d2d72a1ff1cdf3e8ae77af)) + - Rename `git-submodule` to `gix-submodule` ([`d9a84a2`](https://github.com/Byron/gitoxide/commit/d9a84a2a4f5ca9b62857379135ac6be742363156)) + - Merge branch 'main' into http-config ([`bcd9654`](https://github.com/Byron/gitoxide/commit/bcd9654e56169799eb706646da6ee1f4ef2021a9)) + - Merge branch 'version2021' ([`0e4462d`](https://github.com/Byron/gitoxide/commit/0e4462df7a5166fe85c23a779462cdca8ee013e8)) + - Upgrade edition to 2021 in most crates. ([`3d8fa8f`](https://github.com/Byron/gitoxide/commit/3d8fa8fef9800b1576beab8a5bc39b821157a5ed)) + - Merge branch 'main' into index-from-tree ([`bc64b96`](https://github.com/Byron/gitoxide/commit/bc64b96a2ec781c72d1d4daad38aa7fb8b74f99b)) + - Merge branch 'main' into remote-ls-refs ([`e2ee3de`](https://github.com/Byron/gitoxide/commit/e2ee3ded97e5c449933712883535b30d151c7c78)) + - Merge branch 'docsrs-show-features' ([`31c2351`](https://github.com/Byron/gitoxide/commit/31c235140cad212d16a56195763fbddd971d87ce)) + - Uniformize deny attributes ([`f7f136d`](https://github.com/Byron/gitoxide/commit/f7f136dbe4f86e7dee1d54835c420ec07c96cd78)) + - Remove default link to cargo doc everywhere ([`533e887`](https://github.com/Byron/gitoxide/commit/533e887e80c5f7ede8392884562e1c5ba56fb9a8)) + - Release git-submodule v0.0.0 ([`d16821a`](https://github.com/Byron/gitoxide/commit/d16821a20d8446004d4a4e0f52fd50ba68e95eb1)) +</details> + diff --git a/vendor/gix-submodule/Cargo.toml b/vendor/gix-submodule/Cargo.toml new file mode 100644 index 000000000..51c44c86a --- /dev/null +++ b/vendor/gix-submodule/Cargo.toml @@ -0,0 +1,47 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +rust-version = "1.65" +name = "gix-submodule" +version = "0.4.0" +authors = ["Sebastian Thiel <sebastian.thiel@icloud.com>"] +description = "A crate of the gitoxide project dealing git submodules" +license = "MIT OR Apache-2.0" +repository = "https://github.com/Byron/gitoxide" + +[lib] +doctest = false + +[dependencies.bstr] +version = "1.5.0" +default-features = false + +[dependencies.gix-config] +version = "^0.30.0" + +[dependencies.gix-path] +version = "^0.10.0" + +[dependencies.gix-pathspec] +version = "^0.3.0" + +[dependencies.gix-refspec] +version = "^0.18.0" + +[dependencies.gix-url] +version = "^0.24.0" + +[dependencies.thiserror] +version = "1.0.44" + +[dev-dependencies] diff --git a/vendor/gix-submodule/LICENSE-APACHE b/vendor/gix-submodule/LICENSE-APACHE new file mode 100644 index 000000000..a51f59a06 --- /dev/null +++ b/vendor/gix-submodule/LICENSE-APACHE @@ -0,0 +1,191 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2018-2021 Sebastian Thiel, and [contributors](https://github.com/byron/gitoxide/contributors) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/gix-submodule/LICENSE-MIT b/vendor/gix-submodule/LICENSE-MIT new file mode 100644 index 000000000..b58e818f1 --- /dev/null +++ b/vendor/gix-submodule/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018-2021 Sebastian Thiel, and [contributors](https://github.com/byron/gitoxide/contributors). + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/gix-submodule/src/access.rs b/vendor/gix-submodule/src/access.rs new file mode 100644 index 000000000..4def2f42f --- /dev/null +++ b/vendor/gix-submodule/src/access.rs @@ -0,0 +1,248 @@ +use std::{borrow::Cow, collections::HashSet, path::Path}; + +use bstr::BStr; + +use crate::{ + config, + config::{Branch, FetchRecurse, Ignore, Update}, + File, IsActivePlatform, +}; + +/// High-Level Access +/// +/// Note that all methods perform validation of the requested value and report issues right away. +/// If a bypass is needed, use [`config()`](File::config()) for direct access. +impl File { + /// Return the underlying configuration file. + /// + /// Note that it might have been merged with values from another configuration file and may + /// thus not be accurately reflecting that state of a `.gitmodules` file anymore. + pub fn config(&self) -> &gix_config::File<'static> { + &self.config + } + + /// Return the path at which the `.gitmodules` file lives, if it is known. + pub fn config_path(&self) -> Option<&Path> { + self.config.sections().filter_map(|s| s.meta().path.as_deref()).next() + } + + /// Return the unvalidated names of the submodules for which configuration is present. + /// + /// Note that these exact names have to be used for querying submodule values. + pub fn names(&self) -> impl Iterator<Item = &BStr> { + let mut seen = HashSet::<&BStr>::default(); + self.config + .sections_by_name("submodule") + .into_iter() + .flatten() + .filter_map(move |s| { + s.header() + .subsection_name() + .filter(|_| s.meta().source == crate::init::META_MARKER) + .filter(|name| seen.insert(*name)) + }) + } + + /// Similar to [Self::is_active_platform()], but automatically applies it to each name to learn if a submodule is active or not. + pub fn names_and_active_state<'a>( + &'a self, + config: &'a gix_config::File<'static>, + defaults: gix_pathspec::Defaults, + attributes: &'a mut (dyn FnMut( + &BStr, + gix_pathspec::attributes::glob::pattern::Case, + bool, + &mut gix_pathspec::attributes::search::Outcome, + ) -> bool + + 'a), + ) -> Result< + impl Iterator<Item = (&BStr, Result<bool, gix_config::value::Error>)> + 'a, + crate::is_active_platform::Error, + > { + let mut platform = self.is_active_platform(config, defaults)?; + let iter = self + .names() + .map(move |name| (name, platform.is_active(config, name, attributes))); + Ok(iter) + } + + /// Return a platform which allows to check if a submodule name is active or inactive. + /// Use `defaults` for parsing the pathspecs used to later match on names via `submodule.active` configuration retrieved from `config`. + /// + /// All `submodule.active` pathspecs are considered to be top-level specs and match the name of submodules, which are active + /// on inclusive match. + /// The full algorithm is described as [hierarchy of rules](https://git-scm.com/docs/gitsubmodules#_active_submodules). + pub fn is_active_platform( + &self, + config: &gix_config::File<'_>, + defaults: gix_pathspec::Defaults, + ) -> Result<IsActivePlatform, crate::is_active_platform::Error> { + let search = config + .strings_by_key("submodule.active") + .map(|patterns| -> Result<_, crate::is_active_platform::Error> { + let patterns = patterns + .into_iter() + .map(|pattern| gix_pathspec::parse(&pattern, defaults)) + .collect::<Result<Vec<_>, _>>()?; + Ok(gix_pathspec::Search::from_specs( + patterns, + None, + std::path::Path::new(""), + )?) + }) + .transpose()?; + Ok(IsActivePlatform { search }) + } + + /// Given the `relative_path` (as seen from the root of the worktree) of a submodule with possibly platform-specific + /// component separators, find the submodule's name associated with this path, or `None` if none was found. + /// + /// Note that this does a linear search and compares `relative_path` in a normalized form to the same form of the path + /// associated with the submodule. + pub fn name_by_path(&self, relative_path: &BStr) -> Option<&BStr> { + self.names() + .filter_map(|n| self.path(n).ok().map(|p| (n, p))) + .find_map(|(n, p)| (p == relative_path).then_some(n)) + } +} + +/// Per-Submodule Access +impl File { + /// Return the path relative to the root directory of the working tree at which the submodule is expected to be checked out. + /// It's an error if the path doesn't exist as it's the only way to associate a path in the index with additional submodule + /// information, like the URL to fetch from. + /// + /// ### Deviation + /// + /// Git currently allows absolute paths to be used when adding submodules, but fails later as it can't find the submodule by + /// relative path anymore. Let's play it safe here. + pub fn path(&self, name: &BStr) -> Result<Cow<'_, BStr>, config::path::Error> { + let path_bstr = + self.config + .string("submodule", Some(name), "path") + .ok_or_else(|| config::path::Error::Missing { + submodule: name.to_owned(), + })?; + if path_bstr.is_empty() { + return Err(config::path::Error::Missing { + submodule: name.to_owned(), + }); + } + let path = gix_path::from_bstr(path_bstr.as_ref()); + if path.is_absolute() { + return Err(config::path::Error::Absolute { + submodule: name.to_owned(), + actual: path_bstr.into_owned(), + }); + } + if gix_path::normalize(path, "".as_ref()).is_none() { + return Err(config::path::Error::OutsideOfWorktree { + submodule: name.to_owned(), + actual: path_bstr.into_owned(), + }); + } + Ok(path_bstr) + } + + /// Retrieve the `url` field of the submodule named `name`. It's an error if it doesn't exist or is empty. + pub fn url(&self, name: &BStr) -> Result<gix_url::Url, config::url::Error> { + let url = self + .config + .string("submodule", Some(name), "url") + .ok_or_else(|| config::url::Error::Missing { + submodule: name.to_owned(), + })?; + + if url.is_empty() { + return Err(config::url::Error::Missing { + submodule: name.to_owned(), + }); + } + gix_url::Url::from_bytes(url.as_ref()).map_err(|err| config::url::Error::Parse { + submodule: name.to_owned(), + source: err, + }) + } + + /// Retrieve the `update` field of the submodule named `name`, if present. + pub fn update(&self, name: &BStr) -> Result<Option<Update>, config::update::Error> { + let value: Update = match self.config.string("submodule", Some(name), "update") { + Some(v) => v.as_ref().try_into().map_err(|()| config::update::Error::Invalid { + submodule: name.to_owned(), + actual: v.into_owned(), + })?, + None => return Ok(None), + }; + + if let Update::Command(cmd) = &value { + let ours = self.config.meta(); + let has_value_from_foreign_section = self + .config + .sections_by_name("submodule") + .into_iter() + .flatten() + .any(|s| (s.header().subsection_name() == Some(name) && s.meta() as *const _ != ours as *const _)); + if !has_value_from_foreign_section { + return Err(config::update::Error::CommandForbiddenInModulesConfiguration { + submodule: name.to_owned(), + actual: cmd.to_owned(), + }); + } + } + Ok(Some(value)) + } + + /// Retrieve the `branch` field of the submodule named `name`, or `None` if unset. + /// + /// Note that `Default` is implemented for [`Branch`]. + pub fn branch(&self, name: &BStr) -> Result<Option<Branch>, config::branch::Error> { + let branch = match self.config.string("submodule", Some(name), "branch") { + Some(v) => v, + None => return Ok(None), + }; + + Branch::try_from(branch.as_ref()) + .map(Some) + .map_err(|err| config::branch::Error { + submodule: name.to_owned(), + actual: branch.into_owned(), + source: err, + }) + } + + /// Retrieve the `fetchRecurseSubmodules` field of the submodule named `name`, or `None` if unset. + /// + /// Note that if it's unset, it should be retrieved from `fetch.recurseSubmodules` in the configuration. + pub fn fetch_recurse(&self, name: &BStr) -> Result<Option<FetchRecurse>, config::Error> { + self.config + .boolean("submodule", Some(name), "fetchRecurseSubmodules") + .map(FetchRecurse::new) + .transpose() + .map_err(|value| config::Error { + field: "fetchRecurseSubmodules", + submodule: name.to_owned(), + actual: value, + }) + } + + /// Retrieve the `ignore` field of the submodule named `name`, or `None` if unset. + pub fn ignore(&self, name: &BStr) -> Result<Option<Ignore>, config::Error> { + self.config + .string("submodule", Some(name), "ignore") + .map(|value| { + Ignore::try_from(value.as_ref()).map_err(|()| config::Error { + field: "ignore", + submodule: name.to_owned(), + actual: value.into_owned(), + }) + }) + .transpose() + } + + /// Retrieve the `shallow` field of the submodule named `name`, or `None` if unset. + /// + /// If `true`, the submodule will be checked out with `depth = 1`. If unset, `false` is assumed. + pub fn shallow(&self, name: &BStr) -> Result<Option<bool>, gix_config::value::Error> { + self.config.boolean("submodule", Some(name), "shallow").transpose() + } +} diff --git a/vendor/gix-submodule/src/config.rs b/vendor/gix-submodule/src/config.rs new file mode 100644 index 000000000..202696691 --- /dev/null +++ b/vendor/gix-submodule/src/config.rs @@ -0,0 +1,216 @@ +use bstr::{BStr, BString, ByteSlice}; + +/// Determine how the submodule participates in `git status` queries. This setting also affects `git diff`. +#[derive(Default, Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)] +pub enum Ignore { + /// Submodule changes won't be considered at all, which is the fastest option. + /// + /// Note that changes to the submodule hash in the superproject will still be observable. + All, + /// Ignore any changes to the submodule working tree, only show committed differences between the `HEAD` of the submodule + /// compared to the recorded commit in the superproject. + Dirty, + /// Only ignore untracked files in the submodule, but show modifications to the submodule working tree as well as differences + /// between the recorded commit in the superproject and the checked-out commit in the submodule. + Untracked, + /// No modifications to the submodule are ignored, which shows untracked files, modified files in the submodule worktree as well as + /// differences between the recorded commit in the superproject and the checked-out commit in the submodule. + #[default] + None, +} + +impl TryFrom<&BStr> for Ignore { + type Error = (); + + fn try_from(value: &BStr) -> Result<Self, Self::Error> { + Ok(match value.as_bytes() { + b"all" => Ignore::All, + b"dirty" => Ignore::Dirty, + b"untracked" => Ignore::Untracked, + b"none" => Ignore::None, + _ => return Err(()), + }) + } +} + +/// Determine how to recurse into this module from the superproject when fetching. +/// +/// Generally, a fetch is only performed if the submodule commit referenced by the superproject isn't already +/// present in the submodule repository. +/// +/// Note that when unspecified, the `fetch.recurseSubmodules` configuration variable should be used instead. +#[derive(Default, Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash)] +pub enum FetchRecurse { + /// Fetch only changed submodules. + #[default] + OnDemand, + /// Fetch all populated submodules, changed or not. + /// + /// This skips the work needed to determine whether a submodule has changed in the first place, but may work + /// more as some fetches might not be necessary. + Always, + /// Submodules are never fetched. + Never, +} + +impl FetchRecurse { + /// Check if `boolean` is set and translate it the respective variant, or check the underlying string + /// value for non-boolean options. + /// On error, it returns the obtained string value which would be the invalid value. + pub fn new(boolean: Result<bool, gix_config::value::Error>) -> Result<Self, BString> { + Ok(match boolean { + Ok(value) => { + if value { + FetchRecurse::Always + } else { + FetchRecurse::Never + } + } + Err(err) => { + if err.input != "on-demand" { + return Err(err.input); + } + FetchRecurse::OnDemand + } + }) + } +} + +/// Describes the branch that should be tracked on the remote. +#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] +pub enum Branch { + /// The name of the remote branch should be the same as the one currently checked out in the superproject. + CurrentInSuperproject, + /// The validated remote-only branch that could be used for fetching. + Name(BString), +} + +impl Default for Branch { + fn default() -> Self { + Branch::Name("HEAD".into()) + } +} + +impl TryFrom<&BStr> for Branch { + type Error = gix_refspec::parse::Error; + + fn try_from(value: &BStr) -> Result<Self, Self::Error> { + if value == "." { + return Ok(Branch::CurrentInSuperproject); + } + + gix_refspec::parse(value, gix_refspec::parse::Operation::Fetch) + .map(|spec| Branch::Name(spec.source().expect("no object").to_owned())) + } +} + +/// Determine how `git submodule update` should deal with this submodule to bring it up-to-date with the +/// super-project's expectations. +#[derive(Default, Debug, Clone, Hash, PartialOrd, PartialEq, Ord, Eq)] +pub enum Update { + /// The commit recorded in the superproject should be checked out on a detached `HEAD`. + #[default] + Checkout, + /// The current branch in the submodule will be rebased onto the commit recorded in the superproject. + Rebase, + /// The commit recorded in the superproject will merged into the current branch of the submodule. + Merge, + /// A custom command to be called like `<command> hash-of-submodule-commit` that is to be executed to + /// perform the submodule update. + /// + /// Note that this variant is only allowed if the value is coming from an override. Thus it's not allowed to distribute + /// arbitrary commands via `.gitmodules` for security reasons. + Command(BString), + /// The submodule update is not performed at all. + None, +} + +impl TryFrom<&BStr> for Update { + type Error = (); + + fn try_from(value: &BStr) -> Result<Self, Self::Error> { + Ok(match value.as_bstr().as_bytes() { + b"checkout" => Update::Checkout, + b"rebase" => Update::Rebase, + b"merge" => Update::Merge, + b"none" => Update::None, + command if command.first() == Some(&b'!') => Update::Command(command[1..].to_owned().into()), + _ => return Err(()), + }) + } +} + +/// The error returned by [File::fetch_recurse()](crate::File::fetch_recurse) and [File::ignore()](crate::File::ignore). +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +#[error("The '{field}' field of submodule '{submodule}' was invalid: '{actual}'")] +pub struct Error { + pub field: &'static str, + pub submodule: BString, + pub actual: BString, +} + +/// +pub mod branch { + use bstr::BString; + + /// The error returned by [File::branch()](crate::File::branch). + #[derive(Debug, thiserror::Error)] + #[allow(missing_docs)] + #[error("The value '{actual}' of the 'branch' field of submodule '{submodule}' couldn't be turned into a valid fetch refspec")] + pub struct Error { + pub submodule: BString, + pub actual: BString, + pub source: gix_refspec::parse::Error, + } +} + +/// +pub mod update { + use bstr::BString; + + /// The error returned by [File::update()](crate::File::update). + #[derive(Debug, thiserror::Error)] + #[allow(missing_docs)] + pub enum Error { + #[error("The 'update' field of submodule '{submodule}' tried to set command '{actual}' to be shared")] + CommandForbiddenInModulesConfiguration { submodule: BString, actual: BString }, + #[error("The 'update' field of submodule '{submodule}' was invalid: '{actual}'")] + Invalid { submodule: BString, actual: BString }, + } +} + +/// +pub mod url { + use bstr::BString; + + /// The error returned by [File::url()](crate::File::url). + #[derive(Debug, thiserror::Error)] + #[allow(missing_docs)] + pub enum Error { + #[error("The url of submodule '{submodule}' could not be parsed")] + Parse { + submodule: BString, + source: gix_url::parse::Error, + }, + #[error("The submodule '{submodule}' was missing its 'url' field or it was empty")] + Missing { submodule: BString }, + } +} + +/// +pub mod path { + use bstr::BString; + + /// The error returned by [File::path()](crate::File::path). + #[derive(Debug, thiserror::Error)] + #[allow(missing_docs)] + pub enum Error { + #[error("The path '{actual}' of submodule '{submodule}' needs to be relative")] + Absolute { actual: BString, submodule: BString }, + #[error("The submodule '{submodule}' was missing its 'path' field or it was empty")] + Missing { submodule: BString }, + #[error("The path '{actual}' would lead outside of the repository worktree")] + OutsideOfWorktree { actual: BString, submodule: BString }, + } +} diff --git a/vendor/gix-submodule/src/is_active_platform.rs b/vendor/gix-submodule/src/is_active_platform.rs new file mode 100644 index 000000000..01d72f510 --- /dev/null +++ b/vendor/gix-submodule/src/is_active_platform.rs @@ -0,0 +1,49 @@ +use bstr::BStr; + +use crate::IsActivePlatform; + +/// The error returned by [File::names_and_active_state](crate::File::names_and_active_state()). +#[derive(Debug, thiserror::Error)] +#[allow(missing_docs)] +pub enum Error { + #[error(transparent)] + NormalizePattern(#[from] gix_pathspec::normalize::Error), + #[error(transparent)] + ParsePattern(#[from] gix_pathspec::parse::Error), +} + +impl IsActivePlatform { + /// Returns `true` if the submodule named `name` is active or `false` otherwise. + /// `config` is the configuration that was passed to the originating [modules file](crate::File). + /// `attributes(relative_path, case, is_dir, outcome)` provides a way to resolve the attributes mentioned + /// in `submodule.active` pathspecs that are evaluated in the platforms git configuration. + /// + /// A submodule's active state is determined in the following order + /// + /// * it's `submodule.<name>.active` is set in `config` + /// * it matches a `submodule.active` pathspec either positively or negatively via `:!<spec>` + /// * it's active if it has any `url` set in `config` + pub fn is_active( + &mut self, + config: &gix_config::File<'static>, + name: &BStr, + attributes: &mut dyn FnMut( + &BStr, + gix_pathspec::attributes::glob::pattern::Case, + bool, + &mut gix_pathspec::attributes::search::Outcome, + ) -> bool, + ) -> Result<bool, gix_config::value::Error> { + if let Some(val) = config.boolean("submodule", Some(name), "active").transpose()? { + return Ok(val); + }; + if let Some(val) = self.search.as_mut().map(|search| { + search + .pattern_matching_relative_path(name, Some(true), attributes) + .map_or(false, |m| !m.is_excluded()) + }) { + return Ok(val); + } + Ok(config.string("submodule", Some(name), "url").is_some()) + } +} diff --git a/vendor/gix-submodule/src/lib.rs b/vendor/gix-submodule/src/lib.rs new file mode 100644 index 000000000..639af30fa --- /dev/null +++ b/vendor/gix-submodule/src/lib.rs @@ -0,0 +1,144 @@ +//! Primitives for describing git submodules. +#![deny(rust_2018_idioms, missing_docs)] +#![forbid(unsafe_code)] + +use std::{borrow::Cow, collections::BTreeMap}; + +use bstr::BStr; + +/// All relevant information about a git module, typically from `.gitmodules` files. +/// +/// Note that overrides from other configuration might be relevant, which is why this type +/// can be used to take these into consideration when presented with other configuration +/// from the superproject. +#[derive(Clone)] +pub struct File { + config: gix_config::File<'static>, +} + +mod access; + +/// +pub mod config; + +/// +pub mod is_active_platform; + +/// A platform to keep the state necessary to perform repeated active checks, created by [File::is_active_platform()]. +pub struct IsActivePlatform { + pub(crate) search: Option<gix_pathspec::Search>, +} + +/// Mutation +impl File { + /// This can be used to let `config` override some values we know about submodules, namely… + /// + /// * `url` + /// * `fetchRecurseSubmodules` + /// * `ignore` + /// * `update` + /// * `branch` + /// + /// These values aren't validated yet, which will happen upon query. + pub fn append_submodule_overrides(&mut self, config: &gix_config::File<'_>) -> &mut Self { + let mut values = BTreeMap::<_, Vec<_>>::new(); + for (module_name, section) in config + .sections_by_name("submodule") + .into_iter() + .flatten() + .filter_map(|s| s.header().subsection_name().map(|n| (n, s))) + { + for field in ["url", "fetchRecurseSubmodules", "ignore", "update", "branch"] { + if let Some(value) = section.value(field) { + values.entry((module_name, field)).or_default().push(value); + } + } + } + + let values = { + let mut v: Vec<_> = values.into_iter().collect(); + v.sort_by_key(|a| a.0 .0); + v + }; + + let mut config_to_append = gix_config::File::new(config.meta_owned()); + let mut prev_name = None; + for ((module_name, field), values) in values { + if prev_name.map_or(true, |pn: &BStr| pn != module_name) { + config_to_append + .new_section("submodule", Some(Cow::Owned(module_name.to_owned()))) + .expect("all names come from valid configuration, so remain valid"); + prev_name = Some(module_name); + } + config_to_append + .section_mut("submodule", Some(module_name)) + .expect("always set at this point") + .push( + field.try_into().expect("statically known key"), + Some(values.last().expect("at least one value or we wouldn't be here")), + ); + } + + self.config.append(config_to_append); + self + } +} + +/// +mod init { + use std::path::PathBuf; + + use crate::File; + + impl std::fmt::Debug for File { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("File") + .field("config_path", &self.config_path()) + .field("config", &format_args!("r#\"{}\"#", self.config)) + .finish() + } + } + + /// A marker we use when listing names to not pick them up from overridden sections. + pub(crate) const META_MARKER: gix_config::Source = gix_config::Source::Api; + + /// Lifecycle + impl File { + /// Parse `bytes` as git configuration, typically from `.gitmodules`, without doing any further validation. + /// `path` can be provided to keep track of where the file was read from in the underlying [`config`](Self::config()) + /// instance. + /// `config` is used to [apply value overrides](File::append_submodule_overrides), which can be empty if overrides + /// should be applied at a later time. + /// + /// Future access to the module information is lazy and configuration errors are exposed there on a per-value basis. + /// + /// ### Security Considerations + /// + /// The information itself should be used with care as it can direct the caller to fetch from remotes. It is, however, + /// on the caller to assure the input data can be trusted. + pub fn from_bytes( + bytes: &[u8], + path: impl Into<Option<PathBuf>>, + config: &gix_config::File<'_>, + ) -> Result<Self, gix_config::parse::Error> { + let metadata = { + let mut meta = gix_config::file::Metadata::from(META_MARKER); + meta.path = path.into(); + meta + }; + let modules = gix_config::File::from_parse_events_no_includes( + gix_config::parse::Events::from_bytes_owned(bytes, None)?, + metadata, + ); + + let mut res = Self { config: modules }; + res.append_submodule_overrides(config); + Ok(res) + } + + /// Turn ourselves into the underlying parsed configuration file. + pub fn into_config(self) -> gix_config::File<'static> { + self.config + } + } +} diff --git a/vendor/gix-submodule/tests/file/baseline.rs b/vendor/gix-submodule/tests/file/baseline.rs new file mode 100644 index 000000000..dc71ed3ab --- /dev/null +++ b/vendor/gix-submodule/tests/file/baseline.rs @@ -0,0 +1,80 @@ +use std::{ffi::OsStr, path::PathBuf}; + +use bstr::ByteSlice; +use gix_features::fs::walkdir::Parallelism; + +#[test] +fn common_values_and_names_by_path() -> crate::Result { + let modules = module_files() + .map(|(path, stripped)| { + gix_submodule::File::from_bytes(&std::fs::read(path).unwrap(), stripped, &Default::default()) + }) + .collect::<Result<Vec<_>, _>>()?; + + assert_eq!( + modules + .iter() + .map(|m| { m.config_path().expect("present").to_owned() }) + .collect::<Vec<_>>(), + [ + "empty-clone/.gitmodules", + "multiple/.gitmodules", + "not-a-submodule/.gitmodules", + "recursive-clone/.gitmodules", + "recursive-clone/submodule/.gitmodules", + "relative-clone/.gitmodules", + "relative-clone/submodule/.gitmodules", + "super/.gitmodules", + "super/submodule/.gitmodules", + "super-clone/.gitmodules", + "super-clone/submodule/.gitmodules", + "top-only-clone/.gitmodules" + ] + .into_iter() + .map(PathBuf::from) + .collect::<Vec<_>>(), + "config_path() yields the path provided when instantiating (for .gitmodules), and not the path of a submodule." + ); + + assert_eq!( + { + let mut v = modules.iter().flat_map(gix_submodule::File::names).collect::<Vec<_>>(); + v.sort(); + v.dedup(); + v + }, + [".a/..c", "a/b", "a/d\\", "a\\e", "submodule"] + .into_iter() + .map(|n| n.as_bytes().as_bstr()) + .collect::<Vec<_>>(), + "names can be iterated" + ); + + for module in &modules { + for name in module.names() { + let path = module.path(name)?; + assert_eq!(module.name_by_path(path.as_ref()).expect("found"), name); + } + } + Ok(()) +} + +fn module_files() -> impl Iterator<Item = (PathBuf, PathBuf)> { + let dir = gix_testtools::scripted_fixture_read_only("basic.sh").expect("valid fixture"); + gix_features::fs::walkdir_sorted_new(&dir, Parallelism::Serial) + .follow_links(false) + .into_iter() + .filter_map(move |entry| { + let entry = entry.unwrap(); + (entry.file_name() == OsStr::new(".gitmodules")).then(|| { + ( + entry.path().to_owned(), + entry + .path() + .strip_prefix(&dir) + .expect("can only provide sub-dirs") + .to_owned(), + ) + }) + }) +} diff --git a/vendor/gix-submodule/tests/file/mod.rs b/vendor/gix-submodule/tests/file/mod.rs new file mode 100644 index 000000000..cecb7b759 --- /dev/null +++ b/vendor/gix-submodule/tests/file/mod.rs @@ -0,0 +1,453 @@ +fn submodule(bytes: &str) -> gix_submodule::File { + gix_submodule::File::from_bytes(bytes.as_bytes(), None, &Default::default()).expect("valid module") +} + +mod is_active_platform { + use std::str::FromStr; + + fn module_file(name: &str) -> crate::Result<gix_submodule::File> { + let modules = gix_testtools::scripted_fixture_read_only("basic.sh")? + .join(name) + .join(".gitmodules"); + Ok(gix_submodule::File::from_bytes( + std::fs::read(&modules)?.as_slice(), + modules, + &Default::default(), + )?) + } + + use bstr::{BStr, ByteSlice}; + + fn multi_modules() -> crate::Result<gix_submodule::File> { + module_file("multiple") + } + + fn assume_valid_active_state<'a>( + module: &'a gix_submodule::File, + config: &'a gix_config::File<'static>, + defaults: gix_pathspec::Defaults, + ) -> crate::Result<Vec<(&'a str, bool)>> { + assume_valid_active_state_with_attrs(module, config, defaults, |_, _, _, _| { + unreachable!("shouldn't be called") + }) + } + + fn assume_valid_active_state_with_attrs<'a>( + module: &'a gix_submodule::File, + config: &'a gix_config::File<'static>, + defaults: gix_pathspec::Defaults, + mut attributes: impl FnMut( + &BStr, + gix_pathspec::attributes::glob::pattern::Case, + bool, + &mut gix_pathspec::attributes::search::Outcome, + ) -> bool + + 'a, + ) -> crate::Result<Vec<(&'a str, bool)>> { + let mut platform = module.is_active_platform(config, defaults)?; + Ok(module + .names() + .map(|name| { + ( + name.to_str().expect("valid"), + platform.is_active(config, name, &mut attributes).expect("valid"), + ) + }) + .collect()) + } + + #[test] + fn without_submodule_in_index() -> crate::Result { + let module = module_file("not-a-submodule")?; + assert_eq!( + module.names().map(ToOwned::to_owned).collect::<Vec<_>>(), + ["submodule"], + "entries can be read" + ); + Ok(()) + } + + #[test] + fn without_any_additional_settings_all_are_inactive_if_they_have_a_url() -> crate::Result { + let module = multi_modules()?; + assert_eq!( + assume_valid_active_state(&module, &Default::default(), Default::default())?, + &[ + ("submodule", false), + ("a/b", false), + (".a/..c", false), + ("a/d\\", false), + ("a\\e", false) + ] + ); + Ok(()) + } + + #[test] + fn submodules_with_active_config_are_considered_active_or_inactive() -> crate::Result { + let module = multi_modules()?; + assert_eq!( + assume_valid_active_state( + &module, + &gix_config::File::from_str( + "[submodule.submodule]\n active = 0\n url = set \n[submodule \"a/b\"]\n active = false \n url = set \n[submodule \".a/..c\"] active = 1" + )?, + Default::default() + )?, + &[ + ("submodule", false), + ("a/b", false), + (".a/..c", true), + ("a/d\\", false), + ("a\\e", false) + ] + ); + Ok(()) + } + + #[test] + fn submodules_with_active_config_override_pathspecs() -> crate::Result { + let module = multi_modules()?; + assert_eq!( + assume_valid_active_state( + &module, + &gix_config::File::from_str( + "[submodule.submodule]\n active = 0\n[submodule]\n active = *\n[submodule]\n active = :!a*" + )?, + Default::default() + )?, + &[ + ("submodule", false), + ("a/b", false), + (".a/..c", true), + ("a/d\\", false), + ("a\\e", false) + ] + ); + Ok(()) + } + + #[test] + fn pathspecs_matter_even_if_they_do_not_match() -> crate::Result { + let module = multi_modules()?; + assert_eq!( + assume_valid_active_state( + &module, + &gix_config::File::from_str("[submodule]\n active = submodule ")?, + Default::default() + )?, + &[ + ("submodule", true), + ("a/b", false), + (".a/..c", false), + ("a/d\\", false), + ("a\\e", false) + ] + ); + assert_eq!( + assume_valid_active_state( + &module, + &gix_config::File::from_str("[submodule]\n active = :!submodule ")?, + Default::default() + )?, + &[ + ("submodule", false), + ("a/b", true), + (".a/..c", true), + ("a/d\\", true), + ("a\\e", true) + ] + ); + Ok(()) + } +} + +mod path { + use gix_submodule::config::path::Error; + + use crate::file::submodule; + + fn submodule_path(value: &str) -> Error { + let module = submodule(&format!("[submodule.a]\npath = {value}")); + module.path("a".into()).unwrap_err() + } + + #[test] + fn valid() -> crate::Result { + let module = submodule("[submodule.a]\n path = relative/path/submodule"); + assert_eq!(module.path("a".into())?.as_ref(), "relative/path/submodule"); + Ok(()) + } + + #[test] + fn validate_upon_retrieval() { + assert!(matches!( + submodule_path(if cfg!(windows) { + "c:\\\\hello" + } else { + "/definitely/absolute\\\\" + }), + Error::Absolute { .. } + )); + assert!(matches!(submodule_path(""), Error::Missing { .. })); + assert!(matches!(submodule_path("../attack"), Error::OutsideOfWorktree { .. })); + + { + let module = submodule("[submodule.a]\n path"); + assert!(matches!(module.path("a".into()).unwrap_err(), Error::Missing { .. })); + } + + { + let module = submodule("[submodule.a]\n"); + assert!(matches!(module.path("a".into()).unwrap_err(), Error::Missing { .. })); + } + } +} + +mod url { + use gix_submodule::config::url::Error; + + use crate::file::submodule; + + fn submodule_url(value: &str) -> Error { + let module = submodule(&format!("[submodule.a]\nurl = {value}")); + module.url("a".into()).unwrap_err() + } + + #[test] + fn valid() -> crate::Result { + let module = submodule("[submodule.a]\n url = path-to-repo"); + assert_eq!(module.url("a".into())?.to_bstring(), "path-to-repo"); + Ok(()) + } + + #[test] + fn validate_upon_retrieval() { + assert!(matches!(submodule_url(""), Error::Missing { .. })); + { + let module = submodule("[submodule.a]\n url"); + assert!(matches!(module.url("a".into()).unwrap_err(), Error::Missing { .. })); + } + + { + let module = submodule("[submodule.a]\n"); + assert!(matches!(module.url("a".into()).unwrap_err(), Error::Missing { .. })); + } + + assert!(matches!(submodule_url("file://"), Error::Parse { .. })); + } +} + +mod update { + use std::str::FromStr; + + use gix_submodule::config::{update::Error, Update}; + + use crate::file::submodule; + + fn submodule_update(value: &str) -> Error { + let module = submodule(&format!("[submodule.a]\nupdate = {value}")); + module.update("a".into()).unwrap_err() + } + + #[test] + fn default() { + assert_eq!(Update::default(), Update::Checkout, "as defined in the docs"); + } + + #[test] + fn valid() -> crate::Result { + for (valid, expected) in [ + ("checkout", Update::Checkout), + ("rebase", Update::Rebase), + ("merge", Update::Merge), + ("none", Update::None), + ] { + let module = submodule(&format!("[submodule.a]\n update = {valid}")); + assert_eq!(module.update("a".into())?.expect("present"), expected); + } + Ok(()) + } + + #[test] + fn valid_in_overrides() -> crate::Result { + let mut module = submodule("[submodule.a]\n update = merge"); + let repo_config = gix_config::File::from_str("[submodule.a]\n update = !dangerous")?; + let prev_names = module.names().map(ToOwned::to_owned).collect::<Vec<_>>(); + module.append_submodule_overrides(&repo_config); + + assert_eq!( + module.update("a".into())?.expect("present"), + Update::Command("dangerous".into()), + "overridden values are picked up and make commands possible - these are local" + ); + assert_eq!( + module.names().map(ToOwned::to_owned).collect::<Vec<_>>(), + prev_names, + "Appending more configuration sections doesn't affect name listing" + ); + Ok(()) + } + + #[test] + fn validate_upon_retrieval() { + assert!(matches!(submodule_update(""), Error::Invalid { .. })); + assert!(matches!(submodule_update("bogus"), Error::Invalid { .. })); + assert!( + matches!( + submodule_update("!dangerous"), + Error::CommandForbiddenInModulesConfiguration { .. } + ), + "forbidden unless it's an override" + ); + } +} + +mod fetch_recurse { + use gix_submodule::config::FetchRecurse; + + use crate::file::submodule; + + #[test] + fn default() { + assert_eq!( + FetchRecurse::default(), + FetchRecurse::OnDemand, + "as defined in git codebase actually" + ); + } + + #[test] + fn valid() -> crate::Result { + for (valid, expected) in [ + ("yes", FetchRecurse::Always), + ("true", FetchRecurse::Always), + ("", FetchRecurse::Never), + ("no", FetchRecurse::Never), + ("false", FetchRecurse::Never), + ("on-demand", FetchRecurse::OnDemand), + ] { + let module = submodule(&format!("[submodule.a]\n fetchRecurseSubmodules = {valid}")); + assert_eq!(module.fetch_recurse("a".into())?.expect("present"), expected); + } + let module = submodule("[submodule.a]\n fetchRecurseSubmodules"); + assert_eq!( + module.fetch_recurse("a".into())?.expect("present"), + FetchRecurse::Always, + "no value means true, which means to always recurse" + ); + Ok(()) + } + + #[test] + fn validate_upon_retrieval() -> crate::Result { + for invalid in ["foo", "ney", "On-demand"] { + let module = submodule(&format!("[submodule.a]\n fetchRecurseSubmodules = \"{invalid}\"")); + assert!(module.fetch_recurse("a".into()).is_err()); + } + Ok(()) + } +} + +mod ignore { + use gix_submodule::config::Ignore; + + use crate::file::submodule; + + #[test] + fn default() { + assert_eq!(Ignore::default(), Ignore::None, "as defined in the docs"); + } + + #[test] + fn valid() -> crate::Result { + for (valid, expected) in [ + ("all", Ignore::All), + ("dirty", Ignore::Dirty), + ("untracked", Ignore::Untracked), + ("none", Ignore::None), + ] { + let module = submodule(&format!("[submodule.a]\n ignore = {valid}")); + assert_eq!(module.ignore("a".into())?.expect("present"), expected); + } + let module = submodule("[submodule.a]\n ignore"); + assert!( + module.ignore("a".into())?.is_none(), + "no value is interpreted as non-existing string, hence the caller will see None" + ); + Ok(()) + } + + #[test] + fn validate_upon_retrieval() -> crate::Result { + for invalid in ["All", ""] { + let module = submodule(&format!("[submodule.a]\n ignore = \"{invalid}\"")); + assert!(module.ignore("a".into()).is_err()); + } + Ok(()) + } +} + +mod branch { + use gix_submodule::config::Branch; + + use crate::file::submodule; + + #[test] + fn valid() -> crate::Result { + for (valid, expected) in [ + (".", Branch::CurrentInSuperproject), + ("", Branch::Name("HEAD".into())), + ("master", Branch::Name("master".into())), + ("feature/a", Branch::Name("feature/a".into())), + ( + "abcde12345abcde12345abcde12345abcde12345", + Branch::Name("abcde12345abcde12345abcde12345abcde12345".into()), + ), + ] { + let module = submodule(&format!("[submodule.a]\n branch = {valid}")); + assert_eq!(module.branch("a".into())?.expect("present"), expected); + } + let module = submodule("[submodule.a]\n branch"); + assert!( + module.branch("a".into())?.is_none(), + "no value implies it's not set, but the caller will then default" + ); + Ok(()) + } + + #[test] + fn validate_upon_retrieval() -> crate::Result { + let module = submodule("[submodule.a]\n branch = /invalid"); + assert!(module.branch("a".into()).is_err()); + Ok(()) + } +} + +#[test] +fn shallow() -> crate::Result { + let module = submodule("[submodule.a]\n shallow"); + assert_eq!( + module.shallow("a".into())?, + Some(true), + "shallow is a simple boolean without anything special (yet)" + ); + Ok(()) +} + +mod append_submodule_overrides { + use std::str::FromStr; + + use crate::file::submodule; + + #[test] + fn last_of_multiple_values_wins() -> crate::Result { + let mut module = submodule("[submodule.a] url = from-module"); + let repo_config = + gix_config::File::from_str("[submodule.a]\n url = a\n url = b\n ignore = x\n [submodule.a]\n url = c\n[submodule.b] url = not-relevant")?; + module.append_submodule_overrides(&repo_config); + Ok(()) + } +} + +mod baseline; diff --git a/vendor/gix-submodule/tests/fixtures/basic.sh b/vendor/gix-submodule/tests/fixtures/basic.sh new file mode 100755 index 000000000..203e6afde --- /dev/null +++ b/vendor/gix-submodule/tests/fixtures/basic.sh @@ -0,0 +1,48 @@ +#!/bin/bash +set -eu -o pipefail + +set -x +git init +touch empty && git add empty +git commit -m upstream +git clone . super +git clone super multiple +(cd multiple + git submodule add ../multiple submodule + git submodule add ../multiple a/b + git submodule add --name .a/..c ../multiple a\\c + git submodule add --name a/d\\ ../multiple a/d\\ + git submodule add --name a\\e ../multiple a/e/ + git commit -m "subsubmodule-a" +) + +(cd super + git submodule add ../multiple submodule + git commit -m "submodule" +) +git clone super super-clone +(cd super-clone + git submodule update --init --recursive +) +git clone super empty-clone +(cd empty-clone + git submodule init +) +git clone super top-only-clone +git clone super relative-clone +(cd relative-clone + git submodule update --init --recursive +) +git clone super recursive-clone +(cd recursive-clone + git submodule update --init --recursive +) + +git clone super not-a-submodule +(cd not-a-submodule + cp .gitmodules modules.bak + git rm submodule + echo fake > submodule + mv modules.bak .gitmodules + git add submodule && git commit -m "no submodule in index and commit, but in configuration" +) diff --git a/vendor/gix-submodule/tests/fixtures/generated-archives/basic.tar.xz b/vendor/gix-submodule/tests/fixtures/generated-archives/basic.tar.xz Binary files differnew file mode 100644 index 000000000..d483db5e7 --- /dev/null +++ b/vendor/gix-submodule/tests/fixtures/generated-archives/basic.tar.xz diff --git a/vendor/gix-submodule/tests/submodule.rs b/vendor/gix-submodule/tests/submodule.rs new file mode 100644 index 000000000..75144b10c --- /dev/null +++ b/vendor/gix-submodule/tests/submodule.rs @@ -0,0 +1,3 @@ +use gix_testtools::Result; + +mod file; |