Gentoo Archives: gentoo-dev

From: Patrick McLean <chutzpah@g.o>
To: gentoo-dev@l.g.o
Cc: rust@g.o, gyakovlev@g.o, Patrick McLean <chutzpah@g.o>
Subject: [gentoo-dev] [PATCH] cargo.eclass: Add support for GIT_CRATES
Date: Tue, 07 Feb 2023 23:26:36
Message-Id: 20230207232557.3484952-2-chutzpah@gentoo.org
In Reply to: [gentoo-dev] cargo.eclass: Add support for GIT_CRATES by Patrick McLean
1 This adds support for an associative array called GIT_CRATES containing any
2 crates that must be fetched from git rather than just cargo crates. This will
3 add the code to the cargo config to make sure that the locations are overridden
4 so cargo won't try to fetch the crates from git.
5
6 Currently it automatically handle GitHub and GitLab URIs, and will accept
7 arbitrary URIs.
8
9 Tested-By: Georgy Yakovlev <gyakovlev@g.o>
10 Signed-off-by: Patrick McLean <chutzpah@g.o>
11 ---
12 eclass/cargo.eclass | 103 ++++++++++++++++++++++++++++++++++++++++++++
13 1 file changed, 103 insertions(+)
14
15 diff --git a/eclass/cargo.eclass b/eclass/cargo.eclass
16 index eb9d2e8c359..788663a070c 100644
17 --- a/eclass/cargo.eclass
18 +++ b/eclass/cargo.eclass
19 @@ -75,6 +75,43 @@ ECARGO_VENDOR="${ECARGO_HOME}/gentoo"
20 # SRC_URI="$(cargo_crate_uris)"
21 # @CODE
22
23 +# @ECLASS_VARIABLE: GIT_CRATES
24 +# @DEFAULT_UNSET
25 +# @PRE_INHERIT
26 +# @DESCRIPTION:
27 +# bash associative array containing all crates that a package wants
28 +# to be fetch by git.
29 +# The key is the crate name, the value is a semicolon separated list of
30 +# the following fields:
31 +#
32 +# - the URI to to fetch the crate from
33 +# - this intelligentally handles GitHub URIs and GitLab URIs so
34 +# just the path is needed.
35 +# - the string "%commit%" gets replaced with the commit
36 +# - the hash of the commit to use
37 +# - (optional) the path to look for Cargo.toml in
38 +# - this will also replace the string "%commit%" with the commit
39 +# - if this not provided, it will be generated using the crate name and
40 +# the commit
41 +# Used by cargo_crate_uris
42 +#
43 +# If this is defined, then cargo_src_install will add --frozen to "cargo install"
44 +#
45 +# Example of simple definition of GIT_CRATES without any paths defined
46 +# @CODE
47 +# declare -A GIT_CRATES=(
48 +# [home]="https://github.com/rbtcollins/home;a243ee2fbee6022c57d56f5aa79aefe194eabe53"
49 +# )
50 +# @CODE
51 +#
52 +# Example code of how to define GIT_CRATES with paths defined.
53 +# @CODE
54 +# declare -A GIT_CRATES=(
55 +# [rustpython-common]="https://github.com/RustPython/RustPython;4f38cb68e4a97aeea9eb19673803a0bd5f655383;RustPython-%commit%/common"
56 +# [rustpython-parser]="https://github.com/RustPython/RustPython;4f38cb68e4a97aeea9eb19673803a0bd5f655383;RustPython-%commit%/compiler/parser"
57 +# )
58 +# @CODE
59 +
60 # @ECLASS_VARIABLE: CARGO_OPTIONAL
61 # @DEFAULT_UNSET
62 # @PRE_INHERIT
63 @@ -160,6 +197,37 @@ cargo_crate_uris() {
64 url="https://crates.io/api/v1/crates/${name}/${version}/download -> ${crate}.crate"
65 echo "${url}"
66 done
67 +
68 + local git_crates_type
69 + git_crates_type="$(declare -p GIT_CRATES)"
70 + if [[ ${git_crates_type} == "declare -A "* ]]; then
71 + local crate commit crate_uri crate_dir repo_ext feat_expr
72 +
73 + for crate in "${!GIT_CRATES[@]}"; do
74 + IFS=';' read -r crate_uri commit crate_dir <<< "${GIT_CRATES[${crate}]}"
75 +
76 + case "${crate_uri}" in
77 + https://github.com/*)
78 + repo_ext=".gh"
79 + repo_name="${crate_uri##*/}"
80 + crate_uri="${crate_uri%/}/archive/%commit%.tar.gz"
81 + ;;
82 + https://gitlab.com/*)
83 + repo_ext=".gl"
84 + repo_name="${crate_uri##*/}"
85 + crate_uri="${crate_uri%/}/archive/-/%commit%/${repo_name}/%commit%.tar.gz"
86 + ;;
87 + *)
88 + repo_ext=
89 + repo_name="${crate}"
90 + ;;
91 + esac
92 +
93 + printf -- '%s -> %s\n' "${crate_uri//%commit%/${commit}}" "${repo_name}-${commit}${repo_ext}.tar.gz"
94 + done
95 + elif [[ -n ${git_crates_type} ]]; then
96 + die "GIT_CRATE must be declared as an associative array"
97 + fi
98 }
99
100 # @FUNCTION: cargo_gen_config
101 @@ -195,12 +263,46 @@ cargo_gen_config() {
102 [term]
103 verbose = true
104 $([[ "${NOCOLOR}" = true || "${NOCOLOR}" = yes ]] && echo "color = 'never'")
105 + $(_cargo_gen_git_config)
106 _EOF_
107
108 export CARGO_HOME="${ECARGO_HOME}"
109 _CARGO_GEN_CONFIG_HAS_RUN=1
110 }
111
112 +# @FUNCTION: _cargo_gen_git_config
113 +# @USAGE:
114 +# @INTERNAL
115 +# @DESCRIPTION:
116 +# Generate the cargo config for git crates, this will output the
117 +# configuration for cargo to override the cargo config so the local git crates
118 +# specified in GIT_CRATES will be used rather than attempting to fetch
119 +# from git.
120 +#
121 +# Called by cargo_gen_config when generating the config.
122 +_cargo_gen_git_config() {
123 + local git_crates_type
124 + git_crates_type="$(declare -p GIT_CRATES)"
125 +
126 + if [[ ${git_crates_type} == "declare -A "* ]]; then
127 + local crate commit crate_uri crate_dir
128 + local -A crate_patches
129 +
130 + for crate in "${!GIT_CRATES[@]}"; do
131 + IFS=';' read -r crate_uri commit crate_dir <<< "${GIT_CRATES[${crate}]}"
132 + : "${crate_dir:=${crate}-%commit%}"
133 + crate_patches["${crate_uri}"]+="${crate} = { path = \"${WORKDIR}/${crate_dir//%commit%/${commit}}\" };;"
134 + done
135 +
136 + for crate_uri in "${!crate_patches[@]}"; do
137 + printf -- "[patch.'%s']\\n%s\n" "${crate_uri}" "${crate_patches["${crate_uri}"]//;;/$'\n'}"
138 + done
139 +
140 + elif [[ -n ${git_crates_type} ]]; then
141 + die "GIT_CRATE must be declared as an associative array"
142 + fi
143 +}
144 +
145 # @FUNCTION: cargo_src_unpack
146 # @DESCRIPTION:
147 # Unpacks the package and the cargo registry
148 @@ -412,6 +514,7 @@ cargo_src_install() {
149
150 set -- cargo install $(has --path ${@} || echo --path ./) \
151 --root "${ED}/usr" \
152 + ${GIT_CRATES:---frozen} \
153 $(usex debug --debug "") \
154 ${ECARGO_ARGS[@]} "$@"
155 einfo "${@}"
156 --
157 2.39.1