mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-28 09:31:16 -03:00
Compare commits
392 Commits
docker-bui
...
4.2.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
896f0606cd | ||
|
|
2649f8d591 | ||
|
|
e77102d73e | ||
|
|
ac94bc774b | ||
|
|
83eca32111 | ||
|
|
f5662d578e | ||
|
|
80363314aa | ||
|
|
6ce3bb858d | ||
|
|
1c34fb064a | ||
|
|
366b85beb2 | ||
|
|
82038e236d | ||
|
|
f72fc7f09b | ||
|
|
c323a2d5fe | ||
|
|
662b55ee6b | ||
|
|
2e92255032 | ||
|
|
5182901bcc | ||
|
|
248eb2eb4a | ||
|
|
458fe1be2f | ||
|
|
8589231742 | ||
|
|
59658b44a9 | ||
|
|
3f2e4b71bc | ||
|
|
9b42051ba7 | ||
|
|
674e93d127 | ||
|
|
b1472827e7 | ||
|
|
856e649487 | ||
|
|
bc71a1662d | ||
|
|
33bf808084 | ||
|
|
78f71971cb | ||
|
|
b4fc5160ba | ||
|
|
9d3acbdd82 | ||
|
|
873ede7a77 | ||
|
|
d7581dbaa4 | ||
|
|
71e4d7ba87 | ||
|
|
46f7f47bda | ||
|
|
4046df7412 | ||
|
|
a772470b76 | ||
|
|
e1ce53fe15 | ||
|
|
77bdd4fbde | ||
|
|
3fdaa543ed | ||
|
|
336be1e36d | ||
|
|
382027663f | ||
|
|
1d58b84637 | ||
|
|
88ead18709 | ||
|
|
70058bdee2 | ||
|
|
d1c85966d9 | ||
|
|
0679d98950 | ||
|
|
a8b7d89ba5 | ||
|
|
828773b391 | ||
|
|
35f4eb8e9a | ||
|
|
8c69e62a78 | ||
|
|
8e4fa9aafb | ||
|
|
d6ed5f843e | ||
|
|
ba7bc2be13 | ||
|
|
199475b6ca | ||
|
|
60b50afefd | ||
|
|
7aa64dc423 | ||
|
|
7a59540517 | ||
|
|
2cd60077e6 | ||
|
|
2c68a6704f | ||
|
|
cc95cef165 | ||
|
|
cd76c2cb26 | ||
|
|
c586210306 | ||
|
|
ec3cd4f4cb | ||
|
|
eef5a7ff2b | ||
|
|
988985727f | ||
|
|
dad58ac20a | ||
|
|
3f9d8db5b7 | ||
|
|
0b6afbd17b | ||
|
|
e9936bc5ed | ||
|
|
068a1ab95c | ||
|
|
74d9a3537c | ||
|
|
143a4aca0f | ||
|
|
20e66ad990 | ||
|
|
ceec382161 | ||
|
|
782916930a | ||
|
|
a767739c06 | ||
|
|
cf3c9d75d7 | ||
|
|
1846d7fd7e | ||
|
|
b8c7ee3a85 | ||
|
|
0709e4be8b | ||
|
|
328f9a9d16 | ||
|
|
1d9233abc7 | ||
|
|
c9cc2a4069 | ||
|
|
e0a2fa35cc | ||
|
|
da5a57890a | ||
|
|
c7772db4fb | ||
|
|
f00b775172 | ||
|
|
a5cbbd7f10 | ||
|
|
c409e816df | ||
|
|
8d02987c64 | ||
|
|
e091bc3ba2 | ||
|
|
4f9c9b5be4 | ||
|
|
10e0515d50 | ||
|
|
bae735740c | ||
|
|
3b0fa95870 | ||
|
|
d4390c2fad | ||
|
|
9845074a53 | ||
|
|
e7dc1c4635 | ||
|
|
07e26518fc | ||
|
|
034b3b758d | ||
|
|
ea5d77ad6f | ||
|
|
cb320e17ed | ||
|
|
ca8b18cad5 | ||
|
|
aec459c795 | ||
|
|
13d62d5851 | ||
|
|
d8516139c8 | ||
|
|
7f8263b625 | ||
|
|
daadd81ab6 | ||
|
|
c0b7167082 | ||
|
|
ff50e761dd | ||
|
|
7c61fc5151 | ||
|
|
ab39fab68c | ||
|
|
9953edb9ab | ||
|
|
8d2dabbded | ||
|
|
708703b9ec | ||
|
|
def9230ad6 | ||
|
|
4ef0e37011 | ||
|
|
ce82577d2f | ||
|
|
f6584225c2 | ||
|
|
a0a8a0b817 | ||
|
|
f88b1fd393 | ||
|
|
bd720ec9f6 | ||
|
|
56555f6319 | ||
|
|
71a962653d | ||
|
|
732942ec62 | ||
|
|
5eebeff5a9 | ||
|
|
f6d7198317 | ||
|
|
dc553ac628 | ||
|
|
6643b8c3e1 | ||
|
|
2954ff3991 | ||
|
|
ab69ef4b83 | ||
|
|
e8c0b3df24 | ||
|
|
5a12247572 | ||
|
|
58eec96a5b | ||
|
|
2be3f34f2c | ||
|
|
7bd6e577d9 | ||
|
|
e09583e99e | ||
|
|
d1983b29c1 | ||
|
|
c0a988da21 | ||
|
|
f5544fe2ae | ||
|
|
75be4e3f6a | ||
|
|
6c267e88a1 | ||
|
|
27f49b9523 | ||
|
|
b8f12ed857 | ||
|
|
5cad71c081 | ||
|
|
f331f6a8a9 | ||
|
|
461670c36a | ||
|
|
0f32866980 | ||
|
|
c123126991 | ||
|
|
1302ac16f0 | ||
|
|
cc51d91e77 | ||
|
|
2d1c34c36a | ||
|
|
6422139fe0 | ||
|
|
f511ef69c3 | ||
|
|
525c9bbdcb | ||
|
|
7bc560190f | ||
|
|
54b39be7e7 | ||
|
|
578f46c008 | ||
|
|
b1cbbf7ce5 | ||
|
|
af9b03625b | ||
|
|
71f0e75651 | ||
|
|
3c4243fdd2 | ||
|
|
1a1da0649a | ||
|
|
69ccc9be18 | ||
|
|
61d6a83661 | ||
|
|
2f5260aabd | ||
|
|
eca19006ad | ||
|
|
d22b5910c2 | ||
|
|
a868be6ba4 | ||
|
|
8822ba3035 | ||
|
|
e20b06df1a | ||
|
|
e299b71560 | ||
|
|
d6f0e1fdf2 | ||
|
|
4a5bce3fb8 | ||
|
|
7f1dc80b9c | ||
|
|
43731c88bd | ||
|
|
332712866c | ||
|
|
b0d643c4ce | ||
|
|
2b9967bf01 | ||
|
|
9d53d61141 | ||
|
|
c66fa682e9 | ||
|
|
819759840e | ||
|
|
ccde87c4e3 | ||
|
|
3a9c5c7dc0 | ||
|
|
d27537c4fc | ||
|
|
973f0f6134 | ||
|
|
1973f3110e | ||
|
|
95e7977e70 | ||
|
|
15d06f964d | ||
|
|
5f96a4e665 | ||
|
|
075e4040be | ||
|
|
7d41158b1d | ||
|
|
00784248db | ||
|
|
b47b61ea08 | ||
|
|
787c6a443d | ||
|
|
f075c58eb5 | ||
|
|
07f0b1816e | ||
|
|
73696da21c | ||
|
|
e22d90cbad | ||
|
|
c7fdb8dc6b | ||
|
|
f7359751c9 | ||
|
|
0b7ab5a1b5 | ||
|
|
e7ad7e5cf6 | ||
|
|
9ccd6fb2d2 | ||
|
|
e7e97833a3 | ||
|
|
2dd6a7ba22 | ||
|
|
034cd7ea35 | ||
|
|
037a399746 | ||
|
|
6a86974b96 | ||
|
|
3c468054bd | ||
|
|
6fd1304e52 | ||
|
|
a51b2f4023 | ||
|
|
abf3f50bb9 | ||
|
|
20a6ac947b | ||
|
|
b158ba1523 | ||
|
|
372a65aa15 | ||
|
|
804bda5ba6 | ||
|
|
2f07df717d | ||
|
|
1d0de5ce71 | ||
|
|
c8001b5023 | ||
|
|
755d5ae222 | ||
|
|
5cfcfc64d8 | ||
|
|
606802daaf | ||
|
|
71b619bab0 | ||
|
|
a033a5d0e7 | ||
|
|
3f2c58a269 | ||
|
|
f946e5ec73 | ||
|
|
9d06302778 | ||
|
|
bb7180a2d8 | ||
|
|
6f5644a77c | ||
|
|
d79273089f | ||
|
|
68d02916e2 | ||
|
|
d414967b79 | ||
|
|
448471bd50 | ||
|
|
15fd99072b | ||
|
|
61ee695e56 | ||
|
|
1fe6b28877 | ||
|
|
4f48797a09 | ||
|
|
3736636d99 | ||
|
|
16f2135976 | ||
|
|
73fe50f6b1 | ||
|
|
0b5f82a5f0 | ||
|
|
02725b66b3 | ||
|
|
52ea511768 | ||
|
|
c65748c098 | ||
|
|
8aeafa13c9 | ||
|
|
07514c5df0 | ||
|
|
43f8d7478e | ||
|
|
1c3a6a463d | ||
|
|
41636c8e35 | ||
|
|
78e8f87e54 | ||
|
|
8cb5ad9693 | ||
|
|
83ece2161d | ||
|
|
63cda65815 | ||
|
|
165e0d0ed5 | ||
|
|
cab6b97539 | ||
|
|
1c853a4d24 | ||
|
|
73fbd5d994 | ||
|
|
9a43acd77b | ||
|
|
28e8f45828 | ||
|
|
ac8ef4da9e | ||
|
|
52241712b4 | ||
|
|
584a21b34b | ||
|
|
b82920dc26 | ||
|
|
ea69133e48 | ||
|
|
f72ebca1e4 | ||
|
|
40d772fde3 | ||
|
|
d4837f9ef1 | ||
|
|
b44209e14e | ||
|
|
531269bb84 | ||
|
|
80faf5e805 | ||
|
|
0d5fd181be | ||
|
|
8c279b854d | ||
|
|
f1f95c6867 | ||
|
|
ecedd8caed | ||
|
|
ce5b5ec053 | ||
|
|
37e0a5ae8d | ||
|
|
5792df9738 | ||
|
|
73f0e14d90 | ||
|
|
a216cfdd2f | ||
|
|
fad0e39cfa | ||
|
|
4532fc0c1b | ||
|
|
03d21edd63 | ||
|
|
f72b833e38 | ||
|
|
45a3f4f1d6 | ||
|
|
3aab119e5b | ||
|
|
0a1ca206fa | ||
|
|
028e05fff1 | ||
|
|
dabd956216 | ||
|
|
441f90fb55 | ||
|
|
3b52d3db42 | ||
|
|
39943a8406 | ||
|
|
48bdf24964 | ||
|
|
fed2714e30 | ||
|
|
c8262929e1 | ||
|
|
0ded3ed6f9 | ||
|
|
2b428fae38 | ||
|
|
b07adb532a | ||
|
|
af72d4aebc | ||
|
|
bfab595379 | ||
|
|
d72adc0124 | ||
|
|
5f0d83d2f2 | ||
|
|
03f54171c6 | ||
|
|
f391b4a179 | ||
|
|
8db674b6b5 | ||
|
|
f03113d048 | ||
|
|
6c48e214ca | ||
|
|
189a2e90dd | ||
|
|
9b44138917 | ||
|
|
ec7d20b347 | ||
|
|
84b52a3ed1 | ||
|
|
30b1c9570f | ||
|
|
b88622bc35 | ||
|
|
a4edb4020d | ||
|
|
e1e5dfdd62 | ||
|
|
5102c8b137 | ||
|
|
9ae9db7f70 | ||
|
|
d0aaa8d809 | ||
|
|
6024539c12 | ||
|
|
fb06ad4a44 | ||
|
|
598e98794c | ||
|
|
b3a295959d | ||
|
|
50dfd962ec | ||
|
|
65332eaacc | ||
|
|
a00e6f8696 | ||
|
|
6415dfbd35 | ||
|
|
8c387c58de | ||
|
|
da411f6fa7 | ||
|
|
8fe402e9f7 | ||
|
|
c41fc52077 | ||
|
|
f7d730390c | ||
|
|
8fc30d5243 | ||
|
|
93c4d63295 | ||
|
|
7a07c08860 | ||
|
|
1cf110d083 | ||
|
|
fef358fc74 | ||
|
|
b5feb79a7c | ||
|
|
4d52245617 | ||
|
|
ff308b36af | ||
|
|
fa8cf8a1a5 | ||
|
|
5ade4a037e | ||
|
|
861002917a | ||
|
|
eddb26d490 | ||
|
|
b7fe3190bb | ||
|
|
b6ddb56cc7 | ||
|
|
8dd59081d7 | ||
|
|
3ae17ea100 | ||
|
|
10c34c5353 | ||
|
|
e3ebda3647 | ||
|
|
092e7fa274 | ||
|
|
dd47c2baa2 | ||
|
|
15065255e9 | ||
|
|
594f1df39c | ||
|
|
724416125e | ||
|
|
3afafe6398 | ||
|
|
af7446a055 | ||
|
|
7be101e8c9 | ||
|
|
5f18b173dd | ||
|
|
3fec9c8145 | ||
|
|
bdca70bfb0 | ||
|
|
5e28f068ec | ||
|
|
a0b22077a5 | ||
|
|
1d36b04ea6 | ||
|
|
6829c9d678 | ||
|
|
e1f6ab8916 | ||
|
|
778baaecb5 | ||
|
|
a189f79590 | ||
|
|
6395644e8c | ||
|
|
a958f23f63 | ||
|
|
ec8756d7a3 | ||
|
|
b7fabb11ac | ||
|
|
74ba4e9a98 | ||
|
|
b1e8fdfaa2 | ||
|
|
9eb439c01d | ||
|
|
fbfd29d6d2 | ||
|
|
f158a3ae3e | ||
|
|
7d59b4f4e2 | ||
|
|
e99eca47c3 | ||
|
|
d683769e1f | ||
|
|
9ea328e43a | ||
|
|
f6d93f2fdb | ||
|
|
b644fdbb04 | ||
|
|
7647d68b68 | ||
|
|
d167ab9376 | ||
|
|
e68bd2f980 | ||
|
|
b5c17d4743 | ||
|
|
66ca7ac6d0 | ||
|
|
e97a616ffa | ||
|
|
061517cd14 | ||
|
|
6accc475c9 | ||
|
|
c2e2fd6432 | ||
|
|
83af5c91bd |
@@ -1,7 +1,6 @@
|
|||||||
image: alpine/edge
|
image: alpine/edge
|
||||||
packages:
|
packages:
|
||||||
- cargo
|
- cargo
|
||||||
- clang17-libclang
|
|
||||||
- cmake
|
- cmake
|
||||||
- ninja
|
- ninja
|
||||||
- pcre2-dev
|
- pcre2-dev
|
||||||
@@ -24,4 +23,4 @@ tasks:
|
|||||||
ninja
|
ninja
|
||||||
- test: |
|
- test: |
|
||||||
cd fish-shell/build
|
cd fish-shell/build
|
||||||
ninja test
|
ninja fish_run_tests
|
||||||
|
|||||||
@@ -20,4 +20,4 @@ tasks:
|
|||||||
ninja
|
ninja
|
||||||
- test: |
|
- test: |
|
||||||
cd fish/build
|
cd fish/build
|
||||||
ninja test
|
ninja fish_run_tests
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ packages:
|
|||||||
- gettext
|
- gettext
|
||||||
- gmake
|
- gmake
|
||||||
- llvm
|
- llvm
|
||||||
- terminfo-db
|
|
||||||
- ninja
|
- ninja
|
||||||
- pcre2
|
- pcre2
|
||||||
- py311-pexpect
|
- py311-pexpect
|
||||||
|
- py311-sphinx
|
||||||
- python
|
- python
|
||||||
- rust
|
- rust
|
||||||
- tmux
|
- tmux
|
||||||
@@ -27,4 +27,4 @@ tasks:
|
|||||||
ninja
|
ninja
|
||||||
- test: |
|
- test: |
|
||||||
cd fish-shell/build
|
cd fish-shell/build
|
||||||
ninja test
|
ninja fish_run_tests
|
||||||
|
|||||||
30
.builds/openbsd.yml
Normal file
30
.builds/openbsd.yml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
image: openbsd/latest
|
||||||
|
packages:
|
||||||
|
- cmake
|
||||||
|
- gcc
|
||||||
|
- gettext
|
||||||
|
- gmake
|
||||||
|
- llvm
|
||||||
|
- ninja
|
||||||
|
- pcre2
|
||||||
|
- py3-pexpect
|
||||||
|
- py3-sphinx
|
||||||
|
- python
|
||||||
|
- rust
|
||||||
|
- tmux
|
||||||
|
sources:
|
||||||
|
- https://github.com/fish-shell/fish-shell
|
||||||
|
tasks:
|
||||||
|
- build: |
|
||||||
|
cd fish-shell
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake -GNinja .. \
|
||||||
|
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||||
|
-DCMAKE_INSTALL_DATADIR=share \
|
||||||
|
-DCMAKE_INSTALL_DOCDIR=share/doc/fish \
|
||||||
|
-DCMAKE_INSTALL_SYSCONFDIR=/etc
|
||||||
|
ninja
|
||||||
|
- test: |
|
||||||
|
cd fish-shell/build
|
||||||
|
ninja fish_run_tests
|
||||||
45
.cirrus.yml
45
.cirrus.yml
@@ -8,48 +8,26 @@ linux_task:
|
|||||||
container: &step
|
container: &step
|
||||||
image: ghcr.io/krobelus/fish-ci/alpine:latest
|
image: ghcr.io/krobelus/fish-ci/alpine:latest
|
||||||
memory: 4GB
|
memory: 4GB
|
||||||
- name: jammy
|
- name: ubuntu-oldest-supported
|
||||||
container:
|
container:
|
||||||
<<: *step
|
<<: *step
|
||||||
image: ghcr.io/krobelus/fish-ci/jammy:latest
|
image: ghcr.io/krobelus/fish-ci/ubuntu-oldest-supported:latest
|
||||||
# - name: jammy-asan
|
|
||||||
# container:
|
|
||||||
# <<: *step
|
|
||||||
# image: ghcr.io/krobelus/fish-ci/jammy-asan:latest
|
|
||||||
# - name: focal-32bit
|
|
||||||
# container:
|
|
||||||
# <<: *step
|
|
||||||
# image: ghcr.io/krobelus/fish-ci/focal-32bit:latest
|
|
||||||
tests_script:
|
tests_script:
|
||||||
# cirrus at times gives us 32 procs and 2 GB of RAM
|
# cirrus at times gives us 32 procs and 2 GB of RAM
|
||||||
# Unrestriced parallelism results in OOM
|
# Unrestriced parallelism results in OOM
|
||||||
- lscpu || true
|
- lscpu || true
|
||||||
- (cat /proc/meminfo | grep MemTotal) || true
|
- (cat /proc/meminfo | grep MemTotal) || true
|
||||||
- FISH_TEST_MAX_CONCURRENCY=6 build_tools/check.sh
|
- mkdir build && cd build
|
||||||
|
- FISH_TEST_MAX_CONCURRENCY=6 cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
|
- ninja -j 6 fish
|
||||||
|
- ninja fish_run_tests
|
||||||
only_if: $CIRRUS_REPO_OWNER == 'fish-shell'
|
only_if: $CIRRUS_REPO_OWNER == 'fish-shell'
|
||||||
|
|
||||||
linux_arm_task:
|
|
||||||
matrix:
|
|
||||||
- name: focal-arm64
|
|
||||||
arm_container:
|
|
||||||
image: ghcr.io/fish-shell/fish-ci/focal-arm64
|
|
||||||
- name: jammy-armv7-32bit
|
|
||||||
arm_container:
|
|
||||||
image: ghcr.io/fish-shell/fish-ci/jammy-armv7-32bit
|
|
||||||
tests_script:
|
|
||||||
# cirrus at times gives us 32 procs and 2 GB of RAM
|
|
||||||
# Unrestriced parallelism results in OOM
|
|
||||||
- lscpu || true
|
|
||||||
- (cat /proc/meminfo | grep MemTotal) || true
|
|
||||||
- FISH_TEST_MAX_CONCURRENCY=6 build_tools/check.sh
|
|
||||||
# CI task disabled during RIIR transition
|
|
||||||
only_if: false && $CIRRUS_REPO_OWNER == 'fish-shell'
|
|
||||||
|
|
||||||
freebsd_task:
|
freebsd_task:
|
||||||
matrix:
|
matrix:
|
||||||
- name: FreeBSD 14
|
- name: FreeBSD Stable
|
||||||
freebsd_instance:
|
freebsd_instance:
|
||||||
image: freebsd-14-3-release-amd64-ufs
|
image: freebsd-14-3-release-amd64-ufs # updatecli.d/cirrus-freebsd.yml
|
||||||
tests_script:
|
tests_script:
|
||||||
- pkg install -y cmake-core devel/pcre2 devel/ninja gettext git-lite lang/rust misc/py-pexpect
|
- pkg install -y cmake-core devel/pcre2 devel/ninja gettext git-lite lang/rust misc/py-pexpect
|
||||||
# libclang.so is a required build dependency for rust-c++ ffi bridge
|
# libclang.so is a required build dependency for rust-c++ ffi bridge
|
||||||
@@ -61,7 +39,10 @@ freebsd_task:
|
|||||||
- pw user add -n fish-user -s /bin/csh -d /home/fish-user
|
- pw user add -n fish-user -s /bin/csh -d /home/fish-user
|
||||||
- mkdir -p /home/fish-user
|
- mkdir -p /home/fish-user
|
||||||
- chown -R fish-user /home/fish-user
|
- chown -R fish-user /home/fish-user
|
||||||
- chown -R fish-user .
|
- mkdir build && cd build
|
||||||
|
- chown -R fish-user ..
|
||||||
- sudo -u fish-user -s whoami
|
- sudo -u fish-user -s whoami
|
||||||
- sudo -u fish-user -s FISH_TEST_MAX_CONCURRENCY=1 build_tools/check.sh
|
- sudo -u fish-user -s FISH_TEST_MAX_CONCURRENCY=1 cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
|
- sudo -u fish-user -s ninja -j 6 fish
|
||||||
|
- sudo -u fish-user -s ninja fish_run_tests
|
||||||
only_if: $CIRRUS_REPO_OWNER == 'fish-shell'
|
only_if: $CIRRUS_REPO_OWNER == 'fish-shell'
|
||||||
|
|||||||
41
.github/actions/install-dependencies/action.yml
vendored
Normal file
41
.github/actions/install-dependencies/action.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
name: Install dependencies for system tests
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
include_sphinx:
|
||||||
|
description: Whether to install Sphinx
|
||||||
|
required: true
|
||||||
|
default: false
|
||||||
|
include_pcre:
|
||||||
|
description: Whether to install the PCRE library
|
||||||
|
required: false
|
||||||
|
default: true
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- shell: bash
|
||||||
|
env:
|
||||||
|
include_pcre: ${{ inputs.include_pcre }}
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
: "optional dependencies"
|
||||||
|
sudo apt install \
|
||||||
|
gettext \
|
||||||
|
$(if $include_pcre; then echo libpcre2-dev; fi) \
|
||||||
|
;
|
||||||
|
: "system test dependencies"
|
||||||
|
sudo apt install \
|
||||||
|
diffutils $(: "for diff") \
|
||||||
|
git \
|
||||||
|
gettext \
|
||||||
|
less \
|
||||||
|
$(if ${{ inputs.include_pcre }}; then echo libpcre2-dev; fi) \
|
||||||
|
python3-pexpect \
|
||||||
|
tmux \
|
||||||
|
wget \
|
||||||
|
;
|
||||||
|
- uses: ./.github/actions/install-sphinx
|
||||||
|
if: ${{ inputs.include_sphinx == 'true' }}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
name: Install sphinx-markdown-builder
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: "composite"
|
|
||||||
steps:
|
|
||||||
- shell: bash
|
|
||||||
run: |
|
|
||||||
set -x
|
|
||||||
commit=b259de1dc97573a71470a1d71c3d83535934136b
|
|
||||||
pip install git+https://github.com/krobelus/sphinx-markdown-builder@"$commit"
|
|
||||||
python -c 'import sphinx_markdown_builder'
|
|
||||||
22
.github/actions/install-sphinx/action.yml
vendored
Normal file
22
.github/actions/install-sphinx/action.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
name: Install sphinx
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- shell: bash
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
pip=$(command -v pip pip3 | head -1)
|
||||||
|
sudo "$pip" install uv --break-system-packages
|
||||||
|
# Check that pyproject.toml and the lock file are in sync.
|
||||||
|
# TODO Use "uv" to install Python as well.
|
||||||
|
: 'Note that --no-managed-python below would be implied but be explicit'
|
||||||
|
uv='env UV_PYTHON=python uv --no-managed-python'
|
||||||
|
$uv lock --check
|
||||||
|
# Install globally.
|
||||||
|
sudo $uv pip install --group=dev --system --break-system-packages
|
||||||
|
# Smoke test.
|
||||||
|
python -c 'import sphinx; import sphinx_markdown_builder'
|
||||||
41
.github/actions/rust-toolchain/action.yml
vendored
Normal file
41
.github/actions/rust-toolchain/action.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
name: Rust Toolchain
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
toolchain_channel:
|
||||||
|
description: Either "stable" or "msrv"
|
||||||
|
required: true
|
||||||
|
targets:
|
||||||
|
description: Comma-separated list of target triples to install for this toolchain
|
||||||
|
required: false
|
||||||
|
components:
|
||||||
|
description: Comma-separated list of components to be additionally installed
|
||||||
|
required: false
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Set toolchain
|
||||||
|
env:
|
||||||
|
toolchain_channel: ${{ inputs.toolchain_channel }}
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
toolchain=$(
|
||||||
|
case "$toolchain_channel" in
|
||||||
|
(stable) echo 1.91 ;; # updatecli.d/rust.yml
|
||||||
|
(msrv) echo 1.85 ;; # updatecli.d/rust.yml
|
||||||
|
(*)
|
||||||
|
printf >&2 "error: unsupported toolchain channel %s" "$toolchain_channel"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
)
|
||||||
|
printf 'TOOLCHAIN=%s\n' "$toolchain" >>"$GITHUB_ENV"
|
||||||
|
- uses: dtolnay/rust-toolchain@master
|
||||||
|
with:
|
||||||
|
toolchain: ${{ env.TOOLCHAIN }}
|
||||||
|
targets: ${{ inputs.targets }}
|
||||||
|
components: ${{ inputs.components }}
|
||||||
@@ -14,7 +14,8 @@ permissions:
|
|||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
- uses: dtolnay/rust-toolchain@1.70
|
- uses: ./.github/actions/rust-toolchain
|
||||||
with:
|
with:
|
||||||
|
toolchain_channel: "msrv"
|
||||||
targets: ${{ inputs.targets }}
|
targets: ${{ inputs.targets }}
|
||||||
components: ${{ inputs.components}}
|
components: ${{ inputs.components }}
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ permissions:
|
|||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
- uses: dtolnay/rust-toolchain@1.90
|
- uses: ./.github/actions/rust-toolchain
|
||||||
with:
|
with:
|
||||||
|
toolchain_channel: "stable"
|
||||||
targets: ${{ inputs.targets }}
|
targets: ${{ inputs.targets }}
|
||||||
components: ${{ inputs.components }}
|
components: ${{ inputs.components }}
|
||||||
|
|||||||
64
.github/workflows/build_docker_images.yml
vendored
Normal file
64
.github/workflows/build_docker_images.yml
vendored
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
name: Build Docker test images
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
paths:
|
||||||
|
- 'docker/**'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: docker-builds
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: ghcr.io
|
||||||
|
NAMESPACE: fish-ci
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker-build:
|
||||||
|
if: github.repository_owner == 'fish-shell'
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
attestations: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: ubuntu-latest
|
||||||
|
target: alpine
|
||||||
|
- os: ubuntu-latest
|
||||||
|
target: ubuntu-oldest-supported
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v5
|
||||||
|
-
|
||||||
|
name: Login to Container registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
-
|
||||||
|
name: Extract metadata (tags, labels) for Docker
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.NAMESPACE }}/${{ matrix.target }}
|
||||||
|
flavor: |
|
||||||
|
latest=true
|
||||||
|
-
|
||||||
|
name: Build and push
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: docker/context
|
||||||
|
push: true
|
||||||
|
file: docker/${{ matrix.target }}.Dockerfile
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Rust checks
|
name: Lint
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
@@ -6,25 +6,39 @@ permissions:
|
|||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
rustfmt:
|
format:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: ./.github/actions/rust-toolchain@stable
|
- uses: ./.github/actions/rust-toolchain@stable
|
||||||
with:
|
with:
|
||||||
components: rustfmt
|
components: rustfmt
|
||||||
- name: cargo fmt
|
- name: install dependencies
|
||||||
run: cargo fmt --check
|
run: pip install ruff
|
||||||
|
- name: build fish
|
||||||
|
run: cargo build
|
||||||
|
- name: check format
|
||||||
|
run: PATH="target/debug:$PATH" build_tools/style.fish --all --check
|
||||||
|
- name: check rustfmt
|
||||||
|
run: find build.rs crates src -type f -name '*.rs' | xargs rustfmt --check
|
||||||
|
|
||||||
clippy-stable:
|
|
||||||
|
clippy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
features: ["", "--no-default-features"]
|
include:
|
||||||
|
- rust_version: "stable"
|
||||||
|
features: ""
|
||||||
|
- rust_version: "stable"
|
||||||
|
features: "--no-default-features"
|
||||||
|
- rust_version: "msrv"
|
||||||
|
features: ""
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: ./.github/actions/rust-toolchain@stable
|
- uses: ./.github/actions/rust-toolchain
|
||||||
with:
|
with:
|
||||||
|
toolchain_channel: ${{ matrix.rust_version }}
|
||||||
components: clippy
|
components: clippy
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
run: |
|
run: |
|
||||||
@@ -32,19 +46,6 @@ jobs:
|
|||||||
- name: cargo clippy
|
- name: cargo clippy
|
||||||
run: cargo clippy --workspace --all-targets ${{ matrix.features }} -- --deny=warnings
|
run: cargo clippy --workspace --all-targets ${{ matrix.features }} -- --deny=warnings
|
||||||
|
|
||||||
clippy-msrv:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: ./.github/actions/rust-toolchain@oldest-supported
|
|
||||||
with:
|
|
||||||
components: clippy
|
|
||||||
- name: Install deps
|
|
||||||
run: |
|
|
||||||
sudo apt install gettext
|
|
||||||
- name: cargo clippy
|
|
||||||
run: cargo clippy --workspace --all-targets -- --deny=warnings
|
|
||||||
|
|
||||||
rustdoc:
|
rustdoc:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
1
.github/workflows/lockthreads.yml
vendored
1
.github/workflows/lockthreads.yml
vendored
@@ -12,6 +12,7 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lock:
|
lock:
|
||||||
|
if: github.repository_owner == 'fish-shell'
|
||||||
permissions:
|
permissions:
|
||||||
issues: write # for dessant/lock-threads to lock issues
|
issues: write # for dessant/lock-threads to lock issues
|
||||||
pull-requests: write # for dessant/lock-threads to lock PRs
|
pull-requests: write # for dessant/lock-threads to lock PRs
|
||||||
|
|||||||
19
.github/workflows/release.yml
vendored
19
.github/workflows/release.yml
vendored
@@ -41,8 +41,8 @@ jobs:
|
|||||||
# Workaround for https://github.com/actions/checkout/issues/882
|
# Workaround for https://github.com/actions/checkout/issues/882
|
||||||
ref: ${{ inputs.version }}
|
ref: ${{ inputs.version }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt install cmake gettext ninja-build python3-pip python3-sphinx
|
run: sudo apt install cmake gettext ninja-build python3-pip
|
||||||
- uses: ./.github/actions/install-sphinx-markdown-builder
|
- uses: ./.github/actions/install-sphinx
|
||||||
- name: Create tarball
|
- name: Create tarball
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
@@ -52,6 +52,9 @@ jobs:
|
|||||||
# Need history since the last release (i.e. tag) for stats.
|
# Need history since the last release (i.e. tag) for stats.
|
||||||
git fetch --tags
|
git fetch --tags
|
||||||
git fetch --unshallow
|
git fetch --unshallow
|
||||||
|
gpg_public_key_url=https://github.com/${{ github.actor }}.gpg
|
||||||
|
curl -sS "$gpg_public_key_url" | grep 'PGP PUBLIC KEY BLOCK' -A5
|
||||||
|
FISH_GPG_PUBLIC_KEY_URL=$gpg_public_key_url \
|
||||||
sh -x ./build_tools/release-notes.sh >"$relnotes"
|
sh -x ./build_tools/release-notes.sh >"$relnotes"
|
||||||
# Delete title
|
# Delete title
|
||||||
sed -n 1p "$relnotes" | grep -q "^## fish .*"
|
sed -n 1p "$relnotes" | grep -q "^## fish .*"
|
||||||
@@ -68,7 +71,7 @@ jobs:
|
|||||||
|
|
||||||
packages-for-linux:
|
packages-for-linux:
|
||||||
needs: [is-release-tag]
|
needs: [is-release-tag]
|
||||||
name: Build single-file fish for Linux (experimental)
|
name: Build single-file fish for Linux
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -80,7 +83,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
targets: x86_64-unknown-linux-musl,aarch64-unknown-linux-musl
|
targets: x86_64-unknown-linux-musl,aarch64-unknown-linux-musl
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt install crossbuild-essential-arm64 gettext musl-tools python3-sphinx
|
run: sudo apt install crossbuild-essential-arm64 gettext musl-tools
|
||||||
|
- uses: ./.github/actions/install-sphinx
|
||||||
- name: Build statically-linked executables
|
- name: Build statically-linked executables
|
||||||
run: |
|
run: |
|
||||||
set -x
|
set -x
|
||||||
@@ -143,15 +147,12 @@ jobs:
|
|||||||
# Workaround for https://github.com/actions/checkout/issues/882
|
# Workaround for https://github.com/actions/checkout/issues/882
|
||||||
ref: ${{ inputs.version }}
|
ref: ${{ inputs.version }}
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: ./.github/actions/rust-toolchain@oldest-supported
|
|
||||||
with:
|
|
||||||
targets: x86_64-apple-darwin
|
|
||||||
- name: Install Rust Stable
|
|
||||||
uses: ./.github/actions/rust-toolchain@stable
|
uses: ./.github/actions/rust-toolchain@stable
|
||||||
with:
|
with:
|
||||||
targets: aarch64-apple-darwin
|
targets: aarch64-apple-darwin,x86_64-apple-darwin
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: brew install gettext
|
run: brew install gettext
|
||||||
|
- uses: ./.github/actions/install-sphinx
|
||||||
- name: Build and codesign
|
- name: Build and codesign
|
||||||
run: |
|
run: |
|
||||||
die() { echo >&2 "$*"; exit 1; }
|
die() { echo >&2 "$*"; exit 1; }
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
name: make fish_run_tests
|
name: Test
|
||||||
|
|
||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
@@ -11,18 +11,17 @@ permissions:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
ubuntu:
|
ubuntu:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/actions/rust-toolchain@oldest-supported
|
- uses: ./.github/actions/rust-toolchain@oldest-supported
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
|
uses: ./.github/actions/install-dependencies
|
||||||
|
with:
|
||||||
|
include_sphinx: true
|
||||||
|
- name: Generate a locale that uses a comma as decimal separator.
|
||||||
run: |
|
run: |
|
||||||
sudo apt install gettext libpcre2-dev python3-pexpect python3-sphinx tmux
|
|
||||||
# Generate a locale that uses a comma as decimal separator.
|
|
||||||
sudo locale-gen fr_FR.UTF-8
|
sudo locale-gen fr_FR.UTF-8
|
||||||
- uses: ./.github/actions/install-sphinx-markdown-builder
|
|
||||||
- name: cmake
|
- name: cmake
|
||||||
run: |
|
run: |
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
@@ -43,18 +42,20 @@ jobs:
|
|||||||
git --no-pager diff --exit-code || { echo 'There are uncommitted changes after regenerating the gettext PO files. Make sure to update them via `build_tools/update_translations.fish` after changing source files.'; exit 1; }
|
git --no-pager diff --exit-code || { echo 'There are uncommitted changes after regenerating the gettext PO files. Make sure to update them via `build_tools/update_translations.fish` after changing source files.'; exit 1; }
|
||||||
|
|
||||||
ubuntu-32bit-static-pcre2:
|
ubuntu-32bit-static-pcre2:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: ./.github/actions/rust-toolchain@oldest-supported
|
- uses: ./.github/actions/rust-toolchain@oldest-supported
|
||||||
with:
|
with:
|
||||||
targets: "i586-unknown-linux-gnu" # rust-toolchain wants this comma-separated
|
targets: "i586-unknown-linux-gnu"
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
|
uses: ./.github/actions/install-dependencies
|
||||||
|
with:
|
||||||
|
include_pcre: false
|
||||||
|
include_sphinx: false
|
||||||
|
- name: Install g++-multilib
|
||||||
run: |
|
run: |
|
||||||
sudo apt update
|
sudo apt install g++-multilib
|
||||||
sudo apt install gettext python3-pexpect g++-multilib tmux
|
|
||||||
- name: cmake
|
- name: cmake
|
||||||
env:
|
env:
|
||||||
CFLAGS: "-m32"
|
CFLAGS: "-m32"
|
||||||
@@ -69,7 +70,6 @@ jobs:
|
|||||||
make -C build VERBOSE=1 fish_run_tests
|
make -C build VERBOSE=1 fish_run_tests
|
||||||
|
|
||||||
ubuntu-asan:
|
ubuntu-asan:
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
# Rust has two different memory sanitizers of interest; they can't be used at the same time:
|
# Rust has two different memory sanitizers of interest; they can't be used at the same time:
|
||||||
@@ -79,7 +79,6 @@ jobs:
|
|||||||
#
|
#
|
||||||
RUSTFLAGS: "-Zsanitizer=address"
|
RUSTFLAGS: "-Zsanitizer=address"
|
||||||
# RUSTFLAGS: "-Zsanitizer=memory -Zsanitizer-memory-track-origins"
|
# RUSTFLAGS: "-Zsanitizer=memory -Zsanitizer-memory-track-origins"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
# All -Z options require running nightly
|
# All -Z options require running nightly
|
||||||
@@ -89,8 +88,11 @@ jobs:
|
|||||||
# this is comma-separated
|
# this is comma-separated
|
||||||
components: rust-src
|
components: rust-src
|
||||||
- name: Install deps
|
- name: Install deps
|
||||||
|
uses: ./.github/actions/install-dependencies
|
||||||
|
with:
|
||||||
|
include_sphinx: false
|
||||||
|
- name: Install llvm
|
||||||
run: |
|
run: |
|
||||||
sudo apt install gettext libpcre2-dev python3-pexpect tmux
|
|
||||||
sudo apt install llvm # for llvm-symbolizer
|
sudo apt install llvm # for llvm-symbolizer
|
||||||
- name: cmake
|
- name: cmake
|
||||||
env:
|
env:
|
||||||
@@ -119,38 +121,8 @@ jobs:
|
|||||||
export LSAN_OPTIONS="$LSAN_OPTIONS:suppressions=$PWD/build_tools/lsan_suppressions.txt"
|
export LSAN_OPTIONS="$LSAN_OPTIONS:suppressions=$PWD/build_tools/lsan_suppressions.txt"
|
||||||
make -C build VERBOSE=1 fish_run_tests
|
make -C build VERBOSE=1 fish_run_tests
|
||||||
|
|
||||||
# Our clang++ tsan builds are not recognizing safe rust patterns (such as the fact that Drop
|
|
||||||
# cannot be called while a thread is using the object in question). Rust has its own way of
|
|
||||||
# running TSAN, but for the duration of the port from C++ to Rust, we'll keep this disabled.
|
|
||||||
|
|
||||||
# ubuntu-threadsan:
|
|
||||||
#
|
|
||||||
# runs-on: ubuntu-latest
|
|
||||||
#
|
|
||||||
# steps:
|
|
||||||
# - uses: actions/checkout@v4
|
|
||||||
# - uses: ./.github/actions/rust-toolchain@oldest-supported
|
|
||||||
# - name: Install deps
|
|
||||||
# run: |
|
|
||||||
# sudo apt install gettext libpcre2-dev python3-pexpect tmux
|
|
||||||
# - name: cmake
|
|
||||||
# env:
|
|
||||||
# FISH_CI_SAN: 1
|
|
||||||
# CC: clang
|
|
||||||
# run: |
|
|
||||||
# mkdir build && cd build
|
|
||||||
# cmake ..
|
|
||||||
# - name: make
|
|
||||||
# run: |
|
|
||||||
# make
|
|
||||||
# - name: make fish_run_tests
|
|
||||||
# run: |
|
|
||||||
# make -C build fish_run_tests
|
|
||||||
|
|
||||||
macos:
|
macos:
|
||||||
|
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
|
|
||||||
env:
|
env:
|
||||||
# macOS runners keep having issues loading Cargo.toml dependencies from git (GitHub) instead
|
# macOS runners keep having issues loading Cargo.toml dependencies from git (GitHub) instead
|
||||||
# of crates.io, so give this a try. It's also sometimes significantly faster on all platforms.
|
# of crates.io, so give this a try. It's also sometimes significantly faster on all platforms.
|
||||||
@@ -164,9 +136,11 @@ jobs:
|
|||||||
# this is CI so we don't actually care.
|
# this is CI so we don't actually care.
|
||||||
sudo pip3 install --break-system-packages pexpect
|
sudo pip3 install --break-system-packages pexpect
|
||||||
brew install gettext tmux
|
brew install gettext tmux
|
||||||
|
- uses: ./.github/actions/install-sphinx
|
||||||
- name: cmake
|
- name: cmake
|
||||||
run: |
|
run: |
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
|
FISH_TEST_MAX_CONCURRENCY=1 \
|
||||||
cmake -DCMAKE_BUILD_TYPE=Debug ..
|
cmake -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
- name: make
|
- name: make
|
||||||
run: |
|
run: |
|
||||||
@@ -174,3 +148,32 @@ jobs:
|
|||||||
- name: make fish_run_tests
|
- name: make fish_run_tests
|
||||||
run: |
|
run: |
|
||||||
make -C build VERBOSE=1 fish_run_tests
|
make -C build VERBOSE=1 fish_run_tests
|
||||||
|
- name: Setup tmate session
|
||||||
|
if: ${{ failure() }}
|
||||||
|
uses: mxschmitt/action-tmate@v3
|
||||||
|
|
||||||
|
windows:
|
||||||
|
runs-on: windows-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: msys2 {0}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: msys2/setup-msys2@v2
|
||||||
|
with:
|
||||||
|
update: true
|
||||||
|
msystem: MSYS
|
||||||
|
- name: Install deps
|
||||||
|
# Not using setup-msys2 `install` option to make it easier to copy/paste
|
||||||
|
run: |
|
||||||
|
pacman --noconfirm -S --needed git rust
|
||||||
|
- name: cargo build
|
||||||
|
run: |
|
||||||
|
cargo build
|
||||||
|
- name: smoketest
|
||||||
|
# We can't run `build_tools/check.sh` yet, there are just too many failures
|
||||||
|
# so this is just a quick check to make sure that fish can swim
|
||||||
|
run: |
|
||||||
|
set -x
|
||||||
|
[ "$(target/debug/fish.exe -c 'echo (math 1 + 1)')" = 2 ]
|
||||||
|
cargo test
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -7,7 +7,6 @@
|
|||||||
*.DS_Store
|
*.DS_Store
|
||||||
*.a
|
*.a
|
||||||
*.app
|
*.app
|
||||||
*.d
|
|
||||||
*.dll
|
*.dll
|
||||||
*.dylib
|
*.dylib
|
||||||
*.exe
|
*.exe
|
||||||
@@ -105,3 +104,6 @@ target/
|
|||||||
|
|
||||||
# JetBrains editors.
|
# JetBrains editors.
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
# AI slop
|
||||||
|
.claude/
|
||||||
|
|||||||
1
.rustfmt.toml
Normal file
1
.rustfmt.toml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
edition = "2024"
|
||||||
@@ -1,16 +1,80 @@
|
|||||||
fish ?.?.? (released ???)
|
fish 4.2.0 (released November 10, 2025)
|
||||||
=========================
|
=======================================
|
||||||
|
|
||||||
fish 4.1.2 (released ???)
|
Notable improvements and fixes
|
||||||
=========================
|
------------------------------
|
||||||
|
- History-based autosuggestions now include multi-line commands.
|
||||||
|
- A :ref:`transient prompt <transient-prompt>` containing more lines than the final prompt will now be cleared properly (:issue:`11875`).
|
||||||
|
- Taiwanese Chinese translations have been added.
|
||||||
|
- French translations have been supplemented (:issue:`11842`).
|
||||||
|
|
||||||
|
Deprecations and removed features
|
||||||
|
---------------------------------
|
||||||
|
- fish now assumes UTF-8 for character encoding even if the system does not have a UTF-8 locale.
|
||||||
|
Input bytes which are not valid UTF-8 are still round-tripped correctly.
|
||||||
|
For example, file paths using legacy encodings can still be used,
|
||||||
|
but may be rendered differently on the command line.
|
||||||
|
- On systems where no multi-byte locale is available,
|
||||||
|
fish will no longer fall back to using ASCII replacements for :ref:`Unicode characters <term-compat-unicode-codepoints>` such as "…".
|
||||||
|
|
||||||
|
Interactive improvements
|
||||||
|
------------------------
|
||||||
|
- The title of the terminal tab can now be set separately from the window title by defining the :doc:`fish_tab_title <cmds/fish_tab_title>` function (:issue:`2692`).
|
||||||
|
- fish now hides the portion of a multiline prompt that is scrolled out of view due to a huge command line. This prevents duplicate lines after repainting with partially visible prompt (:issue:`11911`).
|
||||||
|
- :doc:`fish_config prompt <cmds/fish_config>`'s ``choose`` and ``save`` subcommands have been taught to reset :doc:`fish_mode_prompt <cmds/fish_mode_prompt>` in addition to the other prompt functions (:issue:`11937`).
|
||||||
|
- fish no longer force-disables mouse capture (DECSET/DECRST 1000),
|
||||||
|
so you can use those commands
|
||||||
|
to let mouse clicks move the cursor or select completions items (:issue:`4918`).
|
||||||
|
- The :kbd:`alt-p` binding no longer adds a redundant space to the command line.
|
||||||
|
- When run as a login shell on macOS, fish now sets :envvar:`MANPATH` correctly when that variable was already present in the environment (:issue:`10684`).
|
||||||
|
- A Windows-specific case of the :doc:`web-based config <cmds/fish_config>` failing to launch has been fixed (:issue:`11805`).
|
||||||
|
- A MSYS2-specific workaround for Konsole and WezTerm has been added,
|
||||||
|
to prevent them from using the wrong working directory when opening new tabs (:issue:`11981`).
|
||||||
|
|
||||||
|
For distributors and developers
|
||||||
|
-------------------------------
|
||||||
|
- Release tags and source code tarballs are GPG-signed again (:issue:`11996`).
|
||||||
|
- Documentation in release tarballs is now built with the latest version of Sphinx,
|
||||||
|
which means that pre-built man pages include :ref:`OSC 8 hyperlinks <term-compat-osc-8>`.
|
||||||
|
- The Sphinx dependency is now specified in ``pyproject.toml``,
|
||||||
|
which allows you to use `uv <https://github.com/astral-sh/uv>`__ to provide Sphinx for building documentation (e.g. ``uv run cargo install --path .``).
|
||||||
|
- The minimum supported Rust version (MSRV) has been updated to 1.85.
|
||||||
|
- The standalone build mode has been made the default.
|
||||||
|
This means that the files in ``$CMAKE_INSTALL_PREFIX/share/fish`` will not be used anymore, except for HTML docs.
|
||||||
|
As a result, future upgrades will no longer break running shells
|
||||||
|
if one of fish's internal helper functions has been changed in the updated version.
|
||||||
|
For now, the data files are still installed redundantly,
|
||||||
|
to prevent upgrades from breaking already-running shells (:issue:`11921`).
|
||||||
|
To reverse this change (which should not be necessary),
|
||||||
|
patch out the ``embed-data`` feature from ``cmake/Rust.cmake``.
|
||||||
|
This option will be removed in future.
|
||||||
|
- OpenBSD 7.8 revealed an issue with fish's approach for displaying builtin man pages, which has been fixed.
|
||||||
|
|
||||||
|
Regression fixes:
|
||||||
|
-----------------
|
||||||
|
- (from 4.1.0) Fix the :doc:`web-based config <cmds/fish_config>` for Python 3.9 and older (:issue:`12039`).
|
||||||
|
- (from 4.1.0) Correct wrong terminal modes set by ``fish -c 'read; cat`` (:issue:`12024`).
|
||||||
|
- (from 4.1.0) On VTE-based terminals, stop redrawing the prompt on resize again, to avoid glitches.
|
||||||
|
- (from 4.1.0) On MSYS2, fix saving/loading of universal variables (:issue:`11948`).
|
||||||
|
- (from 4.1.0) Fix error using ``man`` for the commands ``!`` ``.`` ``:`` ``[`` ``{`` (:issue:`11955`).
|
||||||
|
- (from 4.1.0) Fix build issues on illumos systems (:issue:`11982`).
|
||||||
|
- (from 4.1.0) Fix crash on invalid :doc:`function <cmds/function>` command (:issue:`11912`).
|
||||||
|
- (from 4.0.0) Fix build on SPARC and MIPS Linux by disabling ``SIGSTKFLT``.
|
||||||
|
- (from 4.0.0) Fix crash when passing negative PIDs to builtin :doc:`wait <cmds/wait>` (:issue:`11929`).
|
||||||
|
- (from 4.0.0) On Linux, fix :doc:`status fish-path <cmds/status>` output when fish has been reinstalled since it was started.
|
||||||
|
|
||||||
|
fish 4.1.2 (released October 7, 2025)
|
||||||
|
=====================================
|
||||||
|
|
||||||
This release fixes the following regressions identified in 4.1.0:
|
This release fixes the following regressions identified in 4.1.0:
|
||||||
|
|
||||||
- Fixed spurious error output when completing remote file paths for ``scp`` (:issue:`11860`).
|
- Fixed spurious error output when completing remote file paths for ``scp`` (:issue:`11860`).
|
||||||
|
- Fixed the :kbd:`alt-l` binding not formatting ``ls`` output correctly (one entry per line, no colors) (:issue:`11888`).
|
||||||
- Fixed an issue where focus events (currently only enabled in ``tmux``) would cause multiline prompts to be redrawn in the wrong line (:issue:`11870`).
|
- Fixed an issue where focus events (currently only enabled in ``tmux``) would cause multiline prompts to be redrawn in the wrong line (:issue:`11870`).
|
||||||
- Stopped printing output that would cause a glitch on old versions of Midnight Commander (:issue:`11869`).
|
- Stopped printing output that would cause a glitch on old versions of Midnight Commander (:issue:`11869`).
|
||||||
- Added a workaround for old versions of Zellij where :kbd:`escape` processing was delayed (:issue:`11868`).
|
- Added a fix for some configurations of Zellij where :kbd:`escape` key processing was delayed (:issue:`11868`).
|
||||||
- Fixed a case where the :doc:`web-based configuration tool <cmds/fish_config>` would generate invalid configuration (:issue:`11861`).
|
- Fixed a case where the :doc:`web-based configuration tool <cmds/fish_config>` would generate invalid configuration (:issue:`11861`).
|
||||||
|
- Fixed a case where pasting into ``fish -c read`` would fail with a noisy error (:issue:`11836`).
|
||||||
- Fixed a case where upgrading fish would break old versions of fish that were still running.
|
- Fixed a case where upgrading fish would break old versions of fish that were still running.
|
||||||
|
|
||||||
In general, fish still needs to be restarted after it is upgraded,
|
In general, fish still needs to be restarted after it is upgraded,
|
||||||
@@ -859,7 +923,7 @@ Notable improvements and fixes
|
|||||||
|
|
||||||
which expands ``!!`` to the last history item, anywhere on the command line, mimicking other shells' history expansion.
|
which expands ``!!`` to the last history item, anywhere on the command line, mimicking other shells' history expansion.
|
||||||
|
|
||||||
See :ref:`the documentation <cmd-abbr>` for more.
|
See :doc:`the documentation <cmds/abbr>` for more.
|
||||||
- ``path`` gained a new ``mtime`` subcommand to print the modification time stamp for files. For example, this can be used to handle cache file ages (:issue:`9057`)::
|
- ``path`` gained a new ``mtime`` subcommand to print the modification time stamp for files. For example, this can be used to handle cache file ages (:issue:`9057`)::
|
||||||
|
|
||||||
> touch foo
|
> touch foo
|
||||||
@@ -1284,7 +1348,7 @@ Scripting improvements
|
|||||||
two
|
two
|
||||||
'blue '
|
'blue '
|
||||||
|
|
||||||
- ``$fish_user_paths`` is now automatically deduplicated to fix a common user error of appending to it in config.fish when it is universal (:issue:`8117`). :ref:`fish_add_path <cmd-fish_add_path>` remains the recommended way to add to $PATH.
|
- ``$fish_user_paths`` is now automatically deduplicated to fix a common user error of appending to it in config.fish when it is universal (:issue:`8117`). :doc:`fish_add_path <cmds/fish_add_path>` remains the recommended way to add to $PATH.
|
||||||
- ``return`` can now be used outside functions. In scripts, it does the same thing as ``exit``. In interactive mode,it sets ``$status`` without exiting (:issue:`8148`).
|
- ``return`` can now be used outside functions. In scripts, it does the same thing as ``exit``. In interactive mode,it sets ``$status`` without exiting (:issue:`8148`).
|
||||||
- An oversight prevented all syntax checks from running on commands given to ``fish -c`` (:issue:`8171`). This includes checks such as ``exec`` not being allowed in a pipeline, and ``$$`` not being a valid variable. Generally, another error was generated anyway.
|
- An oversight prevented all syntax checks from running on commands given to ``fish -c`` (:issue:`8171`). This includes checks such as ``exec`` not being allowed in a pipeline, and ``$$`` not being a valid variable. Generally, another error was generated anyway.
|
||||||
- ``fish_indent`` now correctly reformats tokens that end with a backslash followed by a newline (:issue:`8197`).
|
- ``fish_indent`` now correctly reformats tokens that end with a backslash followed by a newline (:issue:`8197`).
|
||||||
|
|||||||
@@ -28,6 +28,24 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
|
|||||||
# This defines the FBVF variable.
|
# This defines the FBVF variable.
|
||||||
include(Version)
|
include(Version)
|
||||||
|
|
||||||
|
# Set up the docs.
|
||||||
|
include(cmake/Docs.cmake)
|
||||||
|
|
||||||
|
# Tell Cargo where our build directory is so it can find Cargo.toml.
|
||||||
|
set(VARS_FOR_CARGO
|
||||||
|
"FISH_CMAKE_BINARY_DIR=${CMAKE_BINARY_DIR}"
|
||||||
|
"PREFIX=${CMAKE_INSTALL_PREFIX}"
|
||||||
|
"DOCDIR=${CMAKE_INSTALL_FULL_DOCDIR}"
|
||||||
|
"DATADIR=${CMAKE_INSTALL_FULL_DATADIR}"
|
||||||
|
"SYSCONFDIR=${CMAKE_INSTALL_FULL_SYSCONFDIR}"
|
||||||
|
"BINDIR=${CMAKE_INSTALL_FULL_BINDIR}"
|
||||||
|
"CARGO_TARGET_DIR=${FISH_RUST_BUILD_DIR}"
|
||||||
|
"CARGO_BUILD_RUSTC=${Rust_COMPILER}"
|
||||||
|
"${FISH_PCRE2_BUILDFLAG}"
|
||||||
|
"RUSTFLAGS=$ENV{RUSTFLAGS} ${rust_debugflags}"
|
||||||
|
"FISH_SPHINX=${SPHINX_EXECUTABLE}"
|
||||||
|
)
|
||||||
|
|
||||||
# Let fish pick up when we're running out of the build directory without installing
|
# Let fish pick up when we're running out of the build directory without installing
|
||||||
get_filename_component(REAL_CMAKE_BINARY_DIR "${CMAKE_BINARY_DIR}" REALPATH)
|
get_filename_component(REAL_CMAKE_BINARY_DIR "${CMAKE_BINARY_DIR}" REALPATH)
|
||||||
get_filename_component(REAL_CMAKE_SOURCE_DIR "${CMAKE_SOURCE_DIR}" REALPATH)
|
get_filename_component(REAL_CMAKE_SOURCE_DIR "${CMAKE_SOURCE_DIR}" REALPATH)
|
||||||
@@ -71,9 +89,6 @@ create_target(fish_indent)
|
|||||||
# Define fish_key_reader.
|
# Define fish_key_reader.
|
||||||
create_target(fish_key_reader)
|
create_target(fish_key_reader)
|
||||||
|
|
||||||
# Set up the docs.
|
|
||||||
include(cmake/Docs.cmake)
|
|
||||||
|
|
||||||
# Set up tests.
|
# Set up tests.
|
||||||
include(cmake/Tests.cmake)
|
include(cmake/Tests.cmake)
|
||||||
|
|
||||||
|
|||||||
126
CONTRIBUTING.rst
126
CONTRIBUTING.rst
@@ -71,7 +71,7 @@ Completion scripts should
|
|||||||
|
|
||||||
1. Use as few dependencies as possible - try to use fish's builtins like ``string`` instead of ``grep`` and ``awk``,
|
1. Use as few dependencies as possible - try to use fish's builtins like ``string`` instead of ``grep`` and ``awk``,
|
||||||
use ``python`` to read json instead of ``jq`` (because it's already a soft dependency for fish's tools)
|
use ``python`` to read json instead of ``jq`` (because it's already a soft dependency for fish's tools)
|
||||||
2. If it uses a common unix tool, use posix-compatible invocations - ideally it would work on GNU/Linux, macOS, the BSDs and other systems
|
2. If it uses a common unix tool, use POSIX-compatible invocations - ideally it would work on GNU/Linux, macOS, the BSDs and other systems
|
||||||
3. Option and argument descriptions should be kept short.
|
3. Option and argument descriptions should be kept short.
|
||||||
The shorter the description, the more likely it is that fish can use more columns.
|
The shorter the description, the more likely it is that fish can use more columns.
|
||||||
4. Function names should start with ``__fish``, and functions should be kept in the completion file unless they're used elsewhere.
|
4. Function names should start with ``__fish``, and functions should be kept in the completion file unless they're used elsewhere.
|
||||||
@@ -100,33 +100,18 @@ The builtins and various functions shipped with fish are documented in doc_src/c
|
|||||||
Code Style
|
Code Style
|
||||||
==========
|
==========
|
||||||
|
|
||||||
To ensure your changes conform to the style rules run
|
For formatting, we use:
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
build_tools/style.fish
|
|
||||||
|
|
||||||
before committing your change. That will run our autoformatters:
|
|
||||||
|
|
||||||
- ``rustfmt`` for Rust
|
- ``rustfmt`` for Rust
|
||||||
- ``fish_indent`` (shipped with fish) for fish script
|
- ``fish_indent`` (shipped with fish) for fish script
|
||||||
- ``black`` for python
|
- ``ruff format`` for Python
|
||||||
|
|
||||||
If you’ve already committed your changes that’s okay since it will then
|
To reformat files, there is a script
|
||||||
check the files in the most recent commit. This can be useful after
|
|
||||||
you’ve merged another person’s change and want to check that it’s style
|
|
||||||
is acceptable. However, in that case it will run ``clang-format`` to
|
|
||||||
ensure the entire file, not just the lines modified by the commit,
|
|
||||||
conform to the style.
|
|
||||||
|
|
||||||
If you want to check the style of the entire code base run
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
build_tools/style.fish --all
|
build_tools/style.fish --all
|
||||||
|
build_tools/style.fish somefile.rs some.fish
|
||||||
That command will refuse to restyle any files if you have uncommitted
|
|
||||||
changes.
|
|
||||||
|
|
||||||
Fish Script Style Guide
|
Fish Script Style Guide
|
||||||
-----------------------
|
-----------------------
|
||||||
@@ -178,10 +163,10 @@ made to run fish_indent via e.g.
|
|||||||
(add-hook 'fish-mode-hook (lambda ()
|
(add-hook 'fish-mode-hook (lambda ()
|
||||||
(add-hook 'before-save-hook 'fish_indent-before-save)))
|
(add-hook 'before-save-hook 'fish_indent-before-save)))
|
||||||
|
|
||||||
Rust Style Guide
|
Minimum Supported Rust Version (MSRV) Policy
|
||||||
----------------
|
--------------------------------------------
|
||||||
|
|
||||||
Use ``cargo fmt`` and ``cargo clippy``. Clippy warnings can be turned off if there's a good reason to.
|
We support at least the version of ``rustc`` available in Debian Stable.
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
=======
|
=======
|
||||||
@@ -196,78 +181,47 @@ You are strongly encouraged to add tests when changing the functionality
|
|||||||
of fish, especially if you are fixing a bug to help ensure there are no
|
of fish, especially if you are fixing a bug to help ensure there are no
|
||||||
regressions in the future (i.e., we don’t reintroduce the bug).
|
regressions in the future (i.e., we don’t reintroduce the bug).
|
||||||
|
|
||||||
The tests can be found in three places:
|
Unit tests live next to the implementation in Rust source files, in inline submodules (``mod tests {}``).
|
||||||
|
|
||||||
- src/tests for unit tests.
|
System tests live in ``tests/``:
|
||||||
- tests/checks for script tests, run by `littlecheck <https://github.com/ridiculousfish/littlecheck>`__
|
|
||||||
- tests/pexpects for interactive tests using `pexpect <https://pexpect.readthedocs.io/en/stable/>`__
|
|
||||||
|
|
||||||
When in doubt, the bulk of the tests should be added as a littlecheck test in tests/checks, as they are the easiest to modify and run, and much faster and more dependable than pexpect tests. The syntax is fairly self-explanatory. It's a fish script with the expected output in ``# CHECK:`` or ``# CHECKERR:`` (for stderr) comments.
|
- ``tests/checks`` are run by `littlecheck <https://github.com/ridiculousfish/littlecheck>`__
|
||||||
If your littlecheck test has a specific dependency, use ``# REQUIRE: ...`` with a posix sh script.
|
and test noninteractive (script) behavior,
|
||||||
|
except for ``tests/checks/tmux-*`` which test interactive scenarios.
|
||||||
|
- ``tests/pexpects`` tests interactive scenarios using `pexpect <https://pexpect.readthedocs.io/en/stable/>`__
|
||||||
|
|
||||||
The pexpects are written in python and can simulate input and output to/from a terminal, so they are needed for anything that needs actual interactivity. The runner is in tests/pexpect_helper.py, in case you need to modify something there.
|
When in doubt, the bulk of the tests should be added as a littlecheck test in tests/checks, as they are the easiest to modify and run, and much faster and more dependable than pexpect tests.
|
||||||
|
The syntax is fairly self-explanatory.
|
||||||
|
It's a fish script with the expected output in ``# CHECK:`` or ``# CHECKERR:`` (for stderr) comments.
|
||||||
|
If your littlecheck test has a specific dependency, use ``# REQUIRE: ...`` with a POSIX sh script.
|
||||||
|
|
||||||
These tests can be run via the tests/test_driver.py python script, which will set up the environment.
|
The pexpect tests are written in Python and can simulate input and output to/from a terminal, so they are needed for anything that needs actual interactivity.
|
||||||
|
The runner is in tests/pexpect_helper.py, in case you need to modify something there.
|
||||||
|
|
||||||
|
These tests can be run via the tests/test_driver.py Python script, which will set up the environment.
|
||||||
It sets up a temporary $HOME and also uses it as the current directory, so you do not need to create a temporary directory in them.
|
It sets up a temporary $HOME and also uses it as the current directory, so you do not need to create a temporary directory in them.
|
||||||
|
|
||||||
If you need a command to do something weird to test something, maybe add it to the ``fish_test_helper`` binary (in tests/fish_test_helper.c), or see if it can already do it.
|
If you need a command to do something weird to test something, maybe add it to the ``fish_test_helper`` binary (in ``tests/fish_test_helper.c``).
|
||||||
|
|
||||||
Local testing
|
Local testing
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
The tests can be run on your local computer on all operating systems.
|
The tests can be run on your local system::
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
cmake path/to/fish-shell
|
|
||||||
make fish_run_tests
|
|
||||||
|
|
||||||
Or you can run them on a fish, without involving cmake::
|
|
||||||
|
|
||||||
cargo build
|
cargo build
|
||||||
cargo test # for the unit tests
|
# Run unit tests
|
||||||
tests/test_driver.py target/debug # for the script and interactive tests
|
cargo test
|
||||||
|
# Run system tests
|
||||||
|
tests/test_driver.py target/debug
|
||||||
|
# Run a specific system test.
|
||||||
|
tests/test_driver.py target/debug tests/checks/abbr.fish
|
||||||
|
|
||||||
Here, the first argument to test_driver.py refers to a directory with ``fish``, ``fish_indent`` and ``fish_key_reader`` in it.
|
Here, the first argument to test_driver.py refers to a directory with ``fish``, ``fish_indent`` and ``fish_key_reader`` in it.
|
||||||
In this example we're in the root of the git repo and have run ``cargo build`` without ``--release``, so it's a debug build.
|
In this example we're in the root of the workspace and have run ``cargo build`` without ``--release``, so it's a debug build.
|
||||||
|
|
||||||
Git hooks
|
To run all tests and linters, use::
|
||||||
---------
|
|
||||||
|
|
||||||
Since developers sometimes forget to run the tests, it can be helpful to
|
|
||||||
use git hooks (see githooks(5)) to automate it.
|
|
||||||
|
|
||||||
One possibility is a pre-push hook script like this one:
|
|
||||||
|
|
||||||
.. code:: sh
|
|
||||||
|
|
||||||
#!/bin/sh
|
|
||||||
#### A pre-push hook for the fish-shell project
|
|
||||||
# This will run the tests when a push to master is detected, and will stop that if the tests fail
|
|
||||||
# Save this as .git/hooks/pre-push and make it executable
|
|
||||||
|
|
||||||
protected_branch='master'
|
|
||||||
|
|
||||||
# Git gives us lines like "refs/heads/frombranch SOMESHA1 refs/heads/tobranch SOMESHA1"
|
|
||||||
# We're only interested in the branches
|
|
||||||
isprotected=false
|
|
||||||
while read from _ to _; do
|
|
||||||
if [ "$to" = "refs/heads/$protected_branch" ]; then
|
|
||||||
isprotected=true
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if "$isprotected"; then
|
|
||||||
echo "Running checks before push to master"
|
|
||||||
build_tools/check.sh
|
build_tools/check.sh
|
||||||
fi
|
|
||||||
|
|
||||||
This will check if the push is to the master branch and, if it is, only
|
|
||||||
allow the push if running ``build_tools/check.sh`` succeeds. In some circumstances
|
|
||||||
it may be advisable to circumvent this check with
|
|
||||||
``git push --no-verify``, but usually that isn’t necessary.
|
|
||||||
|
|
||||||
To install the hook, place the code in a new file
|
|
||||||
``.git/hooks/pre-push`` and make it executable.
|
|
||||||
|
|
||||||
Contributing Translations
|
Contributing Translations
|
||||||
=========================
|
=========================
|
||||||
@@ -343,7 +297,7 @@ command-line and graphical user interface programs. For simple use, you can use
|
|||||||
|
|
||||||
Open up the PO file, for example ``po/sv.po``, and you'll see something like::
|
Open up the PO file, for example ``po/sv.po``, and you'll see something like::
|
||||||
|
|
||||||
msgid "%ls: No suitable job\n"
|
msgid "%s: No suitable job\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
The ``msgid`` here is the "name" of the string to translate, typically the English string to translate.
|
The ``msgid`` here is the "name" of the string to translate, typically the English string to translate.
|
||||||
@@ -351,10 +305,10 @@ The second line (``msgstr``) is where your translation goes.
|
|||||||
|
|
||||||
For example::
|
For example::
|
||||||
|
|
||||||
msgid "%ls: No suitable job\n"
|
msgid "%s: No suitable job\n"
|
||||||
msgstr "%ls: Inget passande jobb\n"
|
msgstr "%s: Inget passande jobb\n"
|
||||||
|
|
||||||
Any ``%s`` / ``%ls`` or ``%d`` are placeholders that fish will use for formatting at runtime. It is important that they match - the translated string should have the same placeholders in the same order.
|
Any ``%s`` or ``%d`` are placeholders that fish will use for formatting at runtime. It is important that they match - the translated string should have the same placeholders in the same order.
|
||||||
|
|
||||||
Also any escaped characters, like that ``\n`` newline at the end, should be kept so the translation has the same behavior.
|
Also any escaped characters, like that ``\n`` newline at the end, should be kept so the translation has the same behavior.
|
||||||
|
|
||||||
@@ -381,7 +335,7 @@ macros:
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
streams.out.append(wgettext_fmt!("%ls: There are no jobs\n", argv[0]));
|
streams.out.append(wgettext_fmt!("%s: There are no jobs\n", argv[0]));
|
||||||
|
|
||||||
All messages in fish script must be enclosed in single or double quote
|
All messages in fish script must be enclosed in single or double quote
|
||||||
characters for our message extraction script to find them.
|
characters for our message extraction script to find them.
|
||||||
@@ -404,6 +358,12 @@ You can use either single or double quotes to enclose the
|
|||||||
message to be translated. You can also optionally include spaces after
|
message to be translated. You can also optionally include spaces after
|
||||||
the opening parentheses or before the closing parentheses.
|
the opening parentheses or before the closing parentheses.
|
||||||
|
|
||||||
|
Updating Dependencies
|
||||||
|
=====================
|
||||||
|
|
||||||
|
To update dependencies, run ``build_tools/update-dependencies.sh``.
|
||||||
|
This currently requires `updatecli <https://github.com/updatecli/updatecli>`__ and a few other tools.
|
||||||
|
|
||||||
Versioning
|
Versioning
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
|||||||
455
Cargo.lock
generated
455
Cargo.lock
generated
@@ -1,6 +1,15 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "allocator-api2"
|
name = "allocator-api2"
|
||||||
@@ -10,15 +19,15 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.4.0"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.6.0"
|
version = "2.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
@@ -30,11 +39,22 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "bstr"
|
||||||
version = "1.2.7"
|
version = "1.12.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7"
|
checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.2.41"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7"
|
||||||
|
dependencies = [
|
||||||
|
"find-msvc-tools",
|
||||||
"jobserver",
|
"jobserver",
|
||||||
"libc",
|
"libc",
|
||||||
"shlex",
|
"shlex",
|
||||||
@@ -42,9 +62,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg_aliases"
|
name = "cfg_aliases"
|
||||||
@@ -54,9 +74,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.16"
|
version = "0.2.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3"
|
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
@@ -82,16 +102,37 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "dirs"
|
||||||
version = "1.0.1"
|
version = "6.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
|
||||||
|
dependencies = [
|
||||||
|
"dirs-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dirs-sys"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"option-ext",
|
||||||
|
"redox_users",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
version = "0.3.11"
|
version = "0.3.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
|
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
@@ -103,12 +144,19 @@ version = "2.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "find-msvc-tools"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fish"
|
name = "fish"
|
||||||
version = "4.1.0-snapshot"
|
version = "4.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"cc",
|
"cc",
|
||||||
|
"cfg-if",
|
||||||
"errno",
|
"errno",
|
||||||
"fish-build-helper",
|
"fish-build-helper",
|
||||||
"fish-build-man-pages",
|
"fish-build-man-pages",
|
||||||
@@ -116,6 +164,7 @@ dependencies = [
|
|||||||
"fish-gettext-maps",
|
"fish-gettext-maps",
|
||||||
"fish-gettext-mo-file-parser",
|
"fish-gettext-mo-file-parser",
|
||||||
"fish-printf",
|
"fish-printf",
|
||||||
|
"fish-tempfile",
|
||||||
"libc",
|
"libc",
|
||||||
"lru",
|
"lru",
|
||||||
"macro_rules_attribute",
|
"macro_rules_attribute",
|
||||||
@@ -182,6 +231,13 @@ dependencies = [
|
|||||||
"widestring",
|
"widestring",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fish-tempfile"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"nix",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@@ -190,25 +246,61 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foldhash"
|
name = "foldhash"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
version = "0.14.7"
|
version = "0.14.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "getrandom"
|
||||||
version = "0.15.2"
|
version = "0.2.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"wasi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"r-efi",
|
||||||
|
"wasip2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "globset"
|
||||||
|
version = "0.4.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"bstr",
|
||||||
|
"log",
|
||||||
|
"regex-automata",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.15.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"allocator-api2",
|
"allocator-api2",
|
||||||
"equivalent",
|
"equivalent",
|
||||||
@@ -217,34 +309,44 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jobserver"
|
name = "jobserver"
|
||||||
version = "0.1.32"
|
version = "0.1.34"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
|
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"getrandom 0.3.4",
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.172"
|
version = "0.2.177"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libredox"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.12"
|
version = "0.4.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.22"
|
version = "0.4.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lru"
|
name = "lru"
|
||||||
@@ -273,9 +375,9 @@ checksum = "670fdfda89751bc4a84ac13eaa63e205cf0fd22b4c9a5fbfa085b63c1f1d3a30"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.7.4"
|
version = "2.7.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minimal-lexical"
|
name = "minimal-lexical"
|
||||||
@@ -316,15 +418,21 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.20.2"
|
version = "1.21.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "option-ext"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.12.3"
|
version = "0.12.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lock_api",
|
"lock_api",
|
||||||
"parking_lot_core",
|
"parking_lot_core",
|
||||||
@@ -332,15 +440,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot_core"
|
name = "parking_lot_core"
|
||||||
version = "0.9.10"
|
version = "0.9.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows-targets",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -447,34 +555,40 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkg-config"
|
name = "pkg-config"
|
||||||
version = "0.3.31"
|
version = "0.3.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "portable-atomic"
|
name = "portable-atomic"
|
||||||
version = "1.10.0"
|
version = "1.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6"
|
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.95"
|
version = "1.0.101"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.40"
|
version = "1.0.41"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "r-efi"
|
||||||
|
version = "5.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
@@ -492,13 +606,41 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.5.8"
|
version = "0.5.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
|
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_users"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.16",
|
||||||
|
"libredox",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rsconf"
|
name = "rsconf"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
@@ -510,9 +652,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-embed"
|
name = "rust-embed"
|
||||||
version = "8.7.2"
|
version = "8.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "025908b8682a26ba8d12f6f2d66b987584a4a87bc024abc5bbc12553a8cd178a"
|
checksum = "fb44e1917075637ee8c7bcb865cf8830e3a92b5b1189e44e3a0ab5a0d5be314b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rust-embed-impl",
|
"rust-embed-impl",
|
||||||
"rust-embed-utils",
|
"rust-embed-utils",
|
||||||
@@ -521,23 +663,25 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-embed-impl"
|
name = "rust-embed-impl"
|
||||||
version = "8.7.2"
|
version = "8.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6065f1a4392b71819ec1ea1df1120673418bf386f50de1d6f54204d836d4349c"
|
checksum = "382499b49db77a7c19abd2a574f85ada7e9dbe125d5d1160fa5cad7c4cf71fc9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rust-embed-utils",
|
"rust-embed-utils",
|
||||||
|
"shellexpand",
|
||||||
"syn",
|
"syn",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-embed-utils"
|
name = "rust-embed-utils"
|
||||||
version = "8.7.2"
|
version = "8.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f6cc0c81648b20b70c491ff8cce00c1c3b223bb8ed2b5d41f0e54c6c4c0a3594"
|
checksum = "21fcbee55c2458836bcdbfffb6ec9ba74bbc23ca7aa6816015a3dd2c4d8fc185"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"globset",
|
||||||
"sha2",
|
"sha2",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
@@ -553,9 +697,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scc"
|
name = "scc"
|
||||||
version = "2.3.0"
|
version = "2.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28e1c91382686d21b5ac7959341fcb9780fa7c03773646995a87c950fa7be640"
|
checksum = "46e6f046b7fef48e2660c57ed794263155d713de679057f2d0c169bfc6e756cc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"sdd",
|
"sdd",
|
||||||
]
|
]
|
||||||
@@ -568,9 +712,38 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sdd"
|
name = "sdd"
|
||||||
version = "3.0.5"
|
version = "3.0.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "478f121bb72bbf63c52c93011ea1791dca40140dfe13f8336c4c5ac952c33aa9"
|
checksum = "490dcfcbfef26be6800d11870ff2df8774fa6e86d047e3e8c8a76b25655e41ca"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.228"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||||
|
dependencies = [
|
||||||
|
"serde_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_core"
|
||||||
|
version = "1.0.228"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.228"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serial_test"
|
name = "serial_test"
|
||||||
@@ -597,15 +770,24 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha2"
|
name = "sha2"
|
||||||
version = "0.10.8"
|
version = "0.10.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
|
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures",
|
||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shellexpand"
|
||||||
|
version = "3.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b1fdf65dd6331831494dd616b30351c38e96e45921a27745cf98490458b90bb"
|
||||||
|
dependencies = [
|
||||||
|
"dirs",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@@ -620,15 +802,15 @@ checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.13.2"
|
version = "1.15.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.95"
|
version = "2.0.107"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a"
|
checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -648,16 +830,36 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "thiserror"
|
||||||
version = "1.17.0"
|
version = "2.0.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "2.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.14"
|
version = "1.0.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-segmentation"
|
name = "unicode-segmentation"
|
||||||
@@ -667,9 +869,9 @@ checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-width"
|
name = "unicode-width"
|
||||||
version = "0.2.0"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
|
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unix_path"
|
name = "unix_path"
|
||||||
@@ -703,89 +905,52 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "widestring"
|
name = "wasi"
|
||||||
version = "1.2.0"
|
version = "0.11.1+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d"
|
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasip2"
|
||||||
|
version = "1.0.1+wasi-0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
|
||||||
|
dependencies = [
|
||||||
|
"wit-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "widestring"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-util"
|
name = "winapi-util"
|
||||||
version = "0.1.9"
|
version = "0.1.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-link"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.59.0"
|
version = "0.61.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-targets"
|
name = "wit-bindgen"
|
||||||
version = "0.52.6"
|
version = "0.46.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm",
|
|
||||||
"windows_aarch64_msvc",
|
|
||||||
"windows_i686_gnu",
|
|
||||||
"windows_i686_gnullvm",
|
|
||||||
"windows_i686_msvc",
|
|
||||||
"windows_x86_64_gnu",
|
|
||||||
"windows_x86_64_gnullvm",
|
|
||||||
"windows_x86_64_msvc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_gnullvm"
|
|
||||||
version = "0.52.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.52.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.52.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnullvm"
|
|
||||||
version = "0.52.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.52.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.52.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.52.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.52.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
|
||||||
|
|||||||
40
Cargo.toml
40
Cargo.toml
@@ -1,16 +1,16 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
resolver = "2"
|
|
||||||
members = ["crates/*"]
|
members = ["crates/*"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
# To build revisions that use Corrosion (those before 2024-01), use CMake 3.19, Rustc 1.78 and Rustup 1.27.
|
# To build revisions that use Corrosion (those before 2024-01), use CMake 3.19, Rustc 1.78 and Rustup 1.27.
|
||||||
rust-version = "1.70"
|
rust-version = "1.85"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
repository = "https://github.com/fish-shell/fish-shell"
|
repository = "https://github.com/fish-shell/fish-shell"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
bitflags = "2.5.0"
|
bitflags = "2.5.0"
|
||||||
cc = "1.0.94"
|
cc = "1.0.94"
|
||||||
|
cfg-if = "1.0.3"
|
||||||
errno = "0.3.0"
|
errno = "0.3.0"
|
||||||
fish-build-helper = { path = "crates/build-helper" }
|
fish-build-helper = { path = "crates/build-helper" }
|
||||||
fish-build-man-pages = { path = "crates/build-man-pages" }
|
fish-build-man-pages = { path = "crates/build-man-pages" }
|
||||||
@@ -18,7 +18,8 @@ fish-gettext-extraction = { path = "crates/gettext-extraction" }
|
|||||||
fish-gettext-maps = { path = "crates/gettext-maps" }
|
fish-gettext-maps = { path = "crates/gettext-maps" }
|
||||||
fish-gettext-mo-file-parser = { path = "crates/gettext-mo-file-parser" }
|
fish-gettext-mo-file-parser = { path = "crates/gettext-mo-file-parser" }
|
||||||
fish-printf = { path = "crates/printf", features = ["widestring"] }
|
fish-printf = { path = "crates/printf", features = ["widestring"] }
|
||||||
libc = "0.2.155"
|
fish-tempfile = { path = "crates/tempfile" }
|
||||||
|
libc = "0.2.177"
|
||||||
# lru pulls in hashbrown by default, which uses a faster (though less DoS resistant) hashing algo.
|
# lru pulls in hashbrown by default, which uses a faster (though less DoS resistant) hashing algo.
|
||||||
# disabling default features uses the stdlib instead, but it doubles the time to rewrite the history
|
# disabling default features uses the stdlib instead, but it doubles the time to rewrite the history
|
||||||
# files as of 22 April 2024.
|
# files as of 22 April 2024.
|
||||||
@@ -45,7 +46,12 @@ proc-macro2 = "1.0"
|
|||||||
# minimum supported version to 10.12.
|
# minimum supported version to 10.12.
|
||||||
rand = { version = "0.8.5", default-features = false, features = ["small_rng"] }
|
rand = { version = "0.8.5", default-features = false, features = ["small_rng"] }
|
||||||
rsconf = "0.2.2"
|
rsconf = "0.2.2"
|
||||||
rust-embed = { version = "8.7.2", features = ["deterministic-timestamps"] }
|
rust-embed = { version = "8.7.2", features = [
|
||||||
|
"deterministic-timestamps",
|
||||||
|
"include-exclude",
|
||||||
|
"interpolate-folder-path",
|
||||||
|
] }
|
||||||
|
|
||||||
serial_test = { version = "3", default-features = false }
|
serial_test = { version = "3", default-features = false }
|
||||||
# We need 0.9.0 specifically for some crash fixes.
|
# We need 0.9.0 specifically for some crash fixes.
|
||||||
terminfo = "0.9.0"
|
terminfo = "0.9.0"
|
||||||
@@ -64,7 +70,7 @@ debug = true
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "fish"
|
name = "fish"
|
||||||
version = "4.1.0-snapshot"
|
version = "4.2.0"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
default-run = "fish"
|
default-run = "fish"
|
||||||
@@ -76,12 +82,14 @@ readme = "README.rst"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags.workspace = true
|
bitflags.workspace = true
|
||||||
|
cfg-if.workspace = true
|
||||||
errno.workspace = true
|
errno.workspace = true
|
||||||
fish-build-helper.workspace = true
|
fish-build-helper.workspace = true
|
||||||
fish-build-man-pages = { workspace = true, optional = true }
|
fish-build-man-pages = { workspace = true, optional = true }
|
||||||
fish-gettext-extraction = { workspace = true, optional = true }
|
fish-gettext-extraction = { workspace = true, optional = true }
|
||||||
fish-gettext-maps = { workspace = true, optional = true }
|
fish-gettext-maps = { workspace = true, optional = true }
|
||||||
fish-printf.workspace = true
|
fish-printf.workspace = true
|
||||||
|
fish-tempfile.workspace = true
|
||||||
libc.workspace = true
|
libc.workspace = true
|
||||||
lru.workspace = true
|
lru.workspace = true
|
||||||
macro_rules_attribute = "0.2.2"
|
macro_rules_attribute = "0.2.2"
|
||||||
@@ -98,9 +106,18 @@ widestring.workspace = true
|
|||||||
portable-atomic.workspace = true
|
portable-atomic.workspace = true
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
rust-embed = { workspace = true, optional = true, features = ["deterministic-timestamps", "debug-embed"] }
|
rust-embed = { workspace = true, optional = true, features = [
|
||||||
|
"deterministic-timestamps",
|
||||||
|
"debug-embed",
|
||||||
|
"include-exclude",
|
||||||
|
"interpolate-folder-path",
|
||||||
|
] }
|
||||||
[target.'cfg(not(windows))'.dependencies]
|
[target.'cfg(not(windows))'.dependencies]
|
||||||
rust-embed = { workspace = true, optional = true, features = ["deterministic-timestamps"] }
|
rust-embed = { workspace = true, optional = true, features = [
|
||||||
|
"deterministic-timestamps",
|
||||||
|
"include-exclude",
|
||||||
|
"interpolate-folder-path",
|
||||||
|
] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serial_test.workspace = true
|
serial_test.workspace = true
|
||||||
@@ -153,9 +170,14 @@ rust.non_camel_case_types = "allow"
|
|||||||
rust.non_upper_case_globals = "allow"
|
rust.non_upper_case_globals = "allow"
|
||||||
rust.unknown_lints = "allow"
|
rust.unknown_lints = "allow"
|
||||||
rust.unstable_name_collisions = "allow"
|
rust.unstable_name_collisions = "allow"
|
||||||
|
rustdoc.private_intra_doc_links = "allow"
|
||||||
|
clippy.len_without_is_empty = "allow" # we're not a library crate
|
||||||
|
clippy.let_and_return = "allow"
|
||||||
clippy.manual_range_contains = "allow"
|
clippy.manual_range_contains = "allow"
|
||||||
clippy.needless_return = "allow"
|
|
||||||
clippy.needless_lifetimes = "allow"
|
clippy.needless_lifetimes = "allow"
|
||||||
|
clippy.needless_return = "allow"
|
||||||
|
clippy.new_without_default = "allow"
|
||||||
|
clippy.option_map_unit_fn = "allow"
|
||||||
|
|
||||||
# We do not want to use the e?print(ln)?! macros.
|
# We do not want to use the e?print(ln)?! macros.
|
||||||
# These lints flag their use.
|
# These lints flag their use.
|
||||||
|
|||||||
52
README.rst
52
README.rst
@@ -90,7 +90,7 @@ Running fish requires:
|
|||||||
|
|
||||||
- some common \*nix system utilities (currently ``mktemp``), in
|
- some common \*nix system utilities (currently ``mktemp``), in
|
||||||
addition to the basic POSIX utilities (``cat``, ``cut``, ``dirname``,
|
addition to the basic POSIX utilities (``cat``, ``cut``, ``dirname``,
|
||||||
``file``, ``ls``, ``mkdir``, ``mkfifo``, ``rm``, ``sh``, ``sort``, ``tee``, ``tr``,
|
``ls``, ``mkdir``, ``mkfifo``, ``rm``, ``sh``, ``sort``, ``tee``, ``tr``,
|
||||||
``uname`` and ``sed`` at least, but the full coreutils plus ``find`` and
|
``uname`` and ``sed`` at least, but the full coreutils plus ``find`` and
|
||||||
``awk`` is preferred)
|
``awk`` is preferred)
|
||||||
|
|
||||||
@@ -100,6 +100,7 @@ The following optional features also have specific requirements:
|
|||||||
messages require ``man`` for display
|
messages require ``man`` for display
|
||||||
- automated completion generation from manual pages requires Python 3.5+
|
- automated completion generation from manual pages requires Python 3.5+
|
||||||
- the ``fish_config`` web configuration tool requires Python 3.5+ and a web browser
|
- the ``fish_config`` web configuration tool requires Python 3.5+ and a web browser
|
||||||
|
- the :ref:`alt-o <shared-binds-alt-o>` binding requires the ``file`` program.
|
||||||
- system clipboard integration (with the default Ctrl-V and Ctrl-X
|
- system clipboard integration (with the default Ctrl-V and Ctrl-X
|
||||||
bindings) require either the ``xsel``, ``xclip``,
|
bindings) require either the ``xsel``, ``xclip``,
|
||||||
``wl-copy``/``wl-paste`` or ``pbcopy``/``pbpaste`` utilities
|
``wl-copy``/``wl-paste`` or ``pbcopy``/``pbpaste`` utilities
|
||||||
@@ -111,14 +112,12 @@ The following optional features also have specific requirements:
|
|||||||
Building
|
Building
|
||||||
--------
|
--------
|
||||||
|
|
||||||
.. _dependencies-1:
|
|
||||||
|
|
||||||
Dependencies
|
Dependencies
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
Compiling fish requires:
|
Compiling fish requires:
|
||||||
|
|
||||||
- Rust (version 1.70 or later)
|
- Rust (version 1.85 or later)
|
||||||
- CMake (version 3.15 or later)
|
- CMake (version 3.15 or later)
|
||||||
- a C compiler (for system feature detection and the test helper binary)
|
- a C compiler (for system feature detection and the test helper binary)
|
||||||
- PCRE2 (headers and libraries) - optional, this will be downloaded if missing
|
- PCRE2 (headers and libraries) - optional, this will be downloaded if missing
|
||||||
@@ -128,7 +127,7 @@ Compiling fish requires:
|
|||||||
Sphinx is also optionally required to build the documentation from a
|
Sphinx is also optionally required to build the documentation from a
|
||||||
cloned git repository.
|
cloned git repository.
|
||||||
|
|
||||||
Additionally, running the full test suite requires Python 3.5+, tmux, and the pexpect package.
|
Additionally, running the full test suite requires diff, git, Python 3.5+, pexpect, less, tmux and wget.
|
||||||
|
|
||||||
Building from source with CMake
|
Building from source with CMake
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@@ -140,7 +139,7 @@ links above, and up-to-date `development builds of fish are available for many p
|
|||||||
|
|
||||||
To install into ``/usr/local``, run:
|
To install into ``/usr/local``, run:
|
||||||
|
|
||||||
.. code:: bash
|
.. code:: shell
|
||||||
|
|
||||||
mkdir build; cd build
|
mkdir build; cd build
|
||||||
cmake ..
|
cmake ..
|
||||||
@@ -165,34 +164,41 @@ In addition to the normal CMake build options (like ``CMAKE_INSTALL_PREFIX``), f
|
|||||||
- WITH_GETTEXT=ON|OFF - whether to include translations.
|
- WITH_GETTEXT=ON|OFF - whether to include translations.
|
||||||
- extra_functionsdir, extra_completionsdir and extra_confdir - to compile in an additional directory to be searched for functions, completions and configuration snippets
|
- extra_functionsdir, extra_completionsdir and extra_confdir - to compile in an additional directory to be searched for functions, completions and configuration snippets
|
||||||
|
|
||||||
Building fish with embedded data (experimental)
|
Building fish with Cargo
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
You can also build fish with the data files embedded.
|
You can also build fish with Cargo.
|
||||||
|
This example uses `uv <https://github.com/astral-sh/uv>`__ to install Sphinx (which is used for man-pages and ``--help`` options).
|
||||||
|
You can also install Sphinx another way and drop the ``uv run --no-managed-python`` prefix.
|
||||||
|
|
||||||
This will include all the datafiles like the included functions or web configuration tool in the main ``fish`` binary.
|
.. code:: shell
|
||||||
|
|
||||||
Fish will then read these right from its own binary, and print them out when needed. Some files, like the webconfig tool and the manpage completion generator, will be extracted to a temporary directory on-demand. You can list the files with ``status list-files`` and print one with ``status get-file path/to/file`` (e.g. ``status get-file functions/fish_prompt.fish`` to get the default prompt).
|
git clone https://github.com/fish-shell/fish-shell
|
||||||
|
cd fish-shell
|
||||||
|
|
||||||
To install fish with embedded files, just use ``cargo``, like::
|
# Optional: check out a specific version rather than building the latest
|
||||||
|
# development version.
|
||||||
|
git checkout "$(git for-each-ref refs/tags/ | awk '$2 == "tag" { print $3 }' | tail -1)"
|
||||||
|
|
||||||
cargo install --path /path/to/fish # if you have a git clone
|
uv run --no-managed-python \
|
||||||
cargo install --git https://github.com/fish-shell/fish-shell --tag "$(curl -s https://api.github.com/repos/fish-shell/fish-shell/releases/latest | jq -r .tag_name)" # to build the latest release
|
cargo install --path .
|
||||||
cargo install --git https://github.com/fish-shell/fish-shell # to build the latest development snapshot
|
|
||||||
|
|
||||||
This will place the standalone binaries in ``~/.cargo/bin/``, but you can place them wherever you want.
|
This will place standalone binaries in ``~/.cargo/bin/``, but you can move them wherever you want.
|
||||||
|
|
||||||
This build won't have the HTML docs (``help`` will open the online version).
|
|
||||||
It will try to build the man pages with sphinx-build. If that is not available and you would like to include man pages, you need to install it and retrigger the build script, e.g. by setting FISH_BUILD_DOCS=1::
|
|
||||||
|
|
||||||
FISH_BUILD_DOCS=1 cargo install --path .
|
|
||||||
|
|
||||||
Setting it to "0" disables the inclusion of man pages.
|
|
||||||
|
|
||||||
To disable translations, disable the ``localize-messages`` feature by passing ``--no-default-features --features=embed-data`` to cargo.
|
To disable translations, disable the ``localize-messages`` feature by passing ``--no-default-features --features=embed-data`` to cargo.
|
||||||
|
|
||||||
You can also link this build statically (but not against glibc) and move it to other computers.
|
You can also link this build statically (but not against glibc) and move it to other computers.
|
||||||
|
|
||||||
|
Here are the remaining advantages of a full installation, as currently done by CMake:
|
||||||
|
|
||||||
|
- Man pages like ``fish(1)`` installed in standard locations, easily accessible from outside fish.
|
||||||
|
- A local copy of the HTML documentation, typically accessed via the ``help`` fish function.
|
||||||
|
In Cargo builds, ``help`` will redirect to `<https://fishshell.com/docs/current/>`__
|
||||||
|
- Ability to use our CMake options extra_functionsdir, extra_completionsdir and extra_confdir,
|
||||||
|
(also recorded in ``$PREFIX/share/pkgconfig/fish.pc``)
|
||||||
|
which are used by some package managers to house third-party completions.
|
||||||
|
Regardless of build system, fish uses ``$XDG_DATA_DIRS/{vendor_completion.d,vendor_conf.d,vendor_functions.d}``.
|
||||||
|
|
||||||
Contributing Changes to the Code
|
Contributing Changes to the Code
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
|
|||||||
123
build.rs
123
build.rs
@@ -1,6 +1,4 @@
|
|||||||
#![allow(clippy::uninlined_format_args)]
|
use fish_build_helper::{env_var, fish_build_dir, workspace_root};
|
||||||
|
|
||||||
use fish_build_helper::{fish_build_dir, workspace_root};
|
|
||||||
use rsconf::Target;
|
use rsconf::Target;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
@@ -16,7 +14,7 @@ fn main() {
|
|||||||
// language server.
|
// language server.
|
||||||
|
|
||||||
rsconf::set_env_value(
|
rsconf::set_env_value(
|
||||||
"FISH_BUILD_DIR",
|
"FISH_RESOLVED_BUILD_DIR",
|
||||||
// If set by CMake, this might include symlinks. Since we want to compare this to the
|
// If set by CMake, this might include symlinks. Since we want to compare this to the
|
||||||
// dir fish is executed in we need to canonicalize it.
|
// dir fish is executed in we need to canonicalize it.
|
||||||
canonicalize(fish_build_dir()).to_str().unwrap(),
|
canonicalize(fish_build_dir()).to_str().unwrap(),
|
||||||
@@ -30,16 +28,17 @@ fn main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Some build info
|
// Some build info
|
||||||
rsconf::set_env_value("BUILD_TARGET_TRIPLE", &env::var("TARGET").unwrap());
|
rsconf::set_env_value("BUILD_TARGET_TRIPLE", &env_var("TARGET").unwrap());
|
||||||
rsconf::set_env_value("BUILD_HOST_TRIPLE", &env::var("HOST").unwrap());
|
rsconf::set_env_value("BUILD_HOST_TRIPLE", &env_var("HOST").unwrap());
|
||||||
rsconf::set_env_value("BUILD_PROFILE", &env::var("PROFILE").unwrap());
|
rsconf::set_env_value("BUILD_PROFILE", &env_var("PROFILE").unwrap());
|
||||||
|
|
||||||
let version = &get_version(&env::current_dir().unwrap());
|
let version = &get_version(&env::current_dir().unwrap());
|
||||||
// Per https://doc.rust-lang.org/cargo/reference/build-scripts.html#inputs-to-the-build-script,
|
// Per https://doc.rust-lang.org/cargo/reference/build-scripts.html#inputs-to-the-build-script,
|
||||||
// the source directory is the current working directory of the build script
|
// the source directory is the current working directory of the build script
|
||||||
rsconf::set_env_value("FISH_BUILD_VERSION", version);
|
rsconf::set_env_value("FISH_BUILD_VERSION", version);
|
||||||
|
|
||||||
std::env::set_var("FISH_BUILD_VERSION", version);
|
// safety: single-threaded code.
|
||||||
|
unsafe { std::env::set_var("FISH_BUILD_VERSION", version) };
|
||||||
|
|
||||||
// These are necessary if built with embedded functions,
|
// These are necessary if built with embedded functions,
|
||||||
// but only in release builds (because rust-embed in debug builds reads from the filesystem).
|
// but only in release builds (because rust-embed in debug builds reads from the filesystem).
|
||||||
@@ -57,7 +56,9 @@ fn main() {
|
|||||||
detect_cfgs(&mut target);
|
detect_cfgs(&mut target);
|
||||||
|
|
||||||
#[cfg(all(target_env = "gnu", target_feature = "crt-static"))]
|
#[cfg(all(target_env = "gnu", target_feature = "crt-static"))]
|
||||||
compile_error!("Statically linking against glibc has unavoidable crashes and is unsupported. Use dynamic linking or link statically against musl.");
|
compile_error!(
|
||||||
|
"Statically linking against glibc has unavoidable crashes and is unsupported. Use dynamic linking or link statically against musl."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check target system support for certain functionality dynamically when the build is invoked,
|
/// Check target system support for certain functionality dynamically when the build is invoked,
|
||||||
@@ -80,6 +81,7 @@ fn detect_cfgs(target: &mut Target) {
|
|||||||
("", &(|_: &Target| false) as &dyn Fn(&Target) -> bool),
|
("", &(|_: &Target| false) as &dyn Fn(&Target) -> bool),
|
||||||
("apple", &detect_apple),
|
("apple", &detect_apple),
|
||||||
("bsd", &detect_bsd),
|
("bsd", &detect_bsd),
|
||||||
|
("using_cmake", &|_| option_env!("FISH_CMAKE_BINARY_DIR").is_some()),
|
||||||
("cygwin", &detect_cygwin),
|
("cygwin", &detect_cygwin),
|
||||||
("small_main_stack", &has_small_stack),
|
("small_main_stack", &has_small_stack),
|
||||||
// See if libc supports the thread-safe localeconv_l(3) alternative to localeconv(3).
|
// See if libc supports the thread-safe localeconv_l(3) alternative to localeconv(3).
|
||||||
@@ -114,7 +116,7 @@ fn detect_apple(_: &Target) -> bool {
|
|||||||
|
|
||||||
fn detect_cygwin(_: &Target) -> bool {
|
fn detect_cygwin(_: &Target) -> bool {
|
||||||
// Cygwin target is usually cross-compiled.
|
// Cygwin target is usually cross-compiled.
|
||||||
std::env::var("CARGO_CFG_TARGET_OS").unwrap() == "cygwin"
|
env_var("CARGO_CFG_TARGET_OS").unwrap() == "cygwin"
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Detect if we're being compiled for a BSD-derived OS, allowing targeting code conditionally with
|
/// Detect if we're being compiled for a BSD-derived OS, allowing targeting code conditionally with
|
||||||
@@ -126,11 +128,10 @@ fn detect_cygwin(_: &Target) -> bool {
|
|||||||
fn detect_bsd(_: &Target) -> bool {
|
fn detect_bsd(_: &Target) -> bool {
|
||||||
// Instead of using `uname`, we can inspect the TARGET env variable set by Cargo. This lets us
|
// Instead of using `uname`, we can inspect the TARGET env variable set by Cargo. This lets us
|
||||||
// support cross-compilation scenarios.
|
// support cross-compilation scenarios.
|
||||||
let mut target = std::env::var("TARGET").unwrap();
|
let mut target = env_var("TARGET").unwrap();
|
||||||
if !target.chars().all(|c| c.is_ascii_lowercase()) {
|
if !target.chars().all(|c| c.is_ascii_lowercase()) {
|
||||||
target = target.to_ascii_lowercase();
|
target = target.to_ascii_lowercase();
|
||||||
}
|
}
|
||||||
#[allow(clippy::let_and_return)] // for old clippy
|
|
||||||
let is_bsd = target.ends_with("bsd") || target.ends_with("dragonfly");
|
let is_bsd = target.ends_with("bsd") || target.ends_with("dragonfly");
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_os = "dragonfly",
|
target_os = "dragonfly",
|
||||||
@@ -160,9 +161,9 @@ fn has_small_stack(_: &Target) -> bool {
|
|||||||
{
|
{
|
||||||
use core::ffi;
|
use core::ffi;
|
||||||
|
|
||||||
extern "C" {
|
unsafe extern "C" {
|
||||||
fn pthread_get_stacksize_np(thread: *const ffi::c_void) -> usize;
|
unsafe fn pthread_get_stacksize_np(thread: *const ffi::c_void) -> usize;
|
||||||
fn pthread_self() -> *const ffi::c_void;
|
unsafe fn pthread_self() -> *const ffi::c_void;
|
||||||
}
|
}
|
||||||
|
|
||||||
// build.rs is executed on the main thread, so we are getting the main thread's stack size.
|
// build.rs is executed on the main thread, so we are getting the main thread's stack size.
|
||||||
@@ -177,59 +178,77 @@ fn setup_paths() {
|
|||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use unix_path::{Path, PathBuf};
|
use unix_path::{Path, PathBuf};
|
||||||
|
|
||||||
fn get_path(name: &str, default: &str, onvar: &Path) -> PathBuf {
|
fn overridable_path(
|
||||||
let mut var = PathBuf::from(env::var(name).unwrap_or(default.to_string()));
|
env_var_name: &str,
|
||||||
if var.is_relative() {
|
f: impl FnOnce(Option<String>) -> Option<PathBuf>,
|
||||||
var = onvar.join(var);
|
) -> Option<PathBuf> {
|
||||||
|
rsconf::rebuild_if_env_changed(env_var_name);
|
||||||
|
let maybe_path = f(env_var(env_var_name));
|
||||||
|
if let Some(path) = maybe_path.as_ref() {
|
||||||
|
rsconf::set_env_value(env_var_name, path.to_str().unwrap());
|
||||||
}
|
}
|
||||||
var
|
maybe_path
|
||||||
}
|
}
|
||||||
|
|
||||||
let prefix = PathBuf::from(env::var("PREFIX").unwrap_or("/usr/local".to_string()));
|
fn join_if_relative(parent_if_relative: &Path, path: String) -> PathBuf {
|
||||||
rsconf::rebuild_if_env_changed("PREFIX");
|
let path = PathBuf::from(path);
|
||||||
rsconf::set_env_value("PREFIX", prefix.to_str().unwrap());
|
if path.is_relative() {
|
||||||
|
parent_if_relative.join(path)
|
||||||
|
} else {
|
||||||
|
path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let datadir = get_path("DATADIR", "share/", &prefix);
|
let prefix = overridable_path("PREFIX", |env_prefix| {
|
||||||
|
Some(PathBuf::from(
|
||||||
|
env_prefix.unwrap_or("/usr/local".to_string()),
|
||||||
|
))
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let sysconfdir = get_path(
|
overridable_path("SYSCONFDIR", |env_sysconfdir| {
|
||||||
"SYSCONFDIR",
|
Some(join_if_relative(
|
||||||
// Embedded builds use "/etc," not "./share/etc".
|
&prefix,
|
||||||
|
env_sysconfdir.unwrap_or(
|
||||||
|
// Embedded builds use "/etc," not "$PREFIX/etc".
|
||||||
if cfg!(feature = "embed-data") {
|
if cfg!(feature = "embed-data") {
|
||||||
"/etc/"
|
"/etc/"
|
||||||
} else {
|
} else {
|
||||||
"etc/"
|
"etc/"
|
||||||
},
|
|
||||||
&datadir,
|
|
||||||
);
|
|
||||||
rsconf::set_env_value("SYSCONFDIR", sysconfdir.to_str().unwrap());
|
|
||||||
rsconf::rebuild_if_env_changed("SYSCONFDIR");
|
|
||||||
|
|
||||||
#[cfg(not(feature = "embed-data"))]
|
|
||||||
{
|
|
||||||
rsconf::set_env_value("DATADIR", datadir.to_str().unwrap());
|
|
||||||
rsconf::rebuild_if_env_changed("DATADIR");
|
|
||||||
|
|
||||||
let bindir = get_path("BINDIR", "bin/", &prefix);
|
|
||||||
rsconf::set_env_value("BINDIR", bindir.to_str().unwrap());
|
|
||||||
rsconf::rebuild_if_env_changed("BINDIR");
|
|
||||||
|
|
||||||
let localedir = get_path("LOCALEDIR", "locale/", &datadir);
|
|
||||||
let localedir = localedir.to_str().unwrap();
|
|
||||||
assert!(!localedir.is_empty(), "empty LOCALEDIR is not supported");
|
|
||||||
rsconf::set_env_value("LOCALEDIR", localedir);
|
|
||||||
rsconf::rebuild_if_env_changed("LOCALEDIR");
|
|
||||||
|
|
||||||
let docdir = get_path("DOCDIR", "doc/fish", &datadir);
|
|
||||||
rsconf::set_env_value("DOCDIR", docdir.to_str().unwrap());
|
|
||||||
rsconf::rebuild_if_env_changed("DOCDIR");
|
|
||||||
}
|
}
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
))
|
||||||
|
});
|
||||||
|
|
||||||
|
let default_ok = !cfg!(feature = "embed-data");
|
||||||
|
let datadir = overridable_path("DATADIR", |env_datadir| {
|
||||||
|
let default = default_ok.then_some("share/".to_string());
|
||||||
|
env_datadir
|
||||||
|
.or(default)
|
||||||
|
.map(|p| join_if_relative(&prefix, p))
|
||||||
|
});
|
||||||
|
overridable_path("BINDIR", |env_bindir| {
|
||||||
|
let default = default_ok.then_some("bin/".to_string());
|
||||||
|
env_bindir.or(default).map(|p| join_if_relative(&prefix, p))
|
||||||
|
});
|
||||||
|
overridable_path("DOCDIR", |env_docdir| {
|
||||||
|
let default = default_ok.then_some("doc/fish".to_string());
|
||||||
|
env_docdir.or(default).map(|p| {
|
||||||
|
join_if_relative(
|
||||||
|
&datadir
|
||||||
|
.expect("Setting DOCDIR without setting DATADIR is not currently supported"),
|
||||||
|
p,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_version(src_dir: &Path) -> String {
|
fn get_version(src_dir: &Path) -> String {
|
||||||
use std::fs::read_to_string;
|
use std::fs::read_to_string;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
if let Ok(var) = std::env::var("FISH_BUILD_VERSION") {
|
if let Some(var) = env_var("FISH_BUILD_VERSION") {
|
||||||
return var;
|
return var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,22 @@ if [ "$FISH_CHECK_LINT" = false ]; then
|
|||||||
lint=false
|
lint=false
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
check_dependency_versions=false
|
||||||
|
if [ "${FISH_CHECK_DEPENDENCY_VERSIONS:-false}" != false ]; then
|
||||||
|
check_dependency_versions=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if $check_dependency_versions; then
|
||||||
|
command -v curl
|
||||||
|
command -v jq
|
||||||
|
command -v rustup
|
||||||
|
command -v uv
|
||||||
|
sort --version-sort </dev/null
|
||||||
|
# To match existing behavior, only check Rust/dockerfiles for now.
|
||||||
|
# TODO: remove this from this script.
|
||||||
|
updatecli diff --config=updatecli.d/docker.yml --config=updatecli.d/rust.yml
|
||||||
|
fi
|
||||||
|
|
||||||
cargo_args=$FISH_CHECK_CARGO_ARGS
|
cargo_args=$FISH_CHECK_CARGO_ARGS
|
||||||
target_triple=$FISH_CHECK_TARGET_TRIPLE
|
target_triple=$FISH_CHECK_TARGET_TRIPLE
|
||||||
if [ -n "$target_triple" ]; then
|
if [ -n "$target_triple" ]; then
|
||||||
@@ -49,7 +65,10 @@ if [ -n "$FISH_TEST_MAX_CONCURRENCY" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
template_file=$(mktemp)
|
template_file=$(mktemp)
|
||||||
FISH_GETTEXT_EXTRACTION_FILE=$template_file cargo build --workspace --all-targets --features=gettext-extract
|
(
|
||||||
|
export FISH_GETTEXT_EXTRACTION_FILE="$template_file"
|
||||||
|
cargo build --workspace --all-targets --features=gettext-extract
|
||||||
|
)
|
||||||
if $lint; then
|
if $lint; then
|
||||||
PATH="$build_dir:$PATH" "$workspace_root/build_tools/style.fish" --all --check
|
PATH="$build_dir:$PATH" "$workspace_root/build_tools/style.fish" --all --check
|
||||||
for features in "" --no-default-features; do
|
for features in "" --no-default-features; do
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
#!/usr/bin/env fish
|
|
||||||
# Build a list of all sections in the html sphinx docs, separately by page,
|
|
||||||
# so it can be added to share/functions/help.fish
|
|
||||||
# Use like
|
|
||||||
# fish extract_help_sections.fish user_doc/html/{fish_for_bash_users.html,faq.html,interactive.html,language.html,tutorial.html}
|
|
||||||
# TODO: Currently `help` uses variable names we can't generate, so it needs to be touched up manually.
|
|
||||||
# Also this could easily be broken by changes in sphinx, ideally we'd have a way to let it print the section titles.
|
|
||||||
#
|
|
||||||
|
|
||||||
for file in $argv
|
|
||||||
set -l varname (string replace -r '.*/(.*).html' '$1' -- $file | string escape --style=var)pages
|
|
||||||
# Technically we can use any id in the document as an anchor, but listing them all is probably too much.
|
|
||||||
# Sphinx stores section titles (in a slug-ized form) in the id,
|
|
||||||
# and stores explicit section links in a `span` tag like
|
|
||||||
# `<span id="identifiers"></span>`
|
|
||||||
# We extract both separately.
|
|
||||||
set -l sections (string replace -rf '.*class="headerlink" href="#([^"]*)".*' '$1' <$file)
|
|
||||||
# Sections titled "id5" and such are internal cruft and shouldn't be offered.
|
|
||||||
set -a sections (string replace -rf '.*span id="([^"]*)".*' '$1' <$file | string match -rv 'id\d+')
|
|
||||||
|
|
||||||
set sections (printf '%s\n' $sections | sort -u)
|
|
||||||
echo set -l $varname $sections
|
|
||||||
end
|
|
||||||
@@ -24,13 +24,7 @@ SIGN=
|
|||||||
NOTARIZE=
|
NOTARIZE=
|
||||||
|
|
||||||
ARM64_DEPLOY_TARGET='MACOSX_DEPLOYMENT_TARGET=11.0'
|
ARM64_DEPLOY_TARGET='MACOSX_DEPLOYMENT_TARGET=11.0'
|
||||||
X86_64_DEPLOY_TARGET='MACOSX_DEPLOYMENT_TARGET=10.9'
|
X86_64_DEPLOY_TARGET='MACOSX_DEPLOYMENT_TARGET=10.12'
|
||||||
|
|
||||||
# As of this writing, the most recent Rust release supports macOS back to 10.12.
|
|
||||||
# The first supported version of macOS on arm64 is 10.15, so any Rust is fine for arm64.
|
|
||||||
# We wish to support back to 10.9 on x86-64; the last version of Rust to support that is
|
|
||||||
# version 1.73.0.
|
|
||||||
RUST_VERSION_X86_64=1.70.0
|
|
||||||
|
|
||||||
while getopts "sf:i:p:e:nj:" opt; do
|
while getopts "sf:i:p:e:nj:" opt; do
|
||||||
case $opt in
|
case $opt in
|
||||||
@@ -65,34 +59,29 @@ OUTPUT_PATH=${FISH_ARTEFACT_PATH:-~/fish_built}
|
|||||||
|
|
||||||
mkdir -p "$PKGDIR/build_x86_64" "$PKGDIR/build_arm64" "$PKGDIR/root" "$PKGDIR/intermediates" "$PKGDIR/dst"
|
mkdir -p "$PKGDIR/build_x86_64" "$PKGDIR/build_arm64" "$PKGDIR/root" "$PKGDIR/intermediates" "$PKGDIR/dst"
|
||||||
|
|
||||||
|
do_cmake() {
|
||||||
|
cmake \
|
||||||
|
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||||
|
-DCMAKE_EXE_LINKER_FLAGS="-Wl,-ld_classic" \
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' \
|
||||||
|
-DFISH_USE_SYSTEM_PCRE2=OFF \
|
||||||
|
"$@" \
|
||||||
|
"$SRC_DIR"
|
||||||
|
}
|
||||||
|
|
||||||
# Build and install for arm64.
|
# Build and install for arm64.
|
||||||
# Pass FISH_USE_SYSTEM_PCRE2=OFF because a system PCRE2 on macOS will not be signed by fish,
|
# Pass FISH_USE_SYSTEM_PCRE2=OFF because a system PCRE2 on macOS will not be signed by fish,
|
||||||
# and will probably not be built universal, so the package will fail to validate/run on other systems.
|
# and will probably not be built universal, so the package will fail to validate/run on other systems.
|
||||||
# Note CMAKE_OSX_ARCHITECTURES is still relevant for the Mac app.
|
# Note CMAKE_OSX_ARCHITECTURES is still relevant for the Mac app.
|
||||||
{ cd "$PKGDIR/build_arm64" \
|
{ cd "$PKGDIR/build_arm64" \
|
||||||
&& cmake \
|
&& do_cmake -DRust_CARGO_TARGET=aarch64-apple-darwin \
|
||||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
|
||||||
-DCMAKE_EXE_LINKER_FLAGS="-Wl,-ld_classic" \
|
|
||||||
-DRust_CARGO_TARGET=aarch64-apple-darwin \
|
|
||||||
-DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' \
|
|
||||||
-DFISH_USE_SYSTEM_PCRE2=OFF \
|
|
||||||
"$SRC_DIR" \
|
|
||||||
&& env $ARM64_DEPLOY_TARGET make VERBOSE=1 -j 12 \
|
&& env $ARM64_DEPLOY_TARGET make VERBOSE=1 -j 12 \
|
||||||
&& env DESTDIR="$PKGDIR/root/" $ARM64_DEPLOY_TARGET make install;
|
&& env DESTDIR="$PKGDIR/root/" $ARM64_DEPLOY_TARGET make install;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Build for x86-64 but do not install; instead we will make some fat binaries inside the root.
|
# Build for x86-64 but do not install; instead we will make some fat binaries inside the root.
|
||||||
# Set RUST_VERSION_X86_64 to the last version of Rust that supports macOS 10.9.
|
|
||||||
{ cd "$PKGDIR/build_x86_64" \
|
{ cd "$PKGDIR/build_x86_64" \
|
||||||
&& cmake \
|
&& do_cmake -DRust_CARGO_TARGET=x86_64-apple-darwin \
|
||||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
|
||||||
-DCMAKE_EXE_LINKER_FLAGS="-Wl,-ld_classic" \
|
|
||||||
-DRust_TOOLCHAIN="$RUST_VERSION_X86_64" \
|
|
||||||
-DRust_CARGO_TARGET=x86_64-apple-darwin \
|
|
||||||
-DRust_COMPILER="$(rustup +$RUST_VERSION_X86_64 which rustc)" \
|
|
||||||
-DRust_CARGO="$(rustup +$RUST_VERSION_X86_64 which cargo)" \
|
|
||||||
-DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' \
|
|
||||||
-DFISH_USE_SYSTEM_PCRE2=OFF "$SRC_DIR" \
|
|
||||||
&& env $X86_64_DEPLOY_TARGET make VERBOSE=1 -j 12; }
|
&& env $X86_64_DEPLOY_TARGET make VERBOSE=1 -j 12; }
|
||||||
|
|
||||||
# Fatten them up.
|
# Fatten them up.
|
||||||
|
|||||||
@@ -41,6 +41,12 @@ wd="$PWD"
|
|||||||
|
|
||||||
# Get the version
|
# Get the version
|
||||||
VERSION=$(build_tools/git_version_gen.sh --stdout 2>/dev/null)
|
VERSION=$(build_tools/git_version_gen.sh --stdout 2>/dev/null)
|
||||||
|
tag_creation_date=$(
|
||||||
|
# If not dirty (i.e. we're building an immutable tag), pin the build date.
|
||||||
|
if [ "$VERSION" = "$(git describe)" ]; then
|
||||||
|
git log --format=%ad '--date=format:%b %d, %Y' -1
|
||||||
|
fi
|
||||||
|
)
|
||||||
|
|
||||||
# The name of the prefix, which is the directory that you get when you untar
|
# The name of the prefix, which is the directory that you get when you untar
|
||||||
prefix="fish-$VERSION"
|
prefix="fish-$VERSION"
|
||||||
@@ -60,7 +66,8 @@ PREFIX_TMPDIR=$(mktemp -d)
|
|||||||
cd "$PREFIX_TMPDIR"
|
cd "$PREFIX_TMPDIR"
|
||||||
echo "$VERSION" > version
|
echo "$VERSION" > version
|
||||||
cmake -G "$BUILD_GENERATOR" -DCMAKE_BUILD_TYPE=Debug "$wd"
|
cmake -G "$BUILD_GENERATOR" -DCMAKE_BUILD_TYPE=Debug "$wd"
|
||||||
$BUILD_TOOL doc
|
FISH_SPHINX_BUILD_DATE=$tag_creation_date \
|
||||||
|
$BUILD_TOOL doc
|
||||||
|
|
||||||
TAR_APPEND="$TAR --append --file=$path --mtime=now --owner=0 --group=0 \
|
TAR_APPEND="$TAR --append --file=$path --mtime=now --owner=0 --group=0 \
|
||||||
--mode=g+w,a+rX --transform s/^/$prefix\//"
|
--mode=g+w,a+rX --transform s/^/$prefix\//"
|
||||||
|
|||||||
@@ -11,37 +11,38 @@ mkdir -p "$relnotes_tmp/fake-workspace" "$relnotes_tmp/out"
|
|||||||
cp -r doc_src CONTRIBUTING.rst README.rst "$relnotes_tmp/fake-workspace"
|
cp -r doc_src CONTRIBUTING.rst README.rst "$relnotes_tmp/fake-workspace"
|
||||||
)
|
)
|
||||||
version=$(sed 's,^fish \(\S*\) .*,\1,; 1q' "$workspace_root/CHANGELOG.rst")
|
version=$(sed 's,^fish \(\S*\) .*,\1,; 1q' "$workspace_root/CHANGELOG.rst")
|
||||||
previous_version=$(
|
add_stats=false
|
||||||
|
# Skip on shallow clone (CI) for now.
|
||||||
|
if test -z "$CI" || [ "$(git -C "$workspace_root" tag | wc -l)" -gt 1 ]; then {
|
||||||
|
previous_version=$(
|
||||||
cd "$workspace_root"
|
cd "$workspace_root"
|
||||||
awk <CHANGELOG.rst '
|
git for-each-ref --format='%(objecttype) %(refname:strip=2)' refs/tags |
|
||||||
( /^fish \S*\.\S*\.\S* \(released .*\)$/ &&
|
awk '/tag/ {print $2}' | sort --version-sort |
|
||||||
NR > 1 &&
|
grep -vxF "$(git describe)" | tail -1
|
||||||
# Skip tags that have not been created yet..
|
)
|
||||||
system("git rev-parse --verify >/dev/null --quiet refs/tags/"$2) == 0 \
|
minor_version=${version%.*}
|
||||||
) {
|
previous_minor_version=${previous_version%.*}
|
||||||
print $2; ok = 1; exit
|
if [ "$minor_version" != "$previous_minor_version" ]; then
|
||||||
}
|
add_stats=true
|
||||||
END { exit !ok }
|
fi
|
||||||
'
|
} fi
|
||||||
)
|
|
||||||
minor_version=${version%.*}
|
|
||||||
previous_minor_version=${previous_version%.*}
|
|
||||||
{
|
{
|
||||||
sed -n 1,2p <"$workspace_root/CHANGELOG.rst"
|
sed -n 1,2p <"$workspace_root/CHANGELOG.rst"
|
||||||
|
if $add_stats; then {
|
||||||
|
ExtractCommitters() {
|
||||||
|
git log "$1" --format="%aN"
|
||||||
|
trailers='Co-authored-by|Signed-off-by'
|
||||||
|
git log "$1" --format="%b" | sed -En "/^($trailers):\s*/{s///;s/\s*<.*//;p}"
|
||||||
|
}
|
||||||
ListCommitters() {
|
ListCommitters() {
|
||||||
comm "$@" "$relnotes_tmp/committers-then" "$relnotes_tmp/committers-now"
|
comm "$@" "$relnotes_tmp/committers-then" "$relnotes_tmp/committers-now"
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
cd "$workspace_root"
|
cd "$workspace_root"
|
||||||
git log "$previous_version" --format="%aN" | sort -u >"$relnotes_tmp/committers-then"
|
ExtractCommitters "$previous_version" | sort -u >"$relnotes_tmp/committers-then"
|
||||||
git log "$previous_version".. --format="%aN" | sort -u >"$relnotes_tmp/committers-now"
|
ExtractCommitters "$previous_version".. | sort -u >"$relnotes_tmp/committers-now"
|
||||||
ListCommitters -13 >"$relnotes_tmp/committers-new"
|
ListCommitters -13 >"$relnotes_tmp/committers-new"
|
||||||
ListCommitters -12 >"$relnotes_tmp/committers-returning"
|
ListCommitters -12 >"$relnotes_tmp/committers-returning"
|
||||||
)
|
|
||||||
if [ "$minor_version" != "$previous_minor_version" ]; then
|
|
||||||
(
|
|
||||||
cd "$workspace_root"
|
|
||||||
num_commits=$(git log --no-merges --format=%H "$previous_version".. | wc -l)
|
num_commits=$(git log --no-merges --format=%H "$previous_version".. | wc -l)
|
||||||
num_authors=$(wc -l <"$relnotes_tmp/committers-now")
|
num_authors=$(wc -l <"$relnotes_tmp/committers-now")
|
||||||
num_new_authors=$(wc -l <"$relnotes_tmp/committers-new")
|
num_new_authors=$(wc -l <"$relnotes_tmp/committers-new")
|
||||||
@@ -51,7 +52,7 @@ previous_minor_version=${previous_version%.*}
|
|||||||
echo
|
echo
|
||||||
echo
|
echo
|
||||||
)
|
)
|
||||||
fi
|
} fi
|
||||||
|
|
||||||
printf '%s\n' "$(awk <"$workspace_root/CHANGELOG.rst" '
|
printf '%s\n' "$(awk <"$workspace_root/CHANGELOG.rst" '
|
||||||
NR <= 2 || /^\.\. ignore / { next }
|
NR <= 2 || /^\.\. ignore / { next }
|
||||||
@@ -60,9 +61,9 @@ previous_minor_version=${previous_version%.*}
|
|||||||
' | sed '$d')" |
|
' | sed '$d')" |
|
||||||
sed -e '$s/^----*$//' # Remove spurious transitions at the end of the document.
|
sed -e '$s/^----*$//' # Remove spurious transitions at the end of the document.
|
||||||
|
|
||||||
if [ "$minor_version" != "$previous_minor_version" ]; then {
|
if $add_stats; then {
|
||||||
JoinEscaped() {
|
JoinEscaped() {
|
||||||
sed 's/\S/\\&/g' |
|
LC_CTYPE=C.UTF-8 sed 's/\S/\\&/g' |
|
||||||
awk '
|
awk '
|
||||||
NR != 1 { printf ",\n" }
|
NR != 1 { printf ",\n" }
|
||||||
{ printf "%s", $0 }
|
{ printf "%s", $0 }
|
||||||
@@ -83,9 +84,14 @@ previous_minor_version=${previous_version%.*}
|
|||||||
echo
|
echo
|
||||||
echo "---"
|
echo "---"
|
||||||
echo
|
echo
|
||||||
echo "*Download links: To download the source code for fish, we suggest the file named \"fish-$version.tar.xz\". The file downloaded from \"Source code (tar.gz)\" will not build correctly.*"
|
echo 'Download links:'
|
||||||
|
echo 'To download the source code for fish, we suggest the file named ``fish-'"$version"'.tar.xz``.'
|
||||||
|
echo 'The file downloaded from ``Source code (tar.gz)`` will not build correctly.'
|
||||||
|
echo 'A GPG signature using the key published at '"${FISH_GPG_PUBLIC_KEY_URL:-???}"' is available as ``fish-'"$version"'.tar.xz.asc``.'
|
||||||
echo
|
echo
|
||||||
echo "*The files called fish-$version-linux-\*.tar.xz are experimental packages containing a single standalone ``fish`` binary for any Linux with the given CPU architecture.*"
|
echo 'The files called ``fish-'"$version"'-linux-*.tar.xz`` contain'
|
||||||
|
echo '`standalone fish binaries <https://github.com/fish-shell/fish-shell/?tab=readme-ov-file#building-fish-with-cargo>`__'
|
||||||
|
echo 'for any Linux with the given CPU architecture.'
|
||||||
} >"$relnotes_tmp/fake-workspace"/CHANGELOG.rst
|
} >"$relnotes_tmp/fake-workspace"/CHANGELOG.rst
|
||||||
|
|
||||||
sphinx-build >&2 -j auto \
|
sphinx-build >&2 -j auto \
|
||||||
@@ -93,7 +99,7 @@ sphinx-build >&2 -j auto \
|
|||||||
-d "$relnotes_tmp/doctree" "$relnotes_tmp/fake-workspace/doc_src" "$relnotes_tmp/out" \
|
-d "$relnotes_tmp/doctree" "$relnotes_tmp/fake-workspace/doc_src" "$relnotes_tmp/out" \
|
||||||
-D markdown_http_base="https://fishshell.com/docs/$minor_version" \
|
-D markdown_http_base="https://fishshell.com/docs/$minor_version" \
|
||||||
-D markdown_uri_doc_suffix=".html" \
|
-D markdown_uri_doc_suffix=".html" \
|
||||||
-D markdown_github_flavored=1 \
|
-D markdown_flavor=github \
|
||||||
"$@"
|
"$@"
|
||||||
|
|
||||||
# Skip changelog header
|
# Skip changelog header
|
||||||
|
|||||||
@@ -19,10 +19,14 @@ fi
|
|||||||
|
|
||||||
for tool in \
|
for tool in \
|
||||||
bundle \
|
bundle \
|
||||||
|
diff \
|
||||||
gh \
|
gh \
|
||||||
|
gpg \
|
||||||
jq \
|
jq \
|
||||||
ruby \
|
ruby \
|
||||||
|
tar \
|
||||||
timeout \
|
timeout \
|
||||||
|
uv \
|
||||||
; do
|
; do
|
||||||
if ! command -v "$tool" >/dev/null; then
|
if ! command -v "$tool" >/dev/null; then
|
||||||
echo >&2 "$0: missing command: $1"
|
echo >&2 "$0: missing command: $1"
|
||||||
@@ -30,8 +34,14 @@ for tool in \
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
committer=$(git var GIT_AUTHOR_IDENT)
|
||||||
|
committer=${committer% *} # strip timezone
|
||||||
|
committer=${committer% *} # strip timestamp
|
||||||
|
gpg --local-user="$committer" --sign </dev/null >/dev/null
|
||||||
|
|
||||||
repo_root="$(dirname "$0")/.."
|
repo_root="$(dirname "$0")/.."
|
||||||
fish_site=$repo_root/../fish-site
|
fish_site=$repo_root/../fish-site
|
||||||
|
fish_site_repo=git@github.com:$repository_owner/fish-site
|
||||||
|
|
||||||
for path in . "$fish_site"
|
for path in . "$fish_site"
|
||||||
do
|
do
|
||||||
@@ -42,6 +52,13 @@ do
|
|||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
(
|
||||||
|
cd "$fish_site"
|
||||||
|
[ "$(git rev-parse HEAD)" = \
|
||||||
|
"$(git ls-remote "$fish_site_repo" refs/heads/master |
|
||||||
|
awk '{print $1}')" ]
|
||||||
|
)
|
||||||
|
|
||||||
if git tag | grep -qxF "$version"; then
|
if git tag | grep -qxF "$version"; then
|
||||||
echo >&2 "$0: tag $version already exists"
|
echo >&2 "$0: tag $version already exists"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -74,8 +91,8 @@ Created by ./build_tools/release.sh $version"
|
|||||||
|
|
||||||
CommitVersion "$version" "Release $version"
|
CommitVersion "$version" "Release $version"
|
||||||
|
|
||||||
# N.B. this is not GPG-signed.
|
git -c "user.signingKey=$committer" \
|
||||||
git tag --annotate --message="Release $version" $version
|
tag --sign --message="Release $version" $version
|
||||||
|
|
||||||
git push $remote $version
|
git push $remote $version
|
||||||
|
|
||||||
@@ -100,13 +117,21 @@ done
|
|||||||
# Update fishshell.com
|
# Update fishshell.com
|
||||||
tag_oid=$(git rev-parse "$version")
|
tag_oid=$(git rev-parse "$version")
|
||||||
tmpdir=$(mktemp -d)
|
tmpdir=$(mktemp -d)
|
||||||
|
fish_tar_xz=fish-$version.tar.xz
|
||||||
|
(
|
||||||
|
local_tarball=$tmpdir/local-tarball
|
||||||
|
mkdir "$local_tarball"
|
||||||
|
FISH_ARTEFACT_PATH=$local_tarball uv run ./build_tools/make_tarball.sh
|
||||||
|
cd "$local_tarball"
|
||||||
|
tar xf "$fish_tar_xz"
|
||||||
|
)
|
||||||
# TODO This works on draft releases only if "gh" is configured to
|
# TODO This works on draft releases only if "gh" is configured to
|
||||||
# have write access to the fish-shell repository. Unless we are fine
|
# have write access to the fish-shell repository. Unless we are fine
|
||||||
# publishing the release at this point, we should at least fail if
|
# publishing the release at this point, we should at least fail if
|
||||||
# "gh" doesn't have write access.
|
# "gh" doesn't have write access.
|
||||||
while ! \
|
while ! \
|
||||||
gh release download "$version" --dir="$tmpdir" \
|
gh release download "$version" --dir="$tmpdir" \
|
||||||
--pattern="fish-$version.tar.xz"
|
--pattern="$fish_tar_xz"
|
||||||
do
|
do
|
||||||
TIMEOUT=30 gh run watch "$run_id" ||:
|
TIMEOUT=30 gh run watch "$run_id" ||:
|
||||||
sleep 5
|
sleep 5
|
||||||
@@ -114,7 +139,16 @@ done
|
|||||||
actual_tag_oid=$(git ls-remote "$remote" |
|
actual_tag_oid=$(git ls-remote "$remote" |
|
||||||
awk '$2 == "refs/tags/'"$version"'" { print $1 }')
|
awk '$2 == "refs/tags/'"$version"'" { print $1 }')
|
||||||
[ "$tag_oid" = "$actual_tag_oid" ]
|
[ "$tag_oid" = "$actual_tag_oid" ]
|
||||||
( cd "$tmpdir" && tar xf fish-$version.tar.xz )
|
|
||||||
|
(
|
||||||
|
cd "$tmpdir"
|
||||||
|
tar xf "$fish_tar_xz"
|
||||||
|
diff -ur "fish-$version" "local-tarball/fish-$version"
|
||||||
|
gpg --local-user="$committer" --sign --detach --armor \
|
||||||
|
"$fish_tar_xz"
|
||||||
|
gh release upload "$version" "$fish_tar_xz.asc"
|
||||||
|
)
|
||||||
|
|
||||||
CopyDocs() {
|
CopyDocs() {
|
||||||
rm -rf "$fish_site/site/docs/$1"
|
rm -rf "$fish_site/site/docs/$1"
|
||||||
cp -r "$tmpdir/fish-$version/user_doc/html" "$fish_site/site/docs/$1"
|
cp -r "$tmpdir/fish-$version/user_doc/html" "$fish_site/site/docs/$1"
|
||||||
@@ -153,7 +187,7 @@ gh_api_repo() {
|
|||||||
command gh api \
|
command gh api \
|
||||||
-H "Accept: application/vnd.github+json" \
|
-H "Accept: application/vnd.github+json" \
|
||||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||||
"/repos/$repository_owner/fish-shell/$1" \
|
"/repos/$repository_owner/fish-shell/$path" \
|
||||||
"$@"
|
"$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +238,7 @@ done
|
|||||||
" | sed 's,^\s*| \?,,')"
|
" | sed 's,^\s*| \?,,')"
|
||||||
# This takes care to support remote names that are different from
|
# This takes care to support remote names that are different from
|
||||||
# fish-shell remote name. Also, support detached HEAD state.
|
# fish-shell remote name. Also, support detached HEAD state.
|
||||||
git push git@github.com:$repository_owner/fish-site HEAD:master
|
git push "$fish_site_repo" HEAD:master
|
||||||
)
|
)
|
||||||
|
|
||||||
if [ -n "$integration_branch" ]; then {
|
if [ -n "$integration_branch" ]; then {
|
||||||
@@ -225,7 +259,7 @@ milestone_number=$(
|
|||||||
gh_api_repo milestones?state=open |
|
gh_api_repo milestones?state=open |
|
||||||
jq '.[] | select(.title == "fish '"$version"'") | .number'
|
jq '.[] | select(.title == "fish '"$version"'") | .number'
|
||||||
)
|
)
|
||||||
gh_api_repo --method PATCH milestones/$milestone_number \
|
gh_api_repo milestones/$milestone_number --method PATCH \
|
||||||
--raw-field state=closed
|
--raw-field state=closed
|
||||||
|
|
||||||
next_patch_version=$(
|
next_patch_version=$(
|
||||||
@@ -236,7 +270,7 @@ next_patch_version=$(
|
|||||||
'
|
'
|
||||||
)
|
)
|
||||||
if [ -n "$next_patch_version" ]; then
|
if [ -n "$next_patch_version" ]; then
|
||||||
gh_api_repo --method POST milestones \
|
gh_api_repo milestones --method POST \
|
||||||
--raw-field title="fish $next_patch_version"
|
--raw-field title="fish $next_patch_version"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ if test $all = yes
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
set fish_files $workspace_root/{benchmarks,build_tools,etc,share}/**.fish
|
set fish_files $workspace_root/{benchmarks,build_tools,etc,share}/**.fish
|
||||||
set python_files {doc_src,share,tests}/**.py
|
set python_files $workspace_root
|
||||||
else
|
else
|
||||||
# Format the files specified as arguments.
|
# Format the files specified as arguments.
|
||||||
set -l files $argv
|
set -l files $argv
|
||||||
@@ -58,6 +58,11 @@ set -l green (set_color green)
|
|||||||
set -l yellow (set_color yellow)
|
set -l yellow (set_color yellow)
|
||||||
set -l normal (set_color normal)
|
set -l normal (set_color normal)
|
||||||
|
|
||||||
|
function die -V red -V normal
|
||||||
|
echo $red$argv[1]$normal
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
if set -q fish_files[1]
|
if set -q fish_files[1]
|
||||||
if not type -q fish_indent
|
if not type -q fish_indent
|
||||||
echo
|
echo
|
||||||
@@ -66,58 +71,52 @@ if set -q fish_files[1]
|
|||||||
end
|
end
|
||||||
echo === Running "$green"fish_indent"$normal"
|
echo === Running "$green"fish_indent"$normal"
|
||||||
if set -l -q _flag_check
|
if set -l -q _flag_check
|
||||||
if not fish_indent --check -- $fish_files
|
fish_indent --check -- $fish_files
|
||||||
echo $red"Fish files are not formatted correctly."$normal
|
or die "Fish files are not formatted correctly."
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
fish_indent -w -- $fish_files
|
fish_indent -w -- $fish_files
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if set -q python_files[1]
|
if set -q python_files[1]
|
||||||
if not type -q black
|
if not type -q ruff
|
||||||
echo
|
echo
|
||||||
echo $yellow'Please install `black` to style python'$normal
|
echo $yellow'Please install `ruff` to style python'$normal
|
||||||
exit 127
|
exit 127
|
||||||
end
|
end
|
||||||
echo === Running "$green"black"$normal"
|
echo === Running "$green"ruff format"$normal"
|
||||||
if set -l -q _flag_check
|
if set -l -q _flag_check
|
||||||
if not black --check $python_files
|
ruff format --check $python_files
|
||||||
echo $red"Python files are not formatted correctly."$normal
|
or die "Python files are not formatted correctly."
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
black $python_files
|
ruff format $python_files
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not cargo fmt --version >/dev/null
|
if test $all = yes; or set -q rust_files[1]
|
||||||
|
if not cargo fmt --version >/dev/null
|
||||||
echo
|
echo
|
||||||
echo $yellow'Please install "rustfmt" to style Rust, e.g. via:'
|
echo $yellow'Please install "rustfmt" to style Rust, e.g. via:'
|
||||||
echo "rustup component add rustfmt"$normal
|
echo "rustup component add rustfmt"$normal
|
||||||
exit 127
|
exit 127
|
||||||
end
|
|
||||||
echo === Running "$green"rustfmt"$normal"
|
|
||||||
if set -l -q _flag_check
|
|
||||||
if set -l -q _flag_all
|
|
||||||
if not cargo fmt --check
|
|
||||||
echo $red"Rust files are not formatted correctly."$normal
|
|
||||||
exit 1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
set -l edition_spec string match -r '^edition\s*=.*'
|
||||||
|
test "$($edition_spec <Cargo.toml)" = "$($edition_spec <.rustfmt.toml)"
|
||||||
|
or die "Cargo.toml and .rustfmt.toml use different editions"
|
||||||
|
|
||||||
|
echo === Running "$green"rustfmt"$normal"
|
||||||
|
if set -l -q _flag_check
|
||||||
|
if test $all = yes
|
||||||
|
cargo fmt --all --check
|
||||||
else
|
else
|
||||||
if set -q rust_files[1]
|
rustfmt --check --files-with-diff $rust_files
|
||||||
if not rustfmt --check --files-with-diff $rust_files
|
|
||||||
echo $red"Rust files are not formatted correctly."
|
|
||||||
exit 1
|
|
||||||
end
|
end
|
||||||
end
|
or die "Rust files are not formatted correctly."
|
||||||
end
|
else
|
||||||
else
|
if test $all = yes
|
||||||
if set -l -q _flag_all
|
cargo fmt --all
|
||||||
cargo fmt
|
|
||||||
else
|
else
|
||||||
if set -q rust_files[1]
|
|
||||||
rustfmt $rust_files
|
rustfmt $rust_files
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
33
build_tools/update-dependencies.sh
Executable file
33
build_tools/update-dependencies.sh
Executable file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
command -v curl
|
||||||
|
command -v gcloud
|
||||||
|
command -v jq
|
||||||
|
command -v rustup
|
||||||
|
command -v updatecli
|
||||||
|
command -v uv
|
||||||
|
sort --version-sort </dev/null
|
||||||
|
|
||||||
|
uv lock --check
|
||||||
|
|
||||||
|
updatecli "${@:-apply}"
|
||||||
|
|
||||||
|
uv lock # Python version constraints may have changed.
|
||||||
|
uv lock --upgrade
|
||||||
|
|
||||||
|
from_gh() {
|
||||||
|
repo=$1
|
||||||
|
path=$2
|
||||||
|
out_dir=$3
|
||||||
|
contents=$(curl -fsS https://raw.githubusercontent.com/"${repo}"/refs/heads/master/"${path}")
|
||||||
|
printf '%s\n' >"$out_dir/$(basename "$path")" "$contents"
|
||||||
|
}
|
||||||
|
from_gh ridiculousfish/widecharwidth widechar_width.rs src/widecharwidth/
|
||||||
|
from_gh ridiculousfish/littlecheck littlecheck/littlecheck.py tests/
|
||||||
|
|
||||||
|
# Update Cargo.lock
|
||||||
|
cargo update
|
||||||
|
# Update Cargo.toml and Cargo.lock
|
||||||
|
cargo +nightly -Zunstable-options update --breaking
|
||||||
@@ -34,7 +34,6 @@ set -l build_tools (status dirname)
|
|||||||
set -l po_dir $build_tools/../po
|
set -l po_dir $build_tools/../po
|
||||||
|
|
||||||
set -l extract
|
set -l extract
|
||||||
set -l po
|
|
||||||
|
|
||||||
argparse dry-run use-existing-template= -- $argv
|
argparse dry-run use-existing-template= -- $argv
|
||||||
or exit $status
|
or exit $status
|
||||||
@@ -134,7 +133,6 @@ for po_file in $po_files
|
|||||||
if set --query tmpdir[1]
|
if set --query tmpdir[1]
|
||||||
set po_file $tmpdir/(basename $po_file)
|
set po_file $tmpdir/(basename $po_file)
|
||||||
end
|
end
|
||||||
if set -l --query po
|
|
||||||
if test -e $po_file
|
if test -e $po_file
|
||||||
merge_po_files $template_file $po_file
|
merge_po_files $template_file $po_file
|
||||||
else
|
else
|
||||||
@@ -143,7 +141,6 @@ for po_file in $po_files
|
|||||||
cat $template_file
|
cat $template_file
|
||||||
end >$po_file
|
end >$po_file
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if set -g --query tmpdir[1]
|
if set -g --query tmpdir[1]
|
||||||
|
|||||||
16
build_tools/version-available-in-debian.sh
Executable file
16
build_tools/version-available-in-debian.sh
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
channel=$1 # e.g. stable, testing
|
||||||
|
package=$2 # e.g. rustc, sphinx
|
||||||
|
|
||||||
|
codename=$(
|
||||||
|
curl -fsS https://ftp.debian.org/debian/dists/"${channel}"/Release |
|
||||||
|
grep '^Codename:' | cut -d' ' -f2)
|
||||||
|
curl -fsS https://sources.debian.org/api/src/"${package}"/ |
|
||||||
|
jq -r --arg codename "${codename}" '
|
||||||
|
.versions[] | select(.suites[] == $codename) | .version' |
|
||||||
|
sed 's/^\([0-9]\+\.[0-9]\+\).*/\1/' |
|
||||||
|
sort --version-sort |
|
||||||
|
tail -1
|
||||||
@@ -136,7 +136,7 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/
|
|||||||
PATTERN "*.1"
|
PATTERN "*.1"
|
||||||
PATTERN ${CONDEMNED_PAGE} EXCLUDE)
|
PATTERN ${CONDEMNED_PAGE} EXCLUDE)
|
||||||
|
|
||||||
install(PROGRAMS share/tools/create_manpage_completions.py share/tools/deroff.py
|
install(PROGRAMS share/tools/create_manpage_completions.py
|
||||||
DESTINATION ${rel_datadir}/fish/tools/)
|
DESTINATION ${rel_datadir}/fish/tools/)
|
||||||
|
|
||||||
install(DIRECTORY share/tools/web_config
|
install(DIRECTORY share/tools/web_config
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ find_package(Rust REQUIRED)
|
|||||||
|
|
||||||
set(FISH_RUST_BUILD_DIR "${CMAKE_BINARY_DIR}/cargo/build")
|
set(FISH_RUST_BUILD_DIR "${CMAKE_BINARY_DIR}/cargo/build")
|
||||||
|
|
||||||
|
list(APPEND FISH_CARGO_FEATURES_LIST "embed-data")
|
||||||
|
|
||||||
if(DEFINED ASAN)
|
if(DEFINED ASAN)
|
||||||
list(APPEND CARGO_FLAGS "-Z" "build-std")
|
list(APPEND CARGO_FLAGS "-Z" "build-std")
|
||||||
list(APPEND FISH_CARGO_FEATURES_LIST "asan")
|
list(APPEND FISH_CARGO_FEATURES_LIST "asan")
|
||||||
@@ -28,19 +30,3 @@ if(NOT DEFINED WITH_GETTEXT OR "${WITH_GETTEXT}")
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
list(JOIN FISH_CARGO_FEATURES_LIST , FISH_CARGO_FEATURES)
|
list(JOIN FISH_CARGO_FEATURES_LIST , FISH_CARGO_FEATURES)
|
||||||
|
|
||||||
# Tell Cargo where our build directory is so it can find Cargo.toml.
|
|
||||||
set(VARS_FOR_CARGO
|
|
||||||
"FISH_BUILD_DIR=${CMAKE_BINARY_DIR}"
|
|
||||||
"PREFIX=${CMAKE_INSTALL_PREFIX}"
|
|
||||||
# Cheesy so we can tell cmake was used to build
|
|
||||||
"CMAKE=1"
|
|
||||||
"DOCDIR=${CMAKE_INSTALL_FULL_DOCDIR}"
|
|
||||||
"DATADIR=${CMAKE_INSTALL_FULL_DATADIR}"
|
|
||||||
"SYSCONFDIR=${CMAKE_INSTALL_FULL_SYSCONFDIR}"
|
|
||||||
"BINDIR=${CMAKE_INSTALL_FULL_BINDIR}"
|
|
||||||
"CARGO_TARGET_DIR=${FISH_RUST_BUILD_DIR}"
|
|
||||||
"CARGO_BUILD_RUSTC=${Rust_COMPILER}"
|
|
||||||
"${FISH_PCRE2_BUILDFLAG}"
|
|
||||||
"RUSTFLAGS=$ENV{RUSTFLAGS} ${rust_debugflags}"
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ endif()
|
|||||||
add_custom_target(fish_run_tests
|
add_custom_target(fish_run_tests
|
||||||
# TODO: This should be replaced with a unified solution, possibly build_tools/check.sh.
|
# TODO: This should be replaced with a unified solution, possibly build_tools/check.sh.
|
||||||
COMMAND ${CMAKE_SOURCE_DIR}/tests/test_driver.py ${max_concurrency_flag} ${CMAKE_CURRENT_BINARY_DIR}
|
COMMAND ${CMAKE_SOURCE_DIR}/tests/test_driver.py ${max_concurrency_flag} ${CMAKE_CURRENT_BINARY_DIR}
|
||||||
COMMAND env ${VARS_FOR_CARGO} cargo test --no-default-features ${CARGO_FLAGS} --workspace --target-dir ${rust_target_dir} ${cargo_test_flags}
|
COMMAND env ${VARS_FOR_CARGO} ${Rust_CARGO} test --no-default-features ${CARGO_FLAGS} --workspace --target-dir ${rust_target_dir} ${cargo_test_flags}
|
||||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||||
DEPENDS fish fish_indent fish_key_reader fish_test_helper
|
DEPENDS fish fish_indent fish_key_reader fish_test_helper
|
||||||
USES_TERMINAL
|
USES_TERMINAL
|
||||||
|
|||||||
@@ -1,4 +1,21 @@
|
|||||||
use std::{borrow::Cow, env, path::Path};
|
use std::{borrow::Cow, env, os::unix::ffi::OsStrExt, path::Path};
|
||||||
|
|
||||||
|
pub fn env_var(name: &str) -> Option<String> {
|
||||||
|
let err = match env::var(name) {
|
||||||
|
Ok(p) => return Some(p),
|
||||||
|
Err(err) => err,
|
||||||
|
};
|
||||||
|
use env::VarError::*;
|
||||||
|
match err {
|
||||||
|
NotPresent => None,
|
||||||
|
NotUnicode(os_string) => {
|
||||||
|
panic!(
|
||||||
|
"Environment variable {name} is not valid Unicode: {:?}",
|
||||||
|
os_string.as_bytes()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn workspace_root() -> &'static Path {
|
pub fn workspace_root() -> &'static Path {
|
||||||
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
|
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
|
||||||
@@ -12,8 +29,7 @@ fn cargo_target_dir() -> Cow<'static, Path> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn fish_build_dir() -> Cow<'static, Path> {
|
pub fn fish_build_dir() -> Cow<'static, Path> {
|
||||||
// FISH_BUILD_DIR is set by CMake, if we are using it.
|
option_env!("FISH_CMAKE_BINARY_DIR")
|
||||||
option_env!("FISH_BUILD_DIR")
|
|
||||||
.map(|d| Cow::Borrowed(Path::new(d)))
|
.map(|d| Cow::Borrowed(Path::new(d)))
|
||||||
.unwrap_or(cargo_target_dir())
|
.unwrap_or(cargo_target_dir())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,75 @@
|
|||||||
#[cfg(not(clippy))]
|
use fish_build_helper::env_var;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mandir = fish_build_helper::fish_build_dir().join("fish-man");
|
let man_dir = fish_build_helper::fish_build_dir().join("fish-man");
|
||||||
let sec1dir = mandir.join("man1");
|
let sec1_dir = man_dir.join("man1");
|
||||||
// Running `cargo clippy` on a clean build directory panics, because when rust-embed tries to
|
// Running `cargo clippy` on a clean build directory panics, because when rust-embed tries to
|
||||||
// embed a directory which does not exist it will panic.
|
// embed a directory which does not exist it will panic.
|
||||||
let _ = std::fs::create_dir_all(sec1dir.to_str().unwrap());
|
let _ = std::fs::create_dir_all(&sec1_dir);
|
||||||
|
|
||||||
|
let help_sections_path = Path::new(&env_var("OUT_DIR").unwrap()).join("help_sections.rs");
|
||||||
|
std::fs::write(
|
||||||
|
help_sections_path.clone(),
|
||||||
|
r#"pub static HELP_SECTIONS: &str = "";"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
#[cfg(not(clippy))]
|
#[cfg(not(clippy))]
|
||||||
build_man(&mandir);
|
build_man(&man_dir, &sec1_dir, &help_sections_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(clippy))]
|
#[cfg(not(clippy))]
|
||||||
fn build_man(man_dir: &Path) {
|
fn build_man(man_dir: &Path, sec1_dir: &Path, help_sections_path: &Path) {
|
||||||
use std::{
|
use std::{
|
||||||
env,
|
ffi::OsStr,
|
||||||
process::{Command, Stdio},
|
process::{Command, Stdio},
|
||||||
};
|
};
|
||||||
|
|
||||||
use fish_build_helper::workspace_root;
|
use fish_build_helper::workspace_root;
|
||||||
|
|
||||||
let workspace_root = workspace_root();
|
let workspace_root = workspace_root();
|
||||||
|
let doc_src_dir = workspace_root.join("doc_src");
|
||||||
|
|
||||||
let man_str = man_dir.to_str().unwrap();
|
fish_build_helper::rebuild_if_paths_changed([
|
||||||
|
&workspace_root.join("CHANGELOG.rst"),
|
||||||
|
&workspace_root.join("CONTRIBUTING.rst"),
|
||||||
|
&doc_src_dir,
|
||||||
|
]);
|
||||||
|
|
||||||
let sec1_dir = man_dir.join("man1");
|
let help_sections_arg = format!("fish_help_sections_output={}", help_sections_path.display());
|
||||||
let sec1_str = sec1_dir.to_str().unwrap();
|
let args: &[&OsStr] = {
|
||||||
|
fn as_os_str<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
|
||||||
let docsrc_dir = workspace_root.join("doc_src");
|
s.as_ref()
|
||||||
let docsrc_str = docsrc_dir.to_str().unwrap();
|
}
|
||||||
|
macro_rules! as_os_strs {
|
||||||
let sphinx_doc_sources = [
|
( [ $( $x:expr, )* ] ) => {
|
||||||
workspace_root.join("CHANGELOG.rst"),
|
&[
|
||||||
workspace_root.join("CONTRIBUTING.rst"),
|
$( as_os_str($x), )*
|
||||||
docsrc_dir.clone(),
|
]
|
||||||
];
|
}
|
||||||
fish_build_helper::rebuild_if_paths_changed(sphinx_doc_sources);
|
}
|
||||||
|
as_os_strs!([
|
||||||
let args = &[
|
"-j",
|
||||||
"-j", "auto", "-q", "-b", "man", "-c", docsrc_str,
|
"auto",
|
||||||
|
"-q",
|
||||||
|
"-b",
|
||||||
|
"man",
|
||||||
|
"-c",
|
||||||
|
&doc_src_dir,
|
||||||
// doctree path - put this *above* the man1 dir to exclude it.
|
// doctree path - put this *above* the man1 dir to exclude it.
|
||||||
// this is ~6M
|
// this is ~6M
|
||||||
"-d", man_str, docsrc_str, sec1_str,
|
"-d",
|
||||||
];
|
&man_dir,
|
||||||
let _ = std::fs::create_dir_all(sec1_str);
|
&doc_src_dir,
|
||||||
|
&sec1_dir,
|
||||||
|
"-D",
|
||||||
|
&help_sections_arg,
|
||||||
|
])
|
||||||
|
};
|
||||||
|
|
||||||
rsconf::rebuild_if_env_changed("FISH_BUILD_DOCS");
|
rsconf::rebuild_if_env_changed("FISH_BUILD_DOCS");
|
||||||
if env::var("FISH_BUILD_DOCS") == Ok("0".to_string()) {
|
if env_var("FISH_BUILD_DOCS") == Some("0".to_string()) {
|
||||||
rsconf::warn!("Skipping man pages because $FISH_BUILD_DOCS is set to 0");
|
rsconf::warn!("Skipping man pages because $FISH_BUILD_DOCS is set to 0");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -57,18 +79,24 @@ fn build_man(man_dir: &Path) {
|
|||||||
// - if we skipped the docs with sphinx not installed, installing it would not then build the docs.
|
// - if we skipped the docs with sphinx not installed, installing it would not then build the docs.
|
||||||
// That means you need to explicitly set $FISH_BUILD_DOCS=0 (`FISH_BUILD_DOCS=0 cargo install --path .`),
|
// That means you need to explicitly set $FISH_BUILD_DOCS=0 (`FISH_BUILD_DOCS=0 cargo install --path .`),
|
||||||
// which is unfortunate - but the docs are pretty important because they're also used for --help.
|
// which is unfortunate - but the docs are pretty important because they're also used for --help.
|
||||||
let sphinx_build = match Command::new("sphinx-build")
|
let sphinx_build = match Command::new(option_env!("FISH_SPHINX").unwrap_or("sphinx-build"))
|
||||||
.args(args)
|
.args(args)
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.spawn()
|
.spawn()
|
||||||
{
|
{
|
||||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
|
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
|
||||||
if env::var("FISH_BUILD_DOCS") == Ok("1".to_string()) {
|
if env_var("FISH_BUILD_DOCS") == Some("1".to_string()) {
|
||||||
panic!("Could not find sphinx-build to build man pages.\nInstall sphinx or disable building the docs by setting $FISH_BUILD_DOCS=0.");
|
panic!(
|
||||||
|
"Could not find sphinx-build required to build man pages.\n\
|
||||||
|
Install Sphinx or disable building the docs by setting $FISH_BUILD_DOCS=0."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
rsconf::warn!("Cannot find sphinx-build to build man pages.");
|
rsconf::warn!(
|
||||||
rsconf::warn!("If you install it now you need to run `cargo clean` and rebuild, or set $FISH_BUILD_DOCS=1 explicitly.");
|
"Could not find sphinx-build required to build man pages. \
|
||||||
|
If you install Sphinx now, you need to trigger a rebuild to include man pages. \
|
||||||
|
For example by running `touch doc_src` followed by the build command."
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
|
include!(concat!(env!("OUT_DIR"), "/help_sections.rs"));
|
||||||
|
|||||||
@@ -50,7 +50,9 @@ fn append_po_entry_to_file(message: &TokenStream, file_name: &OsString) {
|
|||||||
.unwrap_or_else(|e| panic!("Could not open file {file_name:?}: {e}"));
|
.unwrap_or_else(|e| panic!("Could not open file {file_name:?}: {e}"));
|
||||||
let message_string = unescape_multiline_rust_string(message.to_string());
|
let message_string = unescape_multiline_rust_string(message.to_string());
|
||||||
if message_string.contains('\n') {
|
if message_string.contains('\n') {
|
||||||
panic!("Gettext strings may not contain unescaped newlines. Unescaped newline found in '{message_string}'")
|
panic!(
|
||||||
|
"Gettext strings may not contain unescaped newlines. Unescaped newline found in '{message_string}'"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
// Crude check for format strings. This might result in false positives.
|
// Crude check for format strings. This might result in false positives.
|
||||||
let format_string_annotation = if message_string.contains('%') {
|
let format_string_annotation = if message_string.contains('%') {
|
||||||
@@ -84,24 +86,27 @@ pub fn gettext_extract(message: TokenStream) -> TokenStream {
|
|||||||
.next()
|
.next()
|
||||||
.expect("gettext_extract got empty token stream. Expected one token.");
|
.expect("gettext_extract got empty token stream. Expected one token.");
|
||||||
if token_trees.next().is_some() {
|
if token_trees.next().is_some() {
|
||||||
panic!("Invalid number of tokens passed to gettext_extract. Expected one token, but got more.")
|
panic!(
|
||||||
|
"Invalid number of tokens passed to gettext_extract. Expected one token, but got more."
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if let proc_macro2::TokenTree::Group(group) = first_token {
|
let proc_macro2::TokenTree::Group(group) = first_token else {
|
||||||
|
panic!("Expected group in gettext_extract, but got: {first_token:?}");
|
||||||
|
};
|
||||||
let mut group_tokens = group.stream().into_iter();
|
let mut group_tokens = group.stream().into_iter();
|
||||||
let first_group_token = group_tokens
|
let first_group_token = group_tokens
|
||||||
.next()
|
.next()
|
||||||
.expect("gettext_extract expected one group token but got none.");
|
.expect("gettext_extract expected one group token but got none.");
|
||||||
if group_tokens.next().is_some() {
|
if group_tokens.next().is_some() {
|
||||||
panic!("Invalid number of tokens in group passed to gettext_extract. Expected one token, but got more.")
|
panic!(
|
||||||
|
"Invalid number of tokens in group passed to gettext_extract. Expected one token, but got more."
|
||||||
|
)
|
||||||
}
|
}
|
||||||
if let proc_macro2::TokenTree::Literal(_) = first_group_token {
|
if let proc_macro2::TokenTree::Literal(_) = first_group_token {
|
||||||
append_po_entry_to_file(&message, &file_path);
|
append_po_entry_to_file(&message, &file_path);
|
||||||
} else {
|
} else {
|
||||||
panic!("Expected literal in gettext_extract, but got: {first_group_token:?}");
|
panic!("Expected literal in gettext_extract, but got: {first_group_token:?}");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
panic!("Expected group in gettext_extract, but got: {first_token:?}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
message
|
message
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
use std::{
|
use std::{
|
||||||
env,
|
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process::{Command, Stdio},
|
process::Command,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use fish_build_helper::env_var;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let cache_dir =
|
let cache_dir =
|
||||||
PathBuf::from(fish_build_helper::fish_build_dir()).join("fish-localization-map-cache");
|
PathBuf::from(fish_build_helper::fish_build_dir()).join("fish-localization-map-cache");
|
||||||
@@ -27,33 +28,28 @@ fn embed_localizations(cache_dir: &Path) {
|
|||||||
std::fs::create_dir_all(cache_dir).unwrap();
|
std::fs::create_dir_all(cache_dir).unwrap();
|
||||||
|
|
||||||
let localization_map_path =
|
let localization_map_path =
|
||||||
Path::new(&env::var("OUT_DIR").unwrap()).join("localization_maps.rs");
|
Path::new(&env_var("OUT_DIR").unwrap()).join("localization_maps.rs");
|
||||||
let mut localization_map_file = BufWriter::new(File::create(&localization_map_path).unwrap());
|
let mut localization_map_file = BufWriter::new(File::create(&localization_map_path).unwrap());
|
||||||
|
|
||||||
// This will become a map which maps from language identifiers to maps containing localizations
|
// This will become a map which maps from language identifiers to maps containing localizations
|
||||||
// for the respective language.
|
// for the respective language.
|
||||||
let mut catalogs = phf_codegen::Map::new();
|
let mut catalogs = phf_codegen::Map::new();
|
||||||
|
|
||||||
match Command::new("msgfmt")
|
match Command::new("msgfmt").arg("-h").output() {
|
||||||
.arg("-h")
|
|
||||||
.stdout(Stdio::null())
|
|
||||||
.status()
|
|
||||||
{
|
|
||||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
|
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
|
||||||
rsconf::warn!(
|
rsconf::warn!(
|
||||||
"Cannot find msgfmt to build gettext message catalogs. Localization will not work."
|
"Could not find msgfmt required to build message catalogs. \
|
||||||
);
|
Localization will not work. \
|
||||||
rsconf::warn!(
|
If you install gettext now, you need to trigger a rebuild to include localization support. \
|
||||||
"If you install it now you need to trigger a rebuild to get localization support."
|
For example by running `touch po` followed by the build command."
|
||||||
);
|
|
||||||
rsconf::warn!(
|
|
||||||
"One way to achieve that is running `touch po` followed by the build command."
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
panic!("Error when trying to run `msgfmt -h`: {e:?}");
|
panic!("Error when trying to run `msgfmt -h`: {e:?}");
|
||||||
}
|
}
|
||||||
Ok(_) => {
|
Ok(output) => {
|
||||||
|
let has_check_format =
|
||||||
|
String::from_utf8_lossy(&output.stdout).contains("--check-format");
|
||||||
for dir_entry_result in po_dir.read_dir().unwrap() {
|
for dir_entry_result in po_dir.read_dir().unwrap() {
|
||||||
let dir_entry = dir_entry_result.unwrap();
|
let dir_entry = dir_entry_result.unwrap();
|
||||||
let po_file_path = dir_entry.path();
|
let po_file_path = dir_entry.path();
|
||||||
@@ -95,19 +91,32 @@ fn embed_localizations(cache_dir: &Path) {
|
|||||||
// Generate the map file.
|
// Generate the map file.
|
||||||
|
|
||||||
// Try to create new MO data and load it into `mo_data`.
|
// Try to create new MO data and load it into `mo_data`.
|
||||||
let output = Command::new("msgfmt")
|
let mut tmp_mo_file = None;
|
||||||
.arg("--check-format")
|
let output = {
|
||||||
.arg("--output-file=-")
|
let mut cmd = &mut Command::new("msgfmt");
|
||||||
|
if has_check_format {
|
||||||
|
cmd = cmd.arg("--check-format");
|
||||||
|
} else {
|
||||||
|
tmp_mo_file = Some(cache_dir.join("messages.mo"));
|
||||||
|
};
|
||||||
|
cmd.arg(format!(
|
||||||
|
"--output-file={}",
|
||||||
|
tmp_mo_file
|
||||||
|
.as_ref()
|
||||||
|
.map_or("-", |path| path.to_str().unwrap())
|
||||||
|
))
|
||||||
.arg(&po_file_path)
|
.arg(&po_file_path)
|
||||||
.output()
|
.output()
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
};
|
||||||
if !output.status.success() {
|
if !output.status.success() {
|
||||||
panic!(
|
panic!(
|
||||||
"msgfmt failed:\n{}",
|
"msgfmt failed:\n{}",
|
||||||
String::from_utf8(output.stderr).unwrap()
|
String::from_utf8(output.stderr).unwrap()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let mo_data = output.stdout;
|
let mo_data =
|
||||||
|
tmp_mo_file.map_or(output.stdout, |path| std::fs::read(path).unwrap());
|
||||||
|
|
||||||
// Extract map from MO data.
|
// Extract map from MO data.
|
||||||
let language_localizations = parse_mo_file(&mo_data).unwrap();
|
let language_localizations = parse_mo_file(&mo_data).unwrap();
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub enum Arg<'a> {
|
|||||||
#[cfg(feature = "widestring")]
|
#[cfg(feature = "widestring")]
|
||||||
WString(WString),
|
WString(WString),
|
||||||
UInt(u64),
|
UInt(u64),
|
||||||
SInt(i64, u8), // signed integers track their width as the number of bits
|
SInt(i64),
|
||||||
Float(f64),
|
Float(f64),
|
||||||
USizeRef(&'a mut usize), // for use with %n
|
USizeRef(&'a mut usize), // for use with %n
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ pub fn as_str<'s>(&'s self, storage: &'s mut String) -> Result<&'s str, Error>
|
|||||||
pub fn as_uint(&self) -> Result<u64, Error> {
|
pub fn as_uint(&self) -> Result<u64, Error> {
|
||||||
match *self {
|
match *self {
|
||||||
Arg::UInt(u) => Ok(u),
|
Arg::UInt(u) => Ok(u),
|
||||||
Arg::SInt(i, _w) => i.try_into().map_err(|_| Error::Overflow),
|
Arg::SInt(i) => i.try_into().map_err(|_| Error::Overflow),
|
||||||
_ => Err(Error::BadArgType),
|
_ => Err(Error::BadArgType),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,25 +68,18 @@ pub fn as_uint(&self) -> Result<u64, Error> {
|
|||||||
pub fn as_sint(&self) -> Result<i64, Error> {
|
pub fn as_sint(&self) -> Result<i64, Error> {
|
||||||
match *self {
|
match *self {
|
||||||
Arg::UInt(u) => u.try_into().map_err(|_| Error::Overflow),
|
Arg::UInt(u) => u.try_into().map_err(|_| Error::Overflow),
|
||||||
Arg::SInt(i, _w) => Ok(i),
|
Arg::SInt(i) => Ok(i),
|
||||||
_ => Err(Error::BadArgType),
|
_ => Err(Error::BadArgType),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a signed value, then return the sign (true if negative) and the magnitude,
|
/// Unwraps [`Arg::UInt`] to [`u64`].
|
||||||
// masked to the value's width. This allows for e.g. -1 to be returned as 0xFF, 0xFFFF, etc.
|
/// Unwraps [`Arg::SInt`] and casts the [`i64`] to [`u64`].
|
||||||
// depending on the original width.
|
/// Calling this on other variants of `[Arg]` is an error.
|
||||||
// If this is an unsigned value, simply return (false, u64).
|
pub fn as_wrapping_sint(&self) -> Result<u64, Error> {
|
||||||
pub fn as_wrapping_sint(&self) -> Result<(bool, u64), Error> {
|
|
||||||
match *self {
|
match *self {
|
||||||
Arg::UInt(u) => Ok((false, u)),
|
Arg::UInt(u) => Ok(u),
|
||||||
Arg::SInt(i, w) => {
|
Arg::SInt(i) => Ok(i as u64),
|
||||||
// Need to shift twice in case w is 64.
|
|
||||||
debug_assert!(w > 0);
|
|
||||||
let mask = ((1u64 << (w - 1)) << 1).wrapping_sub(1);
|
|
||||||
let ui = (i as u64) & mask;
|
|
||||||
Ok((i < 0, ui))
|
|
||||||
}
|
|
||||||
_ => Err(Error::BadArgType),
|
_ => Err(Error::BadArgType),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,7 +90,7 @@ pub fn as_float(&self) -> Result<f64, Error> {
|
|||||||
match *self {
|
match *self {
|
||||||
Arg::Float(f) => Ok(f),
|
Arg::Float(f) => Ok(f),
|
||||||
Arg::UInt(u) => Ok(u as f64),
|
Arg::UInt(u) => Ok(u as f64),
|
||||||
Arg::SInt(i, _w) => Ok(i as f64),
|
Arg::SInt(i) => Ok(i as f64),
|
||||||
_ => Err(Error::BadArgType),
|
_ => Err(Error::BadArgType),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,7 +174,7 @@ macro_rules! impl_to_arg {
|
|||||||
$(
|
$(
|
||||||
impl<'a> ToArg<'a> for $t {
|
impl<'a> ToArg<'a> for $t {
|
||||||
fn to_arg(self) -> Arg<'a> {
|
fn to_arg(self) -> Arg<'a> {
|
||||||
Arg::SInt(self as i64, <$t>::BITS as u8)
|
Arg::SInt(self as i64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
@@ -211,8 +204,6 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_to_arg() {
|
fn test_to_arg() {
|
||||||
const SIZE_WIDTH: u8 = isize::BITS as u8;
|
|
||||||
|
|
||||||
assert!(matches!("test".to_arg(), Arg::Str("test")));
|
assert!(matches!("test".to_arg(), Arg::Str("test")));
|
||||||
assert!(matches!(String::from("test").to_arg(), Arg::Str(_)));
|
assert!(matches!(String::from("test").to_arg(), Arg::Str(_)));
|
||||||
#[cfg(feature = "widestring")]
|
#[cfg(feature = "widestring")]
|
||||||
@@ -224,17 +215,17 @@ fn test_to_arg() {
|
|||||||
assert!(matches!('x'.to_arg(), Arg::UInt(120)));
|
assert!(matches!('x'.to_arg(), Arg::UInt(120)));
|
||||||
let mut usize_val: usize = 0;
|
let mut usize_val: usize = 0;
|
||||||
assert!(matches!((&mut usize_val).to_arg(), Arg::USizeRef(_)));
|
assert!(matches!((&mut usize_val).to_arg(), Arg::USizeRef(_)));
|
||||||
assert!(matches!(42i8.to_arg(), Arg::SInt(42, 8)));
|
assert!(matches!(42i8.to_arg(), Arg::SInt(42)));
|
||||||
assert!(matches!(42i16.to_arg(), Arg::SInt(42, 16)));
|
assert!(matches!(42i16.to_arg(), Arg::SInt(42)));
|
||||||
assert!(matches!(42i32.to_arg(), Arg::SInt(42, 32)));
|
assert!(matches!(42i32.to_arg(), Arg::SInt(42)));
|
||||||
assert!(matches!(42i64.to_arg(), Arg::SInt(42, 64)));
|
assert!(matches!(42i64.to_arg(), Arg::SInt(42)));
|
||||||
assert!(matches!(42isize.to_arg(), Arg::SInt(42, SIZE_WIDTH)));
|
assert!(matches!(42isize.to_arg(), Arg::SInt(42)));
|
||||||
|
|
||||||
assert_eq!((-42i8).to_arg(), Arg::SInt(-42, 8));
|
assert_eq!((-42i8).to_arg(), Arg::SInt(-42));
|
||||||
assert_eq!((-42i16).to_arg(), Arg::SInt(-42, 16));
|
assert_eq!((-42i16).to_arg(), Arg::SInt(-42));
|
||||||
assert_eq!((-42i32).to_arg(), Arg::SInt(-42, 32));
|
assert_eq!((-42i32).to_arg(), Arg::SInt(-42));
|
||||||
assert_eq!((-42i64).to_arg(), Arg::SInt(-42, 64));
|
assert_eq!((-42i64).to_arg(), Arg::SInt(-42));
|
||||||
assert_eq!((-42isize).to_arg(), Arg::SInt(-42, SIZE_WIDTH));
|
assert_eq!((-42isize).to_arg(), Arg::SInt(-42));
|
||||||
|
|
||||||
assert!(matches!(42u8.to_arg(), Arg::UInt(42)));
|
assert!(matches!(42u8.to_arg(), Arg::UInt(42)));
|
||||||
assert!(matches!(42u16.to_arg(), Arg::UInt(42)));
|
assert!(matches!(42u16.to_arg(), Arg::UInt(42)));
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
use super::locale::Locale;
|
use super::locale::Locale;
|
||||||
use super::printf_impl::{pad, ConversionSpec, Error, ModifierFlags};
|
use super::printf_impl::{ConversionSpec, Error, ModifierFlags, pad};
|
||||||
use decimal::{Decimal, DigitLimit, DIGIT_WIDTH};
|
use decimal::{DIGIT_WIDTH, Decimal, DigitLimit};
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
@@ -279,7 +279,6 @@ fn format_a(mut y: f64, params: FormatParams<'_, impl Write>) -> Result<usize, E
|
|||||||
|
|
||||||
// Compute the number of hex digits in the mantissa after the decimal.
|
// Compute the number of hex digits in the mantissa after the decimal.
|
||||||
// -1 for leading 1 bit (we are to the range [1, 2)), then divide by 4, rounding up.
|
// -1 for leading 1 bit (we are to the range [1, 2)), then divide by 4, rounding up.
|
||||||
#[allow(unknown_lints)] // for old clippy
|
|
||||||
#[allow(clippy::manual_div_ceil)]
|
#[allow(clippy::manual_div_ceil)]
|
||||||
const MANTISSA_HEX_DIGITS: usize = (MANTISSA_BITS - 1 + 3) / 4;
|
const MANTISSA_HEX_DIGITS: usize = (MANTISSA_BITS - 1 + 3) / 4;
|
||||||
if had_prec && prec < MANTISSA_HEX_DIGITS {
|
if had_prec && prec < MANTISSA_HEX_DIGITS {
|
||||||
|
|||||||
@@ -4,9 +4,8 @@
|
|||||||
|
|
||||||
mod fmt_fp;
|
mod fmt_fp;
|
||||||
mod printf_impl;
|
mod printf_impl;
|
||||||
pub use printf_impl::{sprintf_locale, Error, FormatString};
|
pub use printf_impl::{Error, FormatString, sprintf_locale};
|
||||||
pub mod locale;
|
pub mod locale;
|
||||||
pub use locale::{Locale, C_LOCALE, EN_US_LOCALE};
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|||||||
@@ -66,11 +66,7 @@ fn next_group_size(&self, digits_left: usize) -> usize {
|
|||||||
// Divide remaining digits by repeat_group.
|
// Divide remaining digits by repeat_group.
|
||||||
// Apply any remainder to the first group.
|
// Apply any remainder to the first group.
|
||||||
let res = (digits_left - accum) % (repeat_group as usize);
|
let res = (digits_left - accum) % (repeat_group as usize);
|
||||||
if res > 0 {
|
if res > 0 { res } else { repeat_group as usize }
|
||||||
res
|
|
||||||
} else {
|
|
||||||
repeat_group as usize
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,8 +118,12 @@ pub fn separator_count(&self, digits_count: usize) -> usize {
|
|||||||
group_repeat: true,
|
group_repeat: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[cfg(test)]
|
||||||
fn test_apply_grouping() {
|
mod tests {
|
||||||
|
use super::{C_LOCALE, EN_US_LOCALE, Locale};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_apply_grouping() {
|
||||||
let input = "123456789";
|
let input = "123456789";
|
||||||
let mut result: String;
|
let mut result: String;
|
||||||
|
|
||||||
@@ -157,18 +157,18 @@ fn test_apply_grouping() {
|
|||||||
locale.group_repeat = true;
|
locale.group_repeat = true;
|
||||||
result = locale.apply_grouping(input);
|
result = locale.apply_grouping(input);
|
||||||
assert_eq!(result, "1!23!45!67!8!901!23456");
|
assert_eq!(result, "1!23!45!67!8!901!23456");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_thousands_grouping_length_panics_if_no_sep() {
|
fn test_thousands_grouping_length_panics_if_no_sep() {
|
||||||
// We should panic if we try to group with no thousands separator.
|
// We should panic if we try to group with no thousands separator.
|
||||||
assert_eq!(C_LOCALE.thousands_sep, None);
|
assert_eq!(C_LOCALE.thousands_sep, None);
|
||||||
C_LOCALE.apply_grouping("123");
|
C_LOCALE.apply_grouping("123");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_thousands_grouping_length() {
|
fn test_thousands_grouping_length() {
|
||||||
fn validate_grouping_length_hint(locale: Locale, mut input: &str) {
|
fn validate_grouping_length_hint(locale: Locale, mut input: &str) {
|
||||||
loop {
|
loop {
|
||||||
let expected = locale.separator_count(input.len()) + input.len();
|
let expected = locale.separator_count(input.len()) + input.len();
|
||||||
@@ -204,4 +204,5 @@ fn validate_grouping_length_hint(locale: Locale, mut input: &str) {
|
|||||||
locale.grouping = [5, 3, 1, 2];
|
locale.grouping = [5, 3, 1, 2];
|
||||||
locale.group_repeat = true;
|
locale.group_repeat = true;
|
||||||
validate_grouping_length_hint(locale, input);
|
validate_grouping_length_hint(locale, input);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -472,7 +472,7 @@ pub fn sprintf_locale(
|
|||||||
// If someone passes us a negative value, format it with the width
|
// If someone passes us a negative value, format it with the width
|
||||||
// we were given.
|
// we were given.
|
||||||
let lower = conv_spec.is_lower();
|
let lower = conv_spec.is_lower();
|
||||||
let (_, uint) = arg.as_wrapping_sint()?;
|
let uint = arg.as_wrapping_sint()?;
|
||||||
if uint != 0 {
|
if uint != 0 {
|
||||||
if flags.alt_form {
|
if flags.alt_form {
|
||||||
prefix = if lower { "0x" } else { "0X" };
|
prefix = if lower { "0x" } else { "0X" };
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use crate::arg::ToArg;
|
use crate::arg::ToArg;
|
||||||
use crate::locale::{Locale, C_LOCALE, EN_US_LOCALE};
|
use crate::locale::{C_LOCALE, EN_US_LOCALE, Locale};
|
||||||
use crate::{sprintf_locale, Error, FormatString};
|
use crate::{Error, FormatString, sprintf_locale};
|
||||||
use libc::c_char;
|
use libc::c_char;
|
||||||
use std::f64::consts::{E, PI, TAU};
|
use std::f64::consts::{E, PI, TAU};
|
||||||
|
use std::ffi::CStr;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
// sprintf, checking length
|
// sprintf, checking length
|
||||||
@@ -77,7 +78,7 @@ fn write_str(&mut self, _s: &str) -> fmt::Result {
|
|||||||
#[test]
|
#[test]
|
||||||
fn smoke() {
|
fn smoke() {
|
||||||
assert_fmt!("Hello, %s!", "world" => "Hello, world!");
|
assert_fmt!("Hello, %s!", "world" => "Hello, world!");
|
||||||
assert_fmt!("Hello, %ls!", "world" => "Hello, world!");
|
assert_fmt!("Hello, %ls!", "world" => "Hello, world!"); // length modifier
|
||||||
assert_fmt!("Hello, world! %d %%%%", 3 => "Hello, world! 3 %%");
|
assert_fmt!("Hello, world! %d %%%%", 3 => "Hello, world! 3 %%");
|
||||||
assert_fmt!("" => "");
|
assert_fmt!("" => "");
|
||||||
}
|
}
|
||||||
@@ -225,7 +226,7 @@ fn test_int() {
|
|||||||
assert_fmt!("%d", -123 => "-123");
|
assert_fmt!("%d", -123 => "-123");
|
||||||
assert_fmt!("~%d~", 148 => "~148~");
|
assert_fmt!("~%d~", 148 => "~148~");
|
||||||
assert_fmt!("00%dxx", -91232 => "00-91232xx");
|
assert_fmt!("00%dxx", -91232 => "00-91232xx");
|
||||||
assert_fmt!("%x", -9232 => "ffffdbf0");
|
assert_fmt!("%x", -9232 => "ffffffffffffdbf0");
|
||||||
assert_fmt!("%X", 432 => "1B0");
|
assert_fmt!("%X", 432 => "1B0");
|
||||||
assert_fmt!("%09X", 432 => "0000001B0");
|
assert_fmt!("%09X", 432 => "0000001B0");
|
||||||
assert_fmt!("%9X", 432 => " 1B0");
|
assert_fmt!("%9X", 432 => " 1B0");
|
||||||
@@ -234,6 +235,7 @@ fn test_int() {
|
|||||||
assert_fmt!("%2o", 4 => " 4");
|
assert_fmt!("%2o", 4 => " 4");
|
||||||
assert_fmt!("% 12d", -4 => " -4");
|
assert_fmt!("% 12d", -4 => " -4");
|
||||||
assert_fmt!("% 12d", 48 => " 48");
|
assert_fmt!("% 12d", 48 => " 48");
|
||||||
|
// with length modifier
|
||||||
assert_fmt!("%ld", -4_i64 => "-4");
|
assert_fmt!("%ld", -4_i64 => "-4");
|
||||||
assert_fmt!("%lld", -4_i64 => "-4");
|
assert_fmt!("%lld", -4_i64 => "-4");
|
||||||
assert_fmt!("%lX", -4_i64 => "FFFFFFFFFFFFFFFC");
|
assert_fmt!("%lX", -4_i64 => "FFFFFFFFFFFFFFFC");
|
||||||
@@ -248,6 +250,7 @@ fn test_int() {
|
|||||||
assert_fmt!("%9X", 492 => " 1EC");
|
assert_fmt!("%9X", 492 => " 1EC");
|
||||||
assert_fmt!("% 12u", 4 => " 4");
|
assert_fmt!("% 12u", 4 => " 4");
|
||||||
assert_fmt!("% 12u", 48 => " 48");
|
assert_fmt!("% 12u", 48 => " 48");
|
||||||
|
// with length modifier
|
||||||
assert_fmt!("%lu", 4_u64 => "4");
|
assert_fmt!("%lu", 4_u64 => "4");
|
||||||
assert_fmt!("%llu", 4_u64 => "4");
|
assert_fmt!("%llu", 4_u64 => "4");
|
||||||
assert_fmt!("%lX", 4_u64 => "4");
|
assert_fmt!("%lX", 4_u64 => "4");
|
||||||
@@ -414,6 +417,7 @@ fn test_float() {
|
|||||||
assert_fmt1!("%f", 0.0, "0.000000");
|
assert_fmt1!("%f", 0.0, "0.000000");
|
||||||
assert_fmt1!("%g", 0.0, "0");
|
assert_fmt1!("%g", 0.0, "0");
|
||||||
assert_fmt1!("%#g", 0.0, "0.00000");
|
assert_fmt1!("%#g", 0.0, "0.00000");
|
||||||
|
// with length modifier
|
||||||
assert_fmt1!("%la", 0.0, "0x0p+0");
|
assert_fmt1!("%la", 0.0, "0x0p+0");
|
||||||
assert_fmt1!("%le", 0.0, "0.000000e+00");
|
assert_fmt1!("%le", 0.0, "0.000000e+00");
|
||||||
assert_fmt1!("%lf", 0.0, "0.000000");
|
assert_fmt1!("%lf", 0.0, "0.000000");
|
||||||
@@ -430,7 +434,7 @@ fn test_float() {
|
|||||||
assert_fmt1!("%.4f", 1.03125, "1.0312"); /* 0x1.08p0 */
|
assert_fmt1!("%.4f", 1.03125, "1.0312"); /* 0x1.08p0 */
|
||||||
assert_fmt1!("%.2f", 1.375, "1.38");
|
assert_fmt1!("%.2f", 1.375, "1.38");
|
||||||
assert_fmt1!("%.1f", 1.375, "1.4");
|
assert_fmt1!("%.1f", 1.375, "1.4");
|
||||||
assert_fmt1!("%.1lf", 1.375, "1.4");
|
assert_fmt1!("%.1lf", 1.375, "1.4"); // length modifier
|
||||||
assert_fmt1!("%.15f", 1.1, "1.100000000000000");
|
assert_fmt1!("%.15f", 1.1, "1.100000000000000");
|
||||||
assert_fmt1!("%.16f", 1.1, "1.1000000000000001");
|
assert_fmt1!("%.16f", 1.1, "1.1000000000000001");
|
||||||
assert_fmt1!("%.17f", 1.1, "1.10000000000000009");
|
assert_fmt1!("%.17f", 1.1, "1.10000000000000009");
|
||||||
@@ -755,8 +759,8 @@ fn test_errors() {
|
|||||||
sprintf_err!("%1", => BadFormatString);
|
sprintf_err!("%1", => BadFormatString);
|
||||||
sprintf_err!("%%%k", => BadFormatString);
|
sprintf_err!("%%%k", => BadFormatString);
|
||||||
sprintf_err!("%B", => BadFormatString);
|
sprintf_err!("%B", => BadFormatString);
|
||||||
sprintf_err!("%lC", 'q' => BadFormatString);
|
sprintf_err!("%lC", 'q' => BadFormatString); // length modifier
|
||||||
sprintf_err!("%lS", 'q' => BadFormatString);
|
sprintf_err!("%lS", 'q' => BadFormatString); // length modifier
|
||||||
sprintf_err!("%d", => MissingArg);
|
sprintf_err!("%d", => MissingArg);
|
||||||
sprintf_err!("%d %u", 1 => MissingArg);
|
sprintf_err!("%d %u", 1 => MissingArg);
|
||||||
sprintf_err!("%*d", 5 => MissingArg);
|
sprintf_err!("%*d", 5 => MissingArg);
|
||||||
@@ -852,25 +856,20 @@ fn test_float_hex_prec() {
|
|||||||
// Note that our hex float formatting rounds according to the rounding mode,
|
// Note that our hex float formatting rounds according to the rounding mode,
|
||||||
// while libc may not; as a result we may differ in the last digit. So this
|
// while libc may not; as a result we may differ in the last digit. So this
|
||||||
// requires manual comparison.
|
// requires manual comparison.
|
||||||
let mut c_storage = [0u8; 256];
|
|
||||||
let c_storage_ptr = c_storage.as_mut_ptr() as *mut c_char;
|
|
||||||
let mut rust_str = String::with_capacity(256);
|
let mut rust_str = String::with_capacity(256);
|
||||||
|
|
||||||
let c_fmt = b"%.*a\0".as_ptr() as *const c_char;
|
let mut c_storage = [0u8; 256];
|
||||||
|
let mut libc_sprintf = libc_sprintf_one_float_with_precision(&mut c_storage, c"%.*a");
|
||||||
|
|
||||||
let mut failed = false;
|
let mut failed = false;
|
||||||
for sign in [1.0, -1.0].into_iter() {
|
for sign in [1.0, -1.0].into_iter() {
|
||||||
for mut v in [0.0, 0.5, 1.0, 1.5, PI, TAU, E].into_iter() {
|
for mut v in [0.0, 0.5, 1.0, 1.5, PI, TAU, E].into_iter() {
|
||||||
v *= sign;
|
v *= sign;
|
||||||
for preci in 1..=200_i32 {
|
for preci in 1..=200_usize {
|
||||||
rust_str.clear();
|
rust_str.clear();
|
||||||
crate::sprintf!(=> &mut rust_str, "%.*a", preci, v);
|
crate::sprintf!(=> &mut rust_str, "%.*a", preci, v);
|
||||||
|
|
||||||
let printf_str = unsafe {
|
let printf_str = libc_sprintf(preci, v);
|
||||||
let len = libc::snprintf(c_storage_ptr, c_storage.len(), c_fmt, preci, v);
|
|
||||||
assert!(len >= 0);
|
|
||||||
let sl = std::slice::from_raw_parts(c_storage_ptr as *const u8, len as usize);
|
|
||||||
std::str::from_utf8(sl).unwrap()
|
|
||||||
};
|
|
||||||
if rust_str != printf_str {
|
if rust_str != printf_str {
|
||||||
println!(
|
println!(
|
||||||
"Our printf and libc disagree on hex formatting of float: {v}
|
"Our printf and libc disagree on hex formatting of float: {v}
|
||||||
@@ -886,14 +885,27 @@ fn test_float_hex_prec() {
|
|||||||
assert!(!failed);
|
assert!(!failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_exhaustive(rust_fmt: &str, c_fmt: *const c_char) {
|
fn libc_sprintf_one_float_with_precision<'a>(
|
||||||
|
storage: &'a mut [u8],
|
||||||
|
fmt: &'a CStr,
|
||||||
|
) -> impl FnMut(usize, f64) -> &'a str {
|
||||||
|
|preci, float_val| unsafe {
|
||||||
|
let storage_ptr = storage.as_mut_ptr() as *mut c_char;
|
||||||
|
let len = libc::snprintf(storage_ptr, storage.len(), fmt.as_ptr(), preci, float_val);
|
||||||
|
assert!(len >= 0);
|
||||||
|
let sl = std::slice::from_raw_parts(storage_ptr as *const u8, len as usize);
|
||||||
|
std::str::from_utf8(sl).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_exhaustive(rust_fmt: &str, c_fmt: &CStr) {
|
||||||
// "There's only 4 billion floats so test them all."
|
// "There's only 4 billion floats so test them all."
|
||||||
// This tests a format string expected to be of the form "%.*g" or "%.*e".
|
// This tests a format string expected to be of the form "%.*g" or "%.*e".
|
||||||
// That is, it takes a precision and a double.
|
// That is, it takes a precision and a double.
|
||||||
println!("Testing {rust_fmt}");
|
println!("Testing {rust_fmt}");
|
||||||
let mut rust_str = String::with_capacity(128);
|
let mut rust_str = String::with_capacity(128);
|
||||||
let mut c_storage = [0u8; 128];
|
let mut c_storage = [0u8; 128];
|
||||||
let c_storage_ptr = c_storage.as_mut_ptr() as *mut c_char;
|
let mut libc_sprintf = libc_sprintf_one_float_with_precision(&mut c_storage, c_fmt);
|
||||||
|
|
||||||
for i in 0..=u32::MAX {
|
for i in 0..=u32::MAX {
|
||||||
if i % 1000000 == 0 {
|
if i % 1000000 == 0 {
|
||||||
@@ -905,12 +917,7 @@ fn test_exhaustive(rust_fmt: &str, c_fmt: *const c_char) {
|
|||||||
rust_str.clear();
|
rust_str.clear();
|
||||||
crate::sprintf!(=> &mut rust_str, rust_fmt, preci, ff);
|
crate::sprintf!(=> &mut rust_str, rust_fmt, preci, ff);
|
||||||
|
|
||||||
let printf_str = unsafe {
|
let printf_str = libc_sprintf(preci, ff);
|
||||||
let len = libc::snprintf(c_storage_ptr, c_storage.len(), c_fmt, preci, ff);
|
|
||||||
assert!(len >= 0);
|
|
||||||
let sl = std::slice::from_raw_parts(c_storage_ptr as *const u8, len as usize);
|
|
||||||
std::str::from_utf8(sl).unwrap()
|
|
||||||
};
|
|
||||||
if rust_str != printf_str {
|
if rust_str != printf_str {
|
||||||
println!(
|
println!(
|
||||||
"Rust and libc disagree on formatting float {i:x}: {ff}\n
|
"Rust and libc disagree on formatting float {i:x}: {ff}\n
|
||||||
@@ -929,19 +936,19 @@ fn test_exhaustive(rust_fmt: &str, c_fmt: *const c_char) {
|
|||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_float_g_exhaustive() {
|
fn test_float_g_exhaustive() {
|
||||||
// To run: cargo test test_float_g_exhaustive --release -- --ignored --nocapture
|
// To run: cargo test test_float_g_exhaustive --release -- --ignored --nocapture
|
||||||
test_exhaustive("%.*g", b"%.*g\0".as_ptr() as *const c_char);
|
test_exhaustive("%.*g", c"%.*g");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_float_e_exhaustive() {
|
fn test_float_e_exhaustive() {
|
||||||
// To run: cargo test test_float_e_exhaustive --release -- --ignored --nocapture
|
// To run: cargo test test_float_e_exhaustive --release -- --ignored --nocapture
|
||||||
test_exhaustive("%.*e", b"%.*e\0".as_ptr() as *const c_char);
|
test_exhaustive("%.*e", c"%.*e");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
fn test_float_f_exhaustive() {
|
fn test_float_f_exhaustive() {
|
||||||
// To run: cargo test test_float_f_exhaustive --release -- --ignored --nocapture
|
// To run: cargo test test_float_f_exhaustive --release -- --ignored --nocapture
|
||||||
test_exhaustive("%.*f", b"%.*f\0".as_ptr() as *const c_char);
|
test_exhaustive("%.*f", c"%.*f");
|
||||||
}
|
}
|
||||||
|
|||||||
12
crates/tempfile/Cargo.toml
Normal file
12
crates/tempfile/Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[package]
|
||||||
|
name = "fish-tempfile"
|
||||||
|
edition.workspace = true
|
||||||
|
rust-version.workspace = true
|
||||||
|
version = "0.0.0"
|
||||||
|
repository.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
nix = { workspace = true, features = ["fs", "feature"] }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
127
crates/tempfile/src/lib.rs
Normal file
127
crates/tempfile/src/lib.rs
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
use std::{fs::File, path::PathBuf};
|
||||||
|
|
||||||
|
pub struct TempFile {
|
||||||
|
file: File,
|
||||||
|
path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TempFile {
|
||||||
|
pub fn get(&self) -> &File {
|
||||||
|
&self.file
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_mut(&mut self) -> &mut File {
|
||||||
|
&mut self.file
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path(&self) -> &PathBuf {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for TempFile {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let _ = std::fs::remove_file(&self.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TempDir {
|
||||||
|
path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TempDir {
|
||||||
|
pub fn path(&self) -> &PathBuf {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for TempDir {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let _ = std::fs::remove_dir_all(&self.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_tmpdir() -> PathBuf {
|
||||||
|
PathBuf::from(std::env::var_os("TMPDIR").unwrap_or("/tmp".into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_template() -> PathBuf {
|
||||||
|
get_tmpdir().join("fish_tmp_XXXXXX")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tries to create a new temporary file using `mkstemp`.
|
||||||
|
/// On success, a [`TempFile`] is returned.
|
||||||
|
/// When this struct is dropped, the backing file will be deleted.
|
||||||
|
pub fn new_file() -> std::io::Result<TempFile> {
|
||||||
|
let (fd, path) = nix::unistd::mkstemp(&get_template())?;
|
||||||
|
let file = File::from(fd);
|
||||||
|
Ok(TempFile { file, path })
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tries to create a new temporary directory using `mkdtemp`.
|
||||||
|
/// On success, a [`TempDir`] is returned.
|
||||||
|
/// When this struct is dropped, the backing directory, including all its contents, will be deleted.
|
||||||
|
pub fn new_dir() -> std::io::Result<TempDir> {
|
||||||
|
let path = nix::unistd::mkdtemp(&get_template())?;
|
||||||
|
Ok(TempDir { path })
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::{
|
||||||
|
fs::File,
|
||||||
|
io::{Read, Seek, Write},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn create_tempfile() {
|
||||||
|
super::new_file().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "file should no longer exist")]
|
||||||
|
fn use_tempfile() {
|
||||||
|
let mut tempfile = super::new_file().unwrap();
|
||||||
|
let expected_content = "test";
|
||||||
|
{
|
||||||
|
let file = tempfile.get_mut();
|
||||||
|
file.write_all(expected_content.as_bytes()).unwrap();
|
||||||
|
file.seek(std::io::SeekFrom::Start(0)).unwrap();
|
||||||
|
}
|
||||||
|
let mut actual_content = String::new();
|
||||||
|
{
|
||||||
|
let mut file = tempfile.get();
|
||||||
|
file.read_to_string(&mut actual_content).unwrap();
|
||||||
|
}
|
||||||
|
let path = tempfile.path().to_owned();
|
||||||
|
drop(tempfile);
|
||||||
|
assert_eq!(expected_content, actual_content);
|
||||||
|
File::open(&path).expect("file should no longer exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn create_tempdir() {
|
||||||
|
super::new_dir().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "file should no longer exist")]
|
||||||
|
fn use_tempdir() {
|
||||||
|
let tempdir = super::new_dir().unwrap();
|
||||||
|
let file_path = tempdir.path().join("foo");
|
||||||
|
let expected_content = "test";
|
||||||
|
{
|
||||||
|
let mut file = File::create(&file_path).unwrap();
|
||||||
|
file.write_all(expected_content.as_bytes()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut file = File::open(&file_path).unwrap();
|
||||||
|
let mut actual_content = String::new();
|
||||||
|
file.read_to_string(&mut actual_content).unwrap();
|
||||||
|
assert_eq!(expected_content, actual_content);
|
||||||
|
}
|
||||||
|
drop(tempdir);
|
||||||
|
File::open(&file_path).expect("file should no longer exist");
|
||||||
|
}
|
||||||
|
}
|
||||||
7
debian/control
vendored
7
debian/control
vendored
@@ -4,11 +4,12 @@ Priority: optional
|
|||||||
Maintainer: ridiculous_fish <corydoras@ridiculousfish.com>
|
Maintainer: ridiculous_fish <corydoras@ridiculousfish.com>
|
||||||
Uploaders: David Adam <zanchey@ucc.gu.uwa.edu.au>
|
Uploaders: David Adam <zanchey@ucc.gu.uwa.edu.au>
|
||||||
Build-Depends: debhelper (>= 12),
|
Build-Depends: debhelper (>= 12),
|
||||||
cargo (>= 0.66) | cargo-mozilla (>= 0.66),
|
# -web is for Debian's updated version, -X.Y is for Ubuntu's backported versions
|
||||||
cmake (>= 3.15.0) | cmake-mozilla (>= 3.15.0),
|
cargo (>= 1.85) | cargo-web (>= 1.85) | cargo-1.85,
|
||||||
|
cmake (>= 3.15.0),
|
||||||
gettext,
|
gettext,
|
||||||
libpcre2-dev,
|
libpcre2-dev,
|
||||||
rustc (>= 1.70),
|
rustc (>= 1.85) | rustc-web (>= 1.85) | rustc-1.85,
|
||||||
# Test dependencies
|
# Test dependencies
|
||||||
locales-all,
|
locales-all,
|
||||||
ncurses-base,
|
ncurses-base,
|
||||||
|
|||||||
8
debian/rules
vendored
8
debian/rules
vendored
@@ -8,13 +8,15 @@ export DH_VERBOSE=1
|
|||||||
export DEB_BUILD_MAINT_OPTIONS=optimize=-lto
|
export DEB_BUILD_MAINT_OPTIONS=optimize=-lto
|
||||||
|
|
||||||
%:
|
%:
|
||||||
dh $@
|
dh $@ --buildsystem=cmake --builddirectory=build
|
||||||
|
|
||||||
# Setting the build system is still required, because otherwise the GNUmakefile gets picked up
|
# Setting the build system is still required, because otherwise the GNUmakefile gets picked up
|
||||||
override_dh_auto_configure:
|
override_dh_auto_configure:
|
||||||
ln -s cargo-vendor/vendor vendor
|
ln -s cargo-vendor/vendor vendor
|
||||||
ln -s cargo-vendor/.cargo .cargo
|
ln -s cargo-vendor/.cargo .cargo
|
||||||
dh_auto_configure --buildsystem=cmake -- -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
dh_auto_configure -- -DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||||
|
-DRust_CARGO=$$(command -v cargo-1.85 || command -v cargo) \
|
||||||
|
-DRust_COMPILER=$$(command -v rustc-1.85 || command -v rustc)
|
||||||
|
|
||||||
override_dh_clean:
|
override_dh_clean:
|
||||||
dh_clean --exclude=Cargo.toml.orig
|
dh_clean --exclude=Cargo.toml.orig
|
||||||
@@ -22,4 +24,4 @@ override_dh_clean:
|
|||||||
-unlink vendor
|
-unlink vendor
|
||||||
|
|
||||||
override_dh_auto_test:
|
override_dh_auto_test:
|
||||||
make fish_run_tests
|
cd build && make fish_run_tests
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ We use forks of the last two - see the [FFI section](#ffi) below. No special act
|
|||||||
|
|
||||||
### Build Dependencies
|
### Build Dependencies
|
||||||
|
|
||||||
fish-shell currently depends on Rust 1.70 or later. To install Rust, follow https://rustup.rs.
|
fish-shell currently depends on Rust 1.85 or later. To install Rust, follow https://rustup.rs.
|
||||||
|
|
||||||
### Build via CMake
|
### Build via CMake
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-_:
|
|
||||||
|
|
||||||
_ - call fish's translations
|
_ - call fish's translations
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-abbr:
|
|
||||||
|
|
||||||
abbr - manage fish abbreviations
|
abbr - manage fish abbreviations
|
||||||
================================
|
================================
|
||||||
|
|
||||||
@@ -10,8 +8,8 @@ Synopsis
|
|||||||
|
|
||||||
abbr --add NAME [--position command | anywhere] [-r | --regex PATTERN] [-c | --command COMMAND]
|
abbr --add NAME [--position command | anywhere] [-r | --regex PATTERN] [-c | --command COMMAND]
|
||||||
[--set-cursor[=MARKER]] ([-f | --function FUNCTION] | EXPANSION)
|
[--set-cursor[=MARKER]] ([-f | --function FUNCTION] | EXPANSION)
|
||||||
abbr --erase NAME ...
|
abbr --erase [ [-c | --command COMMAND]... ] NAME ...
|
||||||
abbr --rename OLD_WORD NEW_WORD
|
abbr --rename [ [-c | --command COMMAND]... ] OLD_WORD NEW_WORD
|
||||||
abbr --show
|
abbr --show
|
||||||
abbr --list
|
abbr --list
|
||||||
abbr --query NAME ...
|
abbr --query NAME ...
|
||||||
@@ -136,9 +134,10 @@ Other subcommands
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
abbr --rename OLD_NAME NEW_NAME
|
abbr --rename [ [-c | --command COMMAND]... ] OLD_NAME NEW_NAME
|
||||||
|
|
||||||
Renames an abbreviation, from *OLD_NAME* to *NEW_NAME*
|
Renames an abbreviation, from *OLD_NAME* to *NEW_NAME*.
|
||||||
|
For command-specific abbreviations, the ``--command`` options must be provided to disambiguate which abbreviation to rename.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@@ -154,9 +153,10 @@ Prints the names of all abbreviation
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
abbr [-e | --erase] NAME
|
abbr [-e | --erase] [ [-c | --command COMMAND]... ] NAME ...
|
||||||
|
|
||||||
Erases the abbreviation with the given name
|
Erases the abbreviation with the given name.
|
||||||
|
For command-specific abbreviations, the ``--command`` options must be provided to disambiguate which abbreviation to rename.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-alias:
|
|
||||||
|
|
||||||
alias - create a function
|
alias - create a function
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-and:
|
|
||||||
|
|
||||||
and - conditionally execute a command
|
and - conditionally execute a command
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-argparse:
|
|
||||||
|
|
||||||
argparse - parse options passed to a fish script or function
|
argparse - parse options passed to a fish script or function
|
||||||
============================================================
|
============================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-begin:
|
|
||||||
|
|
||||||
begin - start a new block of code
|
begin - start a new block of code
|
||||||
=================================
|
=================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-bg:
|
|
||||||
|
|
||||||
bg - send jobs to background
|
bg - send jobs to background
|
||||||
============================
|
============================
|
||||||
|
|
||||||
@@ -42,6 +40,6 @@ The typical use is to run something, stop it with ctrl-z, and then continue it i
|
|||||||
|
|
||||||
If only 123 and 789 exist, it will still background them and print an error about 456.
|
If only 123 and 789 exist, it will still background them and print an error about 456.
|
||||||
|
|
||||||
``bg 123 banana`` or ``bg banana 123`` will complain that "banana" is not a valid job specifier.
|
``bg 123 banana`` or ``bg banana 123`` will complain that "banana" is not a valid process ID.
|
||||||
|
|
||||||
``bg %2`` will background job 2.
|
``bg %2`` will background job 2.
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-bind:
|
|
||||||
|
|
||||||
bind - handle fish key bindings
|
bind - handle fish key bindings
|
||||||
===============================
|
===============================
|
||||||
Synopsis
|
Synopsis
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-block:
|
|
||||||
|
|
||||||
block - temporarily block delivery of events
|
block - temporarily block delivery of events
|
||||||
============================================
|
============================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-break:
|
|
||||||
|
|
||||||
break - stop the current inner loop
|
break - stop the current inner loop
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-breakpoint:
|
|
||||||
|
|
||||||
breakpoint - launch debug mode
|
breakpoint - launch debug mode
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-builtin:
|
|
||||||
|
|
||||||
builtin - run a builtin command
|
builtin - run a builtin command
|
||||||
===============================
|
===============================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-case:
|
|
||||||
|
|
||||||
case - conditionally execute a block of commands
|
case - conditionally execute a block of commands
|
||||||
================================================
|
================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-cd:
|
|
||||||
|
|
||||||
cd - change directory
|
cd - change directory
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-cdh:
|
|
||||||
|
|
||||||
cdh - change to a recently visited directory
|
cdh - change to a recently visited directory
|
||||||
============================================
|
============================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-command:
|
|
||||||
|
|
||||||
command - run a program
|
command - run a program
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-commandline:
|
|
||||||
|
|
||||||
commandline - set or get the current command line buffer
|
commandline - set or get the current command line buffer
|
||||||
========================================================
|
========================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-complete:
|
|
||||||
|
|
||||||
complete - edit command-specific tab-completions
|
complete - edit command-specific tab-completions
|
||||||
================================================
|
================================================
|
||||||
|
|
||||||
@@ -16,7 +14,7 @@ Description
|
|||||||
|
|
||||||
``complete`` defines, removes or lists completions for a command.
|
``complete`` defines, removes or lists completions for a command.
|
||||||
|
|
||||||
For an introduction to writing your own completions, see :ref:`Writing your own completions <completion-own>` in
|
For an introduction to writing your own completions, see :doc:`Writing your own completions <../completions>` in
|
||||||
the fish manual.
|
the fish manual.
|
||||||
|
|
||||||
The following options are available:
|
The following options are available:
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-contains:
|
|
||||||
|
|
||||||
contains - test if a word is present in a list
|
contains - test if a word is present in a list
|
||||||
==============================================
|
==============================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-continue:
|
|
||||||
|
|
||||||
continue - skip the remainder of the current iteration of the current inner loop
|
continue - skip the remainder of the current iteration of the current inner loop
|
||||||
================================================================================
|
================================================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-count:
|
|
||||||
|
|
||||||
count - count the number of elements of a list
|
count - count the number of elements of a list
|
||||||
================================================
|
================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-dirh:
|
|
||||||
|
|
||||||
dirh - print directory history
|
dirh - print directory history
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-dirs:
|
|
||||||
|
|
||||||
dirs - print directory stack
|
dirs - print directory stack
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-disown:
|
|
||||||
|
|
||||||
disown - remove a process from the list of jobs
|
disown - remove a process from the list of jobs
|
||||||
===============================================
|
===============================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-echo:
|
|
||||||
|
|
||||||
echo - display a line of text
|
echo - display a line of text
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-else:
|
|
||||||
|
|
||||||
else - execute command if a condition is not met
|
else - execute command if a condition is not met
|
||||||
================================================
|
================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-emit:
|
|
||||||
|
|
||||||
emit - emit a generic event
|
emit - emit a generic event
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-end:
|
|
||||||
|
|
||||||
end - end a block of commands
|
end - end a block of commands
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-eval:
|
|
||||||
|
|
||||||
eval - evaluate the specified commands
|
eval - evaluate the specified commands
|
||||||
======================================
|
======================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-exec:
|
|
||||||
|
|
||||||
exec - execute command in current process
|
exec - execute command in current process
|
||||||
=========================================
|
=========================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
.. _cmd-exit:
|
|
||||||
.. program::exit
|
|
||||||
|
|
||||||
exit - exit the shell
|
exit - exit the shell
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-export:
|
|
||||||
|
|
||||||
export - compatibility function for exporting variables
|
export - compatibility function for exporting variables
|
||||||
=======================================================
|
=======================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-false:
|
|
||||||
|
|
||||||
false - return an unsuccessful result
|
false - return an unsuccessful result
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-fg:
|
|
||||||
|
|
||||||
fg - bring job to foreground
|
fg - bring job to foreground
|
||||||
============================
|
============================
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
.. _cmd-fish:
|
|
||||||
.. program::fish
|
|
||||||
|
|
||||||
fish - the friendly interactive shell
|
fish - the friendly interactive shell
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
@@ -18,7 +15,7 @@ Description
|
|||||||
:command:`fish` is a command-line shell written mainly with interactive use in mind.
|
:command:`fish` is a command-line shell written mainly with interactive use in mind.
|
||||||
This page briefly describes the options for invoking :command:`fish`.
|
This page briefly describes the options for invoking :command:`fish`.
|
||||||
The :ref:`full manual <intro>` is available in HTML by using the :command:`help` command from inside fish, and in the `fish-doc(1)` man page.
|
The :ref:`full manual <intro>` is available in HTML by using the :command:`help` command from inside fish, and in the `fish-doc(1)` man page.
|
||||||
The :ref:`tutorial <tutorial>` is available as HTML via ``help tutorial`` or in `man fish-tutorial`.
|
The :doc:`tutorial <../tutorial>` is available as HTML via ``help tutorial`` or in `man fish-tutorial`.
|
||||||
|
|
||||||
|
|
||||||
The following options are available:
|
The following options are available:
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
.. _cmd-fish_add_path:
|
|
||||||
.. program::fish_add_path
|
|
||||||
|
|
||||||
fish_add_path - add to the path
|
fish_add_path - add to the path
|
||||||
==============================================================
|
==============================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-fish_breakpoint_prompt:
|
|
||||||
|
|
||||||
fish_breakpoint_prompt - define the prompt when stopped at a breakpoint
|
fish_breakpoint_prompt - define the prompt when stopped at a breakpoint
|
||||||
=======================================================================
|
=======================================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-fish_clipboard_copy:
|
|
||||||
|
|
||||||
fish_clipboard_copy - copy text to the system's clipboard
|
fish_clipboard_copy - copy text to the system's clipboard
|
||||||
==============================================================
|
==============================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-fish_clipboard_paste:
|
|
||||||
|
|
||||||
fish_clipboard_paste - get text from the system's clipboard
|
fish_clipboard_paste - get text from the system's clipboard
|
||||||
==============================================================
|
==============================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-fish_command_not_found:
|
|
||||||
|
|
||||||
fish_command_not_found - what to do when a command wasn't found
|
fish_command_not_found - what to do when a command wasn't found
|
||||||
===============================================================
|
===============================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-fish_config:
|
|
||||||
|
|
||||||
fish_config - start the web-based configuration interface
|
fish_config - start the web-based configuration interface
|
||||||
=========================================================
|
=========================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-fish_default_key_bindings:
|
|
||||||
|
|
||||||
fish_default_key_bindings - set emacs key bindings for fish
|
fish_default_key_bindings - set emacs key bindings for fish
|
||||||
===============================================================
|
===============================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-fish_git_prompt:
|
|
||||||
|
|
||||||
fish_git_prompt - output git information for use in a prompt
|
fish_git_prompt - output git information for use in a prompt
|
||||||
============================================================
|
============================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-fish_greeting:
|
|
||||||
|
|
||||||
fish_greeting - display a welcome message in interactive shells
|
fish_greeting - display a welcome message in interactive shells
|
||||||
===============================================================
|
===============================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
.. _cmd-fish_hg_prompt:
|
|
||||||
|
|
||||||
fish_hg_prompt - output Mercurial information for use in a prompt
|
fish_hg_prompt - output Mercurial information for use in a prompt
|
||||||
=================================================================
|
=================================================================
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
.. _cmd-fish_indent:
|
|
||||||
.. program::fish_indent
|
|
||||||
|
|
||||||
fish_indent - indenter and prettifier
|
fish_indent - indenter and prettifier
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user