Skip to content

Commit c957ab8

Browse files
committed
Start on auto-generating gix-packetline-blocking/src
By copying the files with added headers, instead of having a symlink. Right now this is entirely as a shell script. It may be beneficial to rewrite at least some parts, especially those that are unnatural to implement portably as a shell script even given Bash, in Rust.
1 parent 68d1a29 commit c957ab8

File tree

3 files changed

+155
-1
lines changed

3 files changed

+155
-1
lines changed

.gitattributes

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
**/generated-archives/*.tar.xz filter=lfs-disabled diff=lfs merge=lfs -text
22

3-
# assure line feeds don't interfere with our working copy hash
3+
# assure line feeds don't interfere with our working copy hash
44
**/tests/fixtures/**/*.sh text crlf=input eol=lf
55
/justfile text crlf=input eol=lf
6+
7+
# have GitHub treat the gix-packetline-blocking src copy as auto-generated
8+
gix-packetline-blocking/src/ linguist-generated=true

etc/copy-packetline.sh

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#!/bin/bash
2+
3+
set -euC -o pipefail
4+
5+
function usage() {
6+
local name
7+
8+
name="$(basename -- "$0")"
9+
printf '%s [--all] regenerate gix-packetline-blocking source\n' "$name"
10+
printf '%s --file {path} regenerate a single file (avoid; prefer --all)\n' "$name"
11+
printf '%s --help print this message\n' "$name"
12+
}
13+
14+
function fail () {
15+
printf '%s: error: %s\n' "$0" "$1" >&2
16+
exit 1
17+
}
18+
19+
function status () {
20+
git status --short --ignored=traditional -- "$@"
21+
}
22+
23+
function avoids_pattern () (
24+
set +e # Temporary, since the function body is in ( ).
25+
grep -q "$@"
26+
test "$?" -eq 1 # Distinguish no-match from error.
27+
)
28+
29+
function indent () {
30+
sed 's/^/ /'
31+
}
32+
33+
function generate_all () {
34+
local root failures
35+
36+
root="$(git rev-parse --show-toplevel)/." # /. in case name ends in newline.
37+
cd -- "$root"
38+
39+
if ! test -d gix-packetline/src; then
40+
fail 'no source directory: gix-packetline/src'
41+
fi
42+
if ! test -d gix-packetline-blocking; then
43+
fail 'no target parent directory: gix-packetline-blocking'
44+
fi
45+
46+
# FIXME: This misinterprets the status when in an unresolved merge conflict!
47+
if ! status gix-packetline-blocking/src | avoids_pattern '^.[^ ]'; then
48+
fail 'target has unstaged changes or contains ignored files'
49+
fi
50+
51+
rm -rf gix-packetline-blocking/src # No trailing /, as it may be a symlink.
52+
if test -e gix-packetline-blocking/src; then
53+
fail 'unable to remove target'
54+
fi
55+
56+
failures="$(find gix-packetline/src/ -exec "$0" --file {} \; -o -print)"
57+
58+
# If we get here, traversal succeeded, but perhaps some generations failed.
59+
if test -n "$failures"; then
60+
fail $'failed to generate from:\n'"$(indent <<<"$failures")"
61+
fi
62+
}
63+
64+
function first_line_ends_crlf () {
65+
# This is tricky to check portably. On Windows in Cygwin-like environments
66+
# including MSYS2 and Git Bash, most text processing tools, including awk,
67+
# sed, and grep, automatically substitute \n for \r\n. Some can be told not
68+
# to, but in non-portable ways that may affect other implementations. Bash
69+
# does so on command substitution and other input, and optionally more often.
70+
# Easy ways to check are often non-portable to other OSes. Fortunately, tools
71+
# that treat input as binary data are exempt (including cat, but "-v" is not
72+
# portable, and it's unreliable in general as lines can end in "^M"). This
73+
# may be doable without od, by using tr more heavily, but it could be hard to
74+
# avoid false positives with unexpected characters, or with \r not before \n.
75+
76+
head -n 1 -- "$1" | # Get the longest prefix with no non-trailing \n byte.
77+
od -An -ta | # Show all bytes symbolically, without addresses.
78+
tr -sd '\n' ' ' | # Scrunch into one line, so "cr nl" appears as such.
79+
grep -q 'cr nl$' # Check if the result signifies a \r\n line ending.
80+
}
81+
82+
function make_header () {
83+
local source endline
84+
source="$1"
85+
endline="$2"
86+
87+
# shellcheck disable=SC2016 # The backticks are intentionally literal.
88+
printf '//! DO NOT EDIT - this is a copy of %s. Run `just copy-packetline` to update it.%s%s' \
89+
"$source" "$endline" "$endline"
90+
}
91+
92+
function copy_with_header () {
93+
local source target endline
94+
95+
source="$1"
96+
target="$2"
97+
98+
if first_line_ends_crlf "$source"; then
99+
endline=$'\r\n'
100+
else
101+
endline=$'\n'
102+
fi
103+
104+
make_header "$source" "$endline" | cat - -- "$source" >"$target"
105+
}
106+
107+
function generate_one () {
108+
local source shared target
109+
110+
source="$1"
111+
shared="${source#gix-packetline/src/}"
112+
if test "$source" = "$shared"; then
113+
fail "source path seems to be outside gix-packetline/src/: $source"
114+
fi
115+
target="gix-packetline-blocking/src/$shared"
116+
117+
if test -d "$source"; then
118+
mkdir -p -- "$target"
119+
elif test -L "$source"; then
120+
# Cover this case separately, for more useful error messages.
121+
fail "source file is symbolic link: $source"
122+
elif ! test -f "$source"; then
123+
# This covers less common kinds of files we can't/shouldn't process.
124+
fail "source file neither regular file nor directory: $source"
125+
elif [[ "$source" =~ \.rs$ ]]; then
126+
copy_with_header "$source" "$target"
127+
else
128+
fail "source file not named as Rust source code: $source"
129+
fi
130+
}
131+
132+
case "$0" in
133+
*{}*)
134+
# Some "find" implementations expand "{}" even inside a larger argument.
135+
fail "can't operate portably with literal {} in command name"
136+
;;
137+
esac
138+
139+
if { test "$#" -eq 1 && test "$1" = '--all'; } || test "$#" -eq 0; then
140+
generate_all
141+
elif test "$#" -eq 2 && test "$1" = '--file'; then
142+
generate_one "$2"
143+
elif test "$#" -eq 1 && test "$1" = '--help'; then
144+
usage
145+
else
146+
fail 'unrecognized syntax, try passing only --help for usage'
147+
fi

justfile

+4
Original file line numberDiff line numberDiff line change
@@ -252,3 +252,7 @@ fmt:
252252
# Cancel this after the first few seconds, as yanked crates will appear in warnings.
253253
find-yanked:
254254
cargo install --debug --locked --no-default-features --features max-pure --path .
255+
256+
# Delete gix-packetline-blocking/src and regenerate from gix-packetline/src
257+
copy-packetline:
258+
./etc/copy-packetline.sh

0 commit comments

Comments
 (0)