mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-10 09:41:16 -03:00
Compare commits
40 Commits
4.2.1
...
coverity_s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9da2f9c77 | ||
|
|
62b69532b1 | ||
|
|
2f1e8d9f8b | ||
|
|
64c8cee001 | ||
|
|
2ea6b8c128 | ||
|
|
ed844fa0ac | ||
|
|
b0bda695b5 | ||
|
|
e945a5f179 | ||
|
|
dfeccf2a1e | ||
|
|
593675e05e | ||
|
|
50a5460c17 | ||
|
|
172436f508 | ||
|
|
10a3eedcab | ||
|
|
53d8d9e0d9 | ||
|
|
642edbc434 | ||
|
|
d85bf9c0da | ||
|
|
37503f5f01 | ||
|
|
193dbe2a78 | ||
|
|
e95b9c16f0 | ||
|
|
d1bfea9ee5 | ||
|
|
c9c2cd069d | ||
|
|
c5409335ee | ||
|
|
db9259210d | ||
|
|
998b878dda | ||
|
|
32e2d36a7a | ||
|
|
37dc28f354 | ||
|
|
20ee1ce94b | ||
|
|
5c95da56a4 | ||
|
|
82325778a5 | ||
|
|
49d8e71e1f | ||
|
|
a9d1fb23da | ||
|
|
d8d194af63 | ||
|
|
85295488a6 | ||
|
|
7a8c5f53d5 | ||
|
|
bec4c374f5 | ||
|
|
d925862350 | ||
|
|
1f2a2de414 | ||
|
|
c21d880f34 | ||
|
|
e1dde5d7e1 | ||
|
|
66d7850b18 |
@@ -1,26 +1,24 @@
|
||||
image: alpine/edge
|
||||
packages:
|
||||
- cargo
|
||||
- cmake
|
||||
- ninja
|
||||
- ncurses-dev
|
||||
- pcre2-dev
|
||||
- py3-pexpect
|
||||
- python3
|
||||
- rust
|
||||
- tmux
|
||||
- expect
|
||||
- python
|
||||
sources:
|
||||
- https://github.com/fish-shell/fish-shell
|
||||
- https://git.sr.ht/~faho/fish
|
||||
tasks:
|
||||
- build: |
|
||||
cd fish-shell
|
||||
mkdir build
|
||||
cd fish
|
||||
mkdir build || :
|
||||
cd build
|
||||
cmake -G Ninja .. \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_INSTALL_DATADIR=share \
|
||||
-DCMAKE_INSTALL_DOCDIR=share/doc/fish \
|
||||
-DCMAKE_INSTALL_SYSCONFDIR=/etc
|
||||
-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
|
||||
cd fish/build
|
||||
env SHOW_INTERACTIVE_LOG=1 ninja test
|
||||
|
||||
@@ -2,9 +2,8 @@ image: archlinux
|
||||
packages:
|
||||
- cmake
|
||||
- ninja
|
||||
- expect
|
||||
- python
|
||||
- python-pexpect
|
||||
- tmux
|
||||
sources:
|
||||
- https://git.sr.ht/~faho/fish
|
||||
tasks:
|
||||
@@ -20,4 +19,4 @@ tasks:
|
||||
ninja
|
||||
- test: |
|
||||
cd fish/build
|
||||
ninja fish_run_tests
|
||||
env SHOW_INTERACTIVE_LOG=1 ninja test
|
||||
|
||||
@@ -1,30 +1,26 @@
|
||||
image: freebsd/latest
|
||||
packages:
|
||||
- cmake
|
||||
- ncurses
|
||||
- gcc
|
||||
- gettext
|
||||
- expect
|
||||
- cmake
|
||||
- gmake
|
||||
- llvm
|
||||
- ninja
|
||||
- pcre2
|
||||
- py311-pexpect
|
||||
- py311-sphinx
|
||||
- python
|
||||
- rust
|
||||
- tmux
|
||||
sources:
|
||||
- https://github.com/fish-shell/fish-shell
|
||||
- https://git.sr.ht/~faho/fish
|
||||
tasks:
|
||||
- build: |
|
||||
cd fish-shell
|
||||
mkdir build
|
||||
cd fish
|
||||
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
|
||||
cmake .. \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_INSTALL_DATADIR=share \
|
||||
-DCMAKE_INSTALL_DOCDIR=share/doc/fish \
|
||||
-DCMAKE_INSTALL_SYSCONFDIR=/etc
|
||||
gmake -j2
|
||||
- test: |
|
||||
cd fish-shell/build
|
||||
ninja fish_run_tests
|
||||
cd fish/build
|
||||
gmake test SHOW_INTERACTIVE_LOG=1
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
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
|
||||
@@ -1,8 +0,0 @@
|
||||
# This file is _not_ included in the tarballs for now
|
||||
# Binary builds on Linux packaging infrastructure need to overwrite it to make `cargo vendor` work
|
||||
# Releases and development builds made using OBS/Launchpad will _not_ reflect the contents of this
|
||||
# file
|
||||
|
||||
[resolver]
|
||||
# Make cargo 1.84+ respect MSRV (rust-version in Cargo.toml)
|
||||
incompatible-rust-versions = "fallback"
|
||||
48
.cirrus.yml
48
.cirrus.yml
@@ -1,48 +0,0 @@
|
||||
env:
|
||||
CIRRUS_CLONE_DEPTH: 100
|
||||
CI: 1
|
||||
|
||||
linux_task:
|
||||
matrix:
|
||||
- name: alpine
|
||||
container: &step
|
||||
image: ghcr.io/krobelus/fish-ci/alpine:latest
|
||||
memory: 4GB
|
||||
- name: ubuntu-oldest-supported
|
||||
container:
|
||||
<<: *step
|
||||
image: ghcr.io/krobelus/fish-ci/ubuntu-oldest-supported:latest
|
||||
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
|
||||
- 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'
|
||||
|
||||
freebsd_task:
|
||||
matrix:
|
||||
- name: FreeBSD Stable
|
||||
freebsd_instance:
|
||||
image: freebsd-14-3-release-amd64-ufs # updatecli.d/cirrus-freebsd.yml
|
||||
tests_script:
|
||||
- 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
|
||||
- pkg install -y llvm
|
||||
# BSDs have the following behavior: root may open or access files even if
|
||||
# the mode bits would otherwise disallow it. For example root may open()
|
||||
# a file with write privileges even if the file has mode 400. This breaks
|
||||
# our tests for e.g. cd and path. So create a new unprivileged user to run tests.
|
||||
- pw user add -n fish-user -s /bin/csh -d /home/fish-user
|
||||
- mkdir -p /home/fish-user
|
||||
- chown -R fish-user /home/fish-user
|
||||
- mkdir build && cd build
|
||||
- chown -R fish-user ..
|
||||
- sudo -u fish-user -s whoami
|
||||
- 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'
|
||||
@@ -6,3 +6,11 @@
|
||||
BasedOnStyle: Google
|
||||
ColumnLimit: 100
|
||||
IndentWidth: 4
|
||||
|
||||
# Place config.h first always.
|
||||
IncludeCategories:
|
||||
- Regex: '^"config.h"'
|
||||
Priority: -1
|
||||
|
||||
# We don't want OCLint pragmas to be reformatted.
|
||||
CommentPragmas: '^!OCLINT'
|
||||
|
||||
17
.clang-tidy
Normal file
17
.clang-tidy
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
Checks: 'clang-diagnostic-*,clang-analyzer-*,cert-*,performance-*,portability-*,modernize-use-auto,modernize-loop-convert,modernize-use-bool-literals,modernize-use-using,hicpp-uppercase-literal-suffix,readability-make-member-function-const,readability-redundant-string-init,readability-inconsistent-declaration-parameter-name,readability-redundant-access-specifiers'
|
||||
WarningsAsErrors: ''
|
||||
HeaderFilterRegex: ''
|
||||
AnalyzeTemporaryDtors: false
|
||||
FormatStyle: File
|
||||
CheckOptions:
|
||||
- key: cert-dcl16-c.NewSuffixes
|
||||
value: 'L;LL;LU;LLU'
|
||||
- key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
|
||||
value: '0'
|
||||
- key: modernize-loop-convert.MinConfidence
|
||||
value: 'risky'
|
||||
- key: modernize-use-auto.RemoveStars
|
||||
value: '1'
|
||||
...
|
||||
|
||||
26
.cppcheck.rules
Normal file
26
.cppcheck.rules
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<![CDATA[
|
||||
<!-- Sadly we can't enable the following two rules since doing so causes false
|
||||
positives in standard header files rather than just project specific
|
||||
source files. If we can find a way to enable these rules by also
|
||||
excluding system include files we should do so.
|
||||
<rule version="1">
|
||||
<pattern> wcwidth \(</pattern>
|
||||
<message>
|
||||
<id>wcwidthForbidden</id>
|
||||
<severity>warning</severity>
|
||||
<summary>Always use fish_wcwidth rather than wcwidth.</summary>
|
||||
</message>
|
||||
</rule>
|
||||
|
||||
<rule version="1">
|
||||
<pattern> wcswidth \(</pattern>
|
||||
<message>
|
||||
<id>wcswidthForbidden</id>
|
||||
<severity>warning</severity>
|
||||
<summary>Always use fish_wcswidth rather than wcswidth.</summary>
|
||||
</message>
|
||||
</rule>
|
||||
<--!>
|
||||
]]>
|
||||
12
.cppcheck.suppressions
Normal file
12
.cppcheck.suppressions
Normal file
@@ -0,0 +1,12 @@
|
||||
// suppress all instances of varFuncNullUB: "Passing NULL after the last typed
|
||||
// argument to a variadic function leads to undefined behaviour." That's
|
||||
// because all the places we do this are valid and won't cause problems even
|
||||
// on a ILP64 platform because we're careful about using NULL rather than 0.
|
||||
varFuncNullUB
|
||||
// Suppress the warning about unmatched suppressions. At the moment these
|
||||
// warnings are emitted even when removing the suppression comment results in
|
||||
// the warning being suppressed. In other words this unmatchedSuppression
|
||||
// warnings are false positives.
|
||||
unmatchedSuppression
|
||||
// Suppress this one because it reports assert(condition && "message"), which we use all over the place
|
||||
incorrectStringBooleanError
|
||||
@@ -13,20 +13,10 @@ max_line_length = 100
|
||||
indent_style = tab
|
||||
|
||||
[*.{md,rst}]
|
||||
max_line_length = unset
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.sh]
|
||||
indent_size = 4
|
||||
|
||||
[build_tools/release.sh]
|
||||
max_line_length = 72
|
||||
[*.{sh,ac}]
|
||||
indent_size = 2
|
||||
|
||||
[Dockerfile]
|
||||
indent_size = 2
|
||||
|
||||
[share/{completions,functions}/**.fish]
|
||||
max_line_length = unset
|
||||
|
||||
[{COMMIT_EDITMSG,git-revise-todo,*.jjdescription}]
|
||||
max_line_length = 72
|
||||
|
||||
21
.gitattributes
vendored
21
.gitattributes
vendored
@@ -1,12 +1,13 @@
|
||||
# normalize newlines
|
||||
* text=auto eol=lf
|
||||
* text=auto
|
||||
*.fish text
|
||||
*.bat eol=crlf
|
||||
|
||||
# let git show off diff hunk headers, help git diff -L:
|
||||
# https://git-scm.com/docs/gitattributes
|
||||
*.c diff=cpp
|
||||
*.cpp diff=cpp
|
||||
*.h diff=cpp
|
||||
*.py diff=py
|
||||
*.rs diff=rust
|
||||
# add a [diff "fish"] to git config with pattern
|
||||
*.fish diff=fish
|
||||
|
||||
@@ -20,13 +21,11 @@
|
||||
/.github/* export-ignore
|
||||
/.builds export-ignore
|
||||
/.builds/* export-ignore
|
||||
# to make cargo vendor work correctly
|
||||
/.cargo/ export-ignore
|
||||
/.cargo/config.toml export-ignore
|
||||
/.travis.yml export-ignore
|
||||
|
||||
# for linguist, which drives GitHub's language statistics
|
||||
alpine.js linguist-vendored
|
||||
doc_src/** linguist-documentation
|
||||
# for linguist; let github identify our project as C++ instead of C due to pcre2
|
||||
/pcre2/* linguist-vendored
|
||||
angular.js linguist-vendored
|
||||
/doc_src/* linguist-documentation
|
||||
*.fish linguist-language=fish
|
||||
# see 70f2899fcd which attempts to "rig the count"
|
||||
share/completions/*.fish linguist-documentation
|
||||
/tests/*.in linguist-language=fish
|
||||
|
||||
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1,2 +0,0 @@
|
||||
github:
|
||||
- krobelus
|
||||
@@ -1,24 +1,14 @@
|
||||
---
|
||||
name: "Bug Report"
|
||||
about: "Simple template for bug reports"
|
||||
title: ""
|
||||
labels: []
|
||||
assignees: []
|
||||
---
|
||||
|
||||
<!--
|
||||
Please tell us which fish version you are using by executing the following:
|
||||
|
||||
fish --version
|
||||
echo $version
|
||||
|
||||
Please tell us which operating system (output of `uname`) and terminal you are using.
|
||||
Please tell us which operating system and terminal you are using. The output of `uname -a` and `echo $TERM` may be helpful in this regard although other commands might be relevant in your specific situation.
|
||||
|
||||
Please tell us if you tried fish without third-party customizations by executing this command and whether it affected the behavior you are reporting:
|
||||
|
||||
sh -c 'env HOME=$(mktemp -d) XDG_CONFIG_HOME= XDG_DATA_DIRS= fish'
|
||||
sh -c 'env HOME=$(mktemp -d) fish'
|
||||
|
||||
Tell us how to reproduce the problem. Including an asciinema.org recording is useful for problems that involve the visual display of fish output such as its prompt.
|
||||
-->
|
||||
|
||||
**YOUR TEXT HERE**
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -8,4 +8,4 @@ Fixes issue #
|
||||
<!-- Just check off what what we know been done so far. We can help you with this stuff. -->
|
||||
- [ ] Changes to fish usage are reflected in user documentation/manpages.
|
||||
- [ ] Tests have been added for regressions fixed
|
||||
- [ ] User-visible changes noted in CHANGELOG.rst <!-- Don't document changes for completions inside CHANGELOG.rst, there are lot of such edits -->
|
||||
- [ ] User-visible changes noted in CHANGELOG.rst
|
||||
|
||||
41
.github/actions/install-dependencies/action.yml
vendored
41
.github/actions/install-dependencies/action.yml
vendored
@@ -1,41 +0,0 @@
|
||||
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' }}
|
||||
21
.github/actions/install-sphinx/action.yml
vendored
21
.github/actions/install-sphinx/action.yml
vendored
@@ -1,21 +0,0 @@
|
||||
name: Install sphinx
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- shell: bash
|
||||
run: |
|
||||
set -x
|
||||
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
41
.github/actions/rust-toolchain/action.yml
vendored
@@ -1,41 +0,0 @@
|
||||
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 }}
|
||||
@@ -1,21 +0,0 @@
|
||||
name: Oldest Supported Rust Toolchain
|
||||
|
||||
inputs:
|
||||
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:
|
||||
- uses: ./.github/actions/rust-toolchain
|
||||
with:
|
||||
toolchain_channel: "msrv"
|
||||
targets: ${{ inputs.targets }}
|
||||
components: ${{ inputs.components }}
|
||||
21
.github/actions/rust-toolchain@stable/action.yml
vendored
21
.github/actions/rust-toolchain@stable/action.yml
vendored
@@ -1,21 +0,0 @@
|
||||
name: Stable Rust Toolchain
|
||||
|
||||
inputs:
|
||||
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:
|
||||
- uses: ./.github/actions/rust-toolchain
|
||||
with:
|
||||
toolchain_channel: "stable"
|
||||
targets: ${{ inputs.targets }}
|
||||
components: ${{ inputs.components }}
|
||||
40
.github/workflows/autolabel_prs.yml
vendored
40
.github/workflows/autolabel_prs.yml
vendored
@@ -1,40 +0,0 @@
|
||||
name: Auto-Label PRs
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize]
|
||||
|
||||
jobs:
|
||||
label-and-milestone:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set label and milestone
|
||||
id: set-label-milestone
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const completionsLabel = 'completions';
|
||||
|
||||
// Get changed files in the pull request
|
||||
const prNumber = context.payload.pull_request.number;
|
||||
const { data: files } = await github.rest.pulls.listFiles({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
pull_number: prNumber,
|
||||
});
|
||||
|
||||
// Check if any file matches /share/completions/*.fish and no change is outside of /share/
|
||||
const completionsRegex = new RegExp('^share/completions/.*\.fish');
|
||||
const isCompletions = files.some(file => completionsRegex.test(file.filename))
|
||||
&& files.every(file => file.filename.startsWith('share/'));
|
||||
|
||||
if (isCompletions) {
|
||||
// Add label to PR
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: prNumber,
|
||||
labels: [completionsLabel],
|
||||
});
|
||||
console.log(`PR ${prNumber} assigned label "${completionsLabel}"`);
|
||||
}
|
||||
64
.github/workflows/build_docker_images.yml
vendored
64
.github/workflows/build_docker_images.yml
vendored
@@ -1,64 +0,0 @@
|
||||
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 }}
|
||||
62
.github/workflows/lint.yml
vendored
62
.github/workflows/lint.yml
vendored
@@ -1,62 +0,0 @@
|
||||
name: Lint
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
format:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/rust-toolchain@stable
|
||||
with:
|
||||
components: rustfmt
|
||||
- name: install dependencies
|
||||
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:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- rust_version: "stable"
|
||||
features: ""
|
||||
- rust_version: "stable"
|
||||
features: "--no-default-features"
|
||||
- rust_version: "msrv"
|
||||
features: ""
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/rust-toolchain
|
||||
with:
|
||||
toolchain_channel: ${{ matrix.rust_version }}
|
||||
components: clippy
|
||||
- name: Install deps
|
||||
run: |
|
||||
sudo apt install gettext
|
||||
- name: cargo clippy
|
||||
run: cargo clippy --workspace --all-targets ${{ matrix.features }} -- --deny=warnings
|
||||
|
||||
rustdoc:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/rust-toolchain@stable
|
||||
- name: Install deps
|
||||
run: |
|
||||
sudo apt install gettext
|
||||
- name: cargo doc
|
||||
run: |
|
||||
RUSTDOCFLAGS='-D warnings' cargo doc --workspace
|
||||
- name: cargo doctest
|
||||
run: |
|
||||
cargo test --doc --workspace
|
||||
20
.github/workflows/lockthreads.yml
vendored
20
.github/workflows/lockthreads.yml
vendored
@@ -2,25 +2,15 @@ name: 'Lock threads'
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 18 * * 1'
|
||||
# │ │ │ │ │
|
||||
# min 0-59 ┘ │ │ │ └ weekday 0-6
|
||||
# hour 0-23 ┘ │ └ month 1-12
|
||||
# └ day 1-31
|
||||
permissions:
|
||||
contents: read
|
||||
- cron: '0 * * * *'
|
||||
|
||||
jobs:
|
||||
lock:
|
||||
if: github.repository_owner == 'fish-shell'
|
||||
permissions:
|
||||
issues: write # for dessant/lock-threads to lock issues
|
||||
pull-requests: write # for dessant/lock-threads to lock PRs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v4
|
||||
- uses: dessant/lock-threads@v2
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-inactive-days: '365'
|
||||
pr-inactive-days: '365'
|
||||
exclude-any-issue-labels: 'question, needs more info'
|
||||
issue-lock-inactive-days: '90'
|
||||
pr-lock-inactive-days: '90'
|
||||
issue-exclude-labels: 'question'
|
||||
|
||||
48
.github/workflows/main.yml
vendored
Normal file
48
.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
name: C/C++ CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
ubuntu:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install deps
|
||||
run: |
|
||||
sudo apt install expect gettext libncurses5-dev libpcre2-dev
|
||||
- name: cmake
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
- name: make
|
||||
run: |
|
||||
make
|
||||
- name: make test
|
||||
run: |
|
||||
make test
|
||||
|
||||
# macos:
|
||||
|
||||
# runs-on: macos-latest
|
||||
|
||||
# steps:
|
||||
# - uses: actions/checkout@v2
|
||||
# - name: Install deps
|
||||
# run: |
|
||||
# brew install pcre2
|
||||
# - name: cmake
|
||||
# run: |
|
||||
# mkdir build && cd build
|
||||
# cmake ..
|
||||
# - name: make
|
||||
# run: |
|
||||
# make
|
||||
# - name: make test
|
||||
# run: |
|
||||
# make test
|
||||
192
.github/workflows/release.yml
vendored
192
.github/workflows/release.yml
vendored
@@ -1,192 +0,0 @@
|
||||
name: Create a new release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: 'Version to release (tag name)'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
is-release-tag:
|
||||
name: Pre-release checks
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# Workaround for https://github.com/actions/checkout/issues/882
|
||||
ref: ${{ inputs.version }}
|
||||
- name: Check if the pushed tag looks like a release
|
||||
run: |
|
||||
set -x
|
||||
commit_subject=$(git log -1 --format=%s)
|
||||
tag=$(git describe)
|
||||
[ "$commit_subject" = "Release $tag" ]
|
||||
|
||||
|
||||
source-tarball:
|
||||
needs: [is-release-tag]
|
||||
name: Create the source tarball
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
tarball-name: ${{ steps.version.outputs.tarball-name }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# Workaround for https://github.com/actions/checkout/issues/882
|
||||
ref: ${{ inputs.version }}
|
||||
- name: Install dependencies
|
||||
run: sudo apt install cmake gettext ninja-build python3-pip
|
||||
- uses: ./.github/actions/install-sphinx
|
||||
- name: Create tarball
|
||||
run: |
|
||||
set -x
|
||||
mkdir /tmp/fish-built
|
||||
FISH_ARTEFACT_PATH=/tmp/fish-built ./build_tools/make_tarball.sh
|
||||
relnotes=/tmp/fish-built/release-notes.md
|
||||
# Need history since the last release (i.e. tag) for stats.
|
||||
git fetch --tags
|
||||
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"
|
||||
# Delete title
|
||||
sed -n 1p "$relnotes" | grep -q "^## fish .*"
|
||||
sed -n 2p "$relnotes" | grep -q '^$'
|
||||
sed -i 1,2d "$relnotes"
|
||||
- name: Upload tarball artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: source-tarball
|
||||
path: |
|
||||
/tmp/fish-built/fish-${{ inputs.version }}.tar.xz
|
||||
/tmp/fish-built/release-notes.md
|
||||
if-no-files-found: error
|
||||
|
||||
packages-for-linux:
|
||||
needs: [is-release-tag]
|
||||
name: Build single-file fish for Linux
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# Workaround for https://github.com/actions/checkout/issues/882
|
||||
ref: ${{ inputs.version }}
|
||||
- name: Install Rust Stable
|
||||
uses: ./.github/actions/rust-toolchain@stable
|
||||
with:
|
||||
targets: x86_64-unknown-linux-musl,aarch64-unknown-linux-musl
|
||||
- name: Install dependencies
|
||||
run: sudo apt install crossbuild-essential-arm64 gettext musl-tools
|
||||
- uses: ./.github/actions/install-sphinx
|
||||
- name: Build statically-linked executables
|
||||
run: |
|
||||
set -x
|
||||
cargo build --release --target x86_64-unknown-linux-musl --bin fish
|
||||
CFLAGS="-D_FORTIFY_SOURCE=2" \
|
||||
CC=aarch64-linux-gnu-gcc \
|
||||
RUSTFLAGS="-C linker=aarch64-linux-gnu-gcc -C link-arg=-lgcc -C link-arg=-D_FORTIFY_SOURCE=0" \
|
||||
cargo build --release --target aarch64-unknown-linux-musl --bin fish
|
||||
- name: Compress
|
||||
run: |
|
||||
set -x
|
||||
for arch in x86_64 aarch64; do
|
||||
tar -cazf fish-$(git describe)-linux-$arch.tar.xz \
|
||||
-C target/$arch-unknown-linux-musl/release fish
|
||||
done
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Static builds for Linux
|
||||
path: fish-${{ inputs.version }}-linux-*.tar.xz
|
||||
if-no-files-found: error
|
||||
|
||||
create-draft-release:
|
||||
needs:
|
||||
- is-release-tag
|
||||
- source-tarball
|
||||
- packages-for-linux
|
||||
name: Create release draft
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# Workaround for https://github.com/actions/checkout/issues/882
|
||||
ref: ${{ inputs.version }}
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
merge-multiple: true
|
||||
path: /tmp/artifacts
|
||||
- name: List artifacts
|
||||
run: find /tmp/artifacts -type f
|
||||
- name: Create draft release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: ${{ inputs.version }}
|
||||
name: fish ${{ inputs.version }}
|
||||
body_path: /tmp/artifacts/release-notes.md
|
||||
draft: true
|
||||
files: |
|
||||
/tmp/artifacts/fish-${{ inputs.version }}.tar.xz
|
||||
/tmp/artifacts/fish-${{ inputs.version }}-linux-*.tar.xz
|
||||
|
||||
packages-for-macos:
|
||||
needs: [is-release-tag, create-draft-release]
|
||||
name: Build packages for macOS
|
||||
runs-on: macos-latest
|
||||
environment: macos-codesign
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
# Workaround for https://github.com/actions/checkout/issues/882
|
||||
ref: ${{ inputs.version }}
|
||||
- name: Install Rust
|
||||
uses: ./.github/actions/rust-toolchain@stable
|
||||
with:
|
||||
targets: aarch64-apple-darwin,x86_64-apple-darwin
|
||||
- name: Install dependencies
|
||||
run: brew install gettext
|
||||
- uses: ./.github/actions/install-sphinx
|
||||
- name: Build and codesign
|
||||
run: |
|
||||
die() { echo >&2 "$*"; exit 1; }
|
||||
[ -n "$MAC_CODESIGN_APP_P12_BASE64" ] || die "Missing MAC_CODESIGN_APP_P12_BASE64"
|
||||
[ -n "$MAC_CODESIGN_INSTALLER_P12_BASE64" ] || die "Missing MAC_CODESIGN_INSTALLER_P12_BASE64"
|
||||
[ -n "$MAC_CODESIGN_PASSWORD" ] || die "Missing MAC_CODESIGN_PASSWORD"
|
||||
[ -n "$MACOS_NOTARIZE_JSON" ] || die "Missing MACOS_NOTARIZE_JSON"
|
||||
set -x
|
||||
export FISH_ARTEFACT_PATH=/tmp/fish-built
|
||||
# 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.
|
||||
export CARGO_NET_GIT_FETCH_WITH_CLI=true
|
||||
cargo install apple-codesign
|
||||
mkdir -p "$FISH_ARTEFACT_PATH"
|
||||
echo "$MAC_CODESIGN_APP_P12_BASE64" | base64 --decode >/tmp/app.p12
|
||||
echo "$MAC_CODESIGN_INSTALLER_P12_BASE64" | base64 --decode >/tmp/installer.p12
|
||||
echo "$MACOS_NOTARIZE_JSON" >/tmp/notarize.json
|
||||
./build_tools/make_macos_pkg.sh -s -f /tmp/app.p12 \
|
||||
-i /tmp/installer.p12 -p "$MAC_CODESIGN_PASSWORD" \
|
||||
-n -j /tmp/notarize.json
|
||||
version=$(git describe)
|
||||
[ -f "${FISH_ARTEFACT_PATH}/fish-$version.app.zip" ]
|
||||
[ -f "${FISH_ARTEFACT_PATH}/fish-$version.pkg" ]
|
||||
rm /tmp/installer.p12 /tmp/app.p12 /tmp/notarize.json
|
||||
env:
|
||||
MAC_CODESIGN_APP_P12_BASE64: ${{ secrets.MAC_CODESIGN_APP_P12_BASE64 }}
|
||||
MAC_CODESIGN_INSTALLER_P12_BASE64: ${{ secrets.MAC_CODESIGN_INSTALLER_P12_BASE64 }}
|
||||
MAC_CODESIGN_PASSWORD: ${{ secrets.MAC_CODESIGN_PASSWORD }}
|
||||
MACOS_NOTARIZE_JSON: ${{ secrets.MACOS_NOTARIZE_JSON }}
|
||||
- name: Add macOS packages to the release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
version=$(git describe)
|
||||
gh release upload $version \
|
||||
/tmp/fish-built/fish-$version.app.zip \
|
||||
/tmp/fish-built/fish-$version.pkg
|
||||
176
.github/workflows/test.yml
vendored
176
.github/workflows/test.yml
vendored
@@ -1,176 +0,0 @@
|
||||
name: Test
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
FISH_TEST_MAX_CONCURRENCY: "4"
|
||||
CMAKE_BUILD_PARALLEL_LEVEL: "4"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
ubuntu:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/rust-toolchain@oldest-supported
|
||||
- name: Install deps
|
||||
uses: ./.github/actions/install-dependencies
|
||||
with:
|
||||
include_sphinx: true
|
||||
- name: Generate a locale that uses a comma as decimal separator.
|
||||
run: |
|
||||
sudo locale-gen fr_FR.UTF-8
|
||||
- name: cmake
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
- name: make
|
||||
run: |
|
||||
make -C build VERBOSE=1
|
||||
- name: make fish_run_tests
|
||||
run: |
|
||||
make -C build VERBOSE=1 fish_run_tests
|
||||
- name: translation updates
|
||||
run: |
|
||||
# Generate PO files. This should not result it a change in the repo if all translations are
|
||||
# up to date.
|
||||
# Ensure that fish is available as an executable.
|
||||
PATH="$PWD/build:$PATH" build_tools/update_translations.fish
|
||||
# Show diff output. Fail if there is any.
|
||||
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:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/rust-toolchain@oldest-supported
|
||||
with:
|
||||
targets: "i586-unknown-linux-gnu"
|
||||
- name: Install deps
|
||||
uses: ./.github/actions/install-dependencies
|
||||
with:
|
||||
include_pcre: false
|
||||
include_sphinx: false
|
||||
- name: Install g++-multilib
|
||||
run: |
|
||||
sudo apt install g++-multilib
|
||||
- name: cmake
|
||||
env:
|
||||
CFLAGS: "-m32"
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake -DFISH_USE_SYSTEM_PCRE2=OFF -DRust_CARGO_TARGET=i586-unknown-linux-gnu ..
|
||||
- name: make
|
||||
run: |
|
||||
make -C build VERBOSE=1
|
||||
- name: make fish_run_tests
|
||||
run: |
|
||||
make -C build VERBOSE=1 fish_run_tests
|
||||
|
||||
ubuntu-asan:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
# Rust has two different memory sanitizers of interest; they can't be used at the same time:
|
||||
# * AddressSanitizer detects out-of-bound access, use-after-free, use-after-return,
|
||||
# use-after-scope, double-free, invalid-free, and memory leaks.
|
||||
# * MemorySanitizer detects uninitialized reads.
|
||||
#
|
||||
RUSTFLAGS: "-Zsanitizer=address"
|
||||
# RUSTFLAGS: "-Zsanitizer=memory -Zsanitizer-memory-track-origins"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
# All -Z options require running nightly
|
||||
- uses: dtolnay/rust-toolchain@nightly
|
||||
with:
|
||||
# ASAN uses `cargo build -Zbuild-std` which requires the rust-src component
|
||||
# this is comma-separated
|
||||
components: rust-src
|
||||
- name: Install deps
|
||||
uses: ./.github/actions/install-dependencies
|
||||
with:
|
||||
include_sphinx: false
|
||||
- name: Install llvm
|
||||
run: |
|
||||
sudo apt install llvm # for llvm-symbolizer
|
||||
- name: cmake
|
||||
env:
|
||||
CC: clang
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
# Rust's ASAN requires the build system to explicitly pass a --target triple. We read that
|
||||
# value from CMake variable Rust_CARGO_TARGET.
|
||||
cmake .. -DASAN=1 -DRust_CARGO_TARGET=x86_64-unknown-linux-gnu -DCMAKE_BUILD_TYPE=Debug
|
||||
- name: make
|
||||
run: |
|
||||
make -C build VERBOSE=1
|
||||
- name: make fish_run_tests
|
||||
env:
|
||||
FISH_CI_SAN: 1
|
||||
ASAN_OPTIONS: check_initialization_order=1:detect_stack_use_after_return=1:detect_leaks=1:fast_unwind_on_malloc=0
|
||||
# use_tls=0 is a workaround for LSAN crashing with "Tracer caught signal 11" (SIGSEGV),
|
||||
# which seems to be an issue with TLS support in newer glibc versions under virtualized
|
||||
# environments. Follow https://github.com/google/sanitizers/issues/1342 and
|
||||
# https://github.com/google/sanitizers/issues/1409 to track this issue.
|
||||
# UPDATE: this can cause spurious leak reports for __cxa_thread_atexit_impl() under glibc.
|
||||
LSAN_OPTIONS: verbosity=0:log_threads=0:use_tls=1:print_suppressions=0
|
||||
run: |
|
||||
set -x
|
||||
export ASAN_SYMBOLIZER_PATH=$(command -v /usr/bin/llvm-symbolizer* | sort -n | head -1)
|
||||
export LSAN_OPTIONS="$LSAN_OPTIONS:suppressions=$PWD/build_tools/lsan_suppressions.txt"
|
||||
make -C build VERBOSE=1 fish_run_tests
|
||||
|
||||
macos:
|
||||
runs-on: macos-latest
|
||||
env:
|
||||
# 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.
|
||||
CARGO_NET_GIT_FETCH_WITH_CLI: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/rust-toolchain@oldest-supported
|
||||
- name: Install deps
|
||||
run: |
|
||||
# --break-system-packages because homebrew has now declared itself "externally managed".
|
||||
# this is CI so we don't actually care.
|
||||
sudo pip3 install --break-system-packages pexpect
|
||||
brew install gettext tmux
|
||||
- uses: ./.github/actions/install-sphinx
|
||||
- name: cmake
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
FISH_TEST_MAX_CONCURRENCY=1 \
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug ..
|
||||
- name: make
|
||||
run: |
|
||||
make -C build VERBOSE=1
|
||||
- name: make fish_run_tests
|
||||
run: |
|
||||
make -C build VERBOSE=1 fish_run_tests
|
||||
|
||||
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
|
||||
22
.gitignore
vendored
22
.gitignore
vendored
@@ -7,6 +7,7 @@
|
||||
*.DS_Store
|
||||
*.a
|
||||
*.app
|
||||
*.d
|
||||
*.dll
|
||||
*.dylib
|
||||
*.exe
|
||||
@@ -37,6 +38,7 @@ Desktop.ini
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
messages.pot
|
||||
.directory
|
||||
.fuse_hidden*
|
||||
|
||||
@@ -75,7 +77,6 @@ __pycache__
|
||||
/share/__fish_build_paths.fish
|
||||
/share/pkgconfig
|
||||
/tests/*.tmp.*
|
||||
/tests/.last-check-all-files
|
||||
|
||||
# xcode
|
||||
## Build generated
|
||||
@@ -88,22 +89,3 @@ __pycache__
|
||||
/tags
|
||||
xcuserdata/
|
||||
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
debug/
|
||||
target/
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
||||
|
||||
# Generated by clangd
|
||||
/.cache
|
||||
|
||||
# JetBrains editors.
|
||||
.idea/
|
||||
|
||||
# AI slop
|
||||
.claude/
|
||||
|
||||
95
.oclint
Normal file
95
.oclint
Normal file
@@ -0,0 +1,95 @@
|
||||
rules:
|
||||
rule-configurations:
|
||||
#
|
||||
# This is the default value (as of the time I wrote this) but I'm making
|
||||
# it explicit since it needs to agree with the value used by clang-format.
|
||||
# Thus, if we ever change the fish style to allow longer or shorter lines
|
||||
# this should be changed (as well as the corresponding .clang-format file).
|
||||
#
|
||||
- key: LONG_LINE
|
||||
value: 100
|
||||
#
|
||||
# The default limit for the length of variable names is 20. Long names are
|
||||
# problematic but twenty chars results in way too many errors. So increase
|
||||
# the limit to something more reasonable.
|
||||
#
|
||||
- key: LONG_VARIABLE_NAME
|
||||
value: 30
|
||||
#
|
||||
# This allows us to avoid peppering our code with inline comments such as
|
||||
#
|
||||
# scoped_lock locker(m_lock); //!OCLINT(side-effect)
|
||||
#
|
||||
# Specifically, this config key tells oclint that the named classes have
|
||||
# RAII behavior so the local vars are actually used.
|
||||
#
|
||||
- key: RAII_CUSTOM_CLASSES
|
||||
value: scoped_lock scoped_buffer_t builtin_commandline_scoped_transient_t scoped_push
|
||||
|
||||
# We're slightly more persmissive regarding the total number of lines in a
|
||||
# function. Default is 50.
|
||||
- key: LONG_METHOD
|
||||
value: 60
|
||||
|
||||
# We're slightly more persmissive regarding the number of non-comment
|
||||
# lines in a function. Default is 30.
|
||||
- key: NCSS_METHOD
|
||||
value: 40
|
||||
|
||||
# We're willing to allow slighly more linearly independent paths through a
|
||||
# function. Most of our code has a lot of `switch` blocks or consecutive
|
||||
# `if` tests that are straightforward to interpret but which increase this
|
||||
# metric. Default is 10.
|
||||
- key: CYCLOMATIC_COMPLEXITY
|
||||
value: 14
|
||||
|
||||
# We're willing to allow slighly more execution paths through a function.
|
||||
# Default is 200.
|
||||
- key: NPATH_COMPLEXITY
|
||||
value: 300
|
||||
|
||||
disable-rules:
|
||||
#
|
||||
# A few instances of "useless parentheses" errors are meaningful. Mostly
|
||||
# in the context of the `return` statement. Unfortunately the vast
|
||||
# majority would result in removing parentheses that decreases
|
||||
# readability. So we're going to ignore this warning and rely on humans to
|
||||
# notice when the parentheses are truly not needed.
|
||||
#
|
||||
# Also, some macro expansions, such as FD_SET(), trigger this warning and
|
||||
# we don't want to suppress each of those individually.
|
||||
#
|
||||
- UselessParentheses
|
||||
#
|
||||
# OCLint wants variable names to be at least three characters in length.
|
||||
# Which would be fine if it supported a reasonable set of exceptions
|
||||
# (e.g., "i", "j", "k") and allowed adding additional exceptions to match
|
||||
# conventions employed by a project. Since it doesn't, and thus generates
|
||||
# a lot of really annoying warnings, we're going to disable this rule.
|
||||
#
|
||||
- ShortVariableName
|
||||
#
|
||||
# This rule flags perfectly reasonable conditions like `if (!some_condition)`
|
||||
# and is therefore just noise. Disable this rule.
|
||||
#
|
||||
- InvertedLogic
|
||||
#
|
||||
# The idea behind the "double negative" rule is sound since constructs
|
||||
# like "!!(var & flag)" should be written as "static_cast<bool>(var &
|
||||
# flag)". Unfortunately this rule has way too many false positives;
|
||||
# especially in the context of assert statements. So disable this rule.
|
||||
#
|
||||
- DoubleNegative
|
||||
#
|
||||
# Avoiding bitwise operators in a conditional is a good idea with one
|
||||
# exception: testing whether a bit flag is set. Which happens to be the
|
||||
# only time you'll see something like `if (j->flags & JOB_CONSTRUCTED)`
|
||||
# in fish source.
|
||||
#
|
||||
- BitwiseOperatorInConditional
|
||||
#
|
||||
# I don't think I've ever seen a case where assigning a value to a
|
||||
# parameter inside the function body was unclear, let along dangerous or
|
||||
# an error. This rule is therefore just noise. Disable this rule.
|
||||
#
|
||||
- ParameterReassignment
|
||||
@@ -1 +0,0 @@
|
||||
edition = "2024"
|
||||
122
.travis.yml
Normal file
122
.travis.yml
Normal file
@@ -0,0 +1,122 @@
|
||||
language: cpp
|
||||
dist: xenial
|
||||
sudo: required
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- expect
|
||||
- gettext
|
||||
- libncurses5-dev
|
||||
- libpcre2-dev
|
||||
- python3
|
||||
- python3-pip
|
||||
before_install:
|
||||
- sudo pip3 install pexpect
|
||||
env:
|
||||
# Some warnings upgraded to errors to match Open Build Service platforms
|
||||
- CXXFLAGS="-Werror=address -Werror=return-type"
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
packages: # Don't use libpcre2-dev here, so that one build uses the vendored code
|
||||
- expect
|
||||
- gettext
|
||||
- lib32ncurses5-dev
|
||||
- g++-multilib
|
||||
- python3
|
||||
- python3-pip
|
||||
before_install:
|
||||
- sudo pip3 install pexpect
|
||||
env:
|
||||
- CXXFLAGS="-m32 -Werror=address -Werror=return-type" CFLAGS="-m32"
|
||||
- os: linux
|
||||
compiler: clang
|
||||
env:
|
||||
- CXXFLAGS="-fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address"
|
||||
- ASAN_OPTIONS=check_initialization_order=1:detect_stack_use_after_return=1:detect_leaks=1
|
||||
- UBSAN_OPTIONS=print_stacktrace=1:report_error_type=1:suppressions=$TRAVIS_BUILD_DIR/build_tools/ubsan.blacklist
|
||||
before_install:
|
||||
- sudo pip3 install pexpect
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- expect
|
||||
- gettext
|
||||
- libncurses5-dev
|
||||
- libpcre2-dev
|
||||
- python
|
||||
- python3
|
||||
- python3-pip
|
||||
- os: linux
|
||||
compiler: clang
|
||||
env:
|
||||
- CXXFLAGS="-fsanitize=thread"
|
||||
before_install:
|
||||
- sudo pip3 install pexpect
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- expect
|
||||
- gettext
|
||||
- libncurses5-dev
|
||||
- libpcre2-dev
|
||||
- python3
|
||||
- python3-pip
|
||||
- os: linux
|
||||
compiler: gcc
|
||||
addons:
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "fish-shell/fish-shell"
|
||||
description: "The friendly interactive shell"
|
||||
notification_email: corydoras@ridiculousfish.com
|
||||
build_command_prepend: "mkdir -p build; cd build; cmake -G Ninja .."
|
||||
build_command: "ninja"
|
||||
branch_pattern: coverity_scan_master
|
||||
apt:
|
||||
packages:
|
||||
- expect
|
||||
- gettext
|
||||
- libncurses5-dev
|
||||
- libpcre2-dev
|
||||
- python3
|
||||
- python3-pip
|
||||
before_install:
|
||||
- sudo pip3 install pexpect
|
||||
- echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
|
||||
env:
|
||||
- secure: "Q1AS5iEi17s+xsRaMwfkxmm62UDaV47uE39pvXsNL+DO9YWbMMuhTpIOeYhxLvFNL3LMUFU2TwVpVRYX2YFGhNNaMSmjQfyQ+7q7/oSEo0aSqvQkwelpK/pwuRAXdv1MU4aQ6FrCEQ4VMO45WRo0o5WD26pvxjqRyAQ6ry+serA="
|
||||
# Some warnings upgraded to errors to match Open Build Service platforms
|
||||
- CXXFLAGS="-Werror=address -Werror=return-type"
|
||||
- os: osx
|
||||
before_install:
|
||||
- sudo pip3 install pexpect
|
||||
fast_finish: true
|
||||
|
||||
script:
|
||||
- cmake -DCMAKE_INSTALL_PREFIX=$HOME/prefix . || cat CMakeFiles/CMakeError.log &&
|
||||
make -j2 &&
|
||||
make install &&
|
||||
make test SHOW_INTERACTIVE_LOG=1
|
||||
|
||||
notifications:
|
||||
# Some items are encrypted so that notifications from other repositories
|
||||
# don't flood the official repositories.
|
||||
irc:
|
||||
channels:
|
||||
#- "irc.oftc.net#fish"
|
||||
secure: "eRk9KGZ5+mrlD2SoI8yg2Sp8OYrh7YPyGe3WCDQUwTnNgNDII34rbM9a6UOA/l7AeWSNY8joLq5xVLCU4wpFgUcJ11SYIpMnLosZK29OW4ubDOHmdBDvJ971rLgAVG9cXngZtIxEVVxN/jnS1Qr8GKZx4DjkaTMgz1pemb4WxCc="
|
||||
template:
|
||||
- "%{repository}#%{build_number} (%{commit} on %{branch} by %{author}): %{message} Details at %{build_url}"
|
||||
use_notice: true
|
||||
skip_join: true
|
||||
webhooks:
|
||||
urls:
|
||||
#- https://webhooks.gitter.im/e/61821cec3015bf0f8bb1
|
||||
secure: fPfOmxnC3MCsfR1oocVFeWLawGcRZkn+8fNHlSOeZ+SqqoZfcCHgQTvQ22TqmVl1yvkXbNlaXjo6dbVzTOAh7r7H0bRMEKBVh3dQS7wqjB1sKivpXd8PAS3BTj5MQpGeJzdHnDuwVlwDktGtfHfhGeq1Go/4IosOq8u+6RTe28g=
|
||||
18
BSDmakefile
18
BSDmakefile
@@ -20,22 +20,20 @@ _GENERATOR!=which ninja 2>/dev/null >/dev/null && echo Ninja || echo "Unix Makef
|
||||
GENERATOR?=$(_GENERATOR)
|
||||
|
||||
.if $(GENERATOR) == "Ninja"
|
||||
BUILDFILE=build.ninja
|
||||
BUILDFILE=build/build.ninja
|
||||
.else
|
||||
BUILDFILE=Makefile
|
||||
BUILDFILE=build/Makefile
|
||||
.endif
|
||||
|
||||
PREFIX?=/usr/local
|
||||
|
||||
.PHONY: build/fish
|
||||
build/fish: build/$(BUILDFILE)
|
||||
$(CMAKE) --build build
|
||||
|
||||
# Don't split the mkdir into its own rule because that would cause CMake to regenerate the build
|
||||
# files after each build (because it adds the mdate of the build directory into the out-of-date
|
||||
# calculation tree). GNUmake supports order-only dependencies, BSDmake does not seem to.
|
||||
build/$(BUILDFILE):
|
||||
build:
|
||||
mkdir -p build
|
||||
|
||||
build/$(BUILDFILE): build
|
||||
cd build; $(CMAKE) .. -G "$(GENERATOR)" -DCMAKE_INSTALL_PREFIX="$(PREFIX)" -DCMAKE_EXPORT_COMPILE_COMMANDS=1
|
||||
|
||||
.PHONY: install
|
||||
@@ -48,11 +46,7 @@ clean:
|
||||
|
||||
.PHONY: test
|
||||
test: build/fish
|
||||
$(CMAKE) --build build --target fish_run_tests
|
||||
|
||||
.PHONY: fish_run_tests
|
||||
fish_run_tests: build/fish
|
||||
$(CMAKE) --build build --target fish_run_tests
|
||||
$(CMAKE) --build build --target test
|
||||
|
||||
.PHONY: run
|
||||
run: build/fish
|
||||
|
||||
3641
CHANGELOG.rst
3641
CHANGELOG.rst
File diff suppressed because it is too large
Load Diff
238
CMakeLists.txt
238
CMakeLists.txt
@@ -1,94 +1,203 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
cmake_minimum_required(VERSION 3.2)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
|
||||
if(POLICY CMP0066)
|
||||
cmake_policy(SET CMP0066 OLD)
|
||||
endif()
|
||||
if(POLICY CMP0067)
|
||||
cmake_policy(SET CMP0067 NEW)
|
||||
endif()
|
||||
|
||||
project(fish LANGUAGES C)
|
||||
include(cmake/Mac.cmake)
|
||||
|
||||
project(fish)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# We are C++11.
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(DEFAULT_BUILD_TYPE "RelWithDebInfo")
|
||||
|
||||
# Use the default flags (#6296) but remove -DNDEBUG so that asserts remain enabled.
|
||||
string(REPLACE "-DNDEBUG" ""
|
||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||
|
||||
string(REPLACE "-DNDEBUG" ""
|
||||
CMAKE_CXX_FLAGS_RELEASE
|
||||
"${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
message(STATUS "Setting build type to default '${DEFAULT_BUILD_TYPE}'")
|
||||
set(CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}")
|
||||
endif()
|
||||
|
||||
# Set up standard directories.
|
||||
include(GNUInstallDirs)
|
||||
# Force colored warnings in Ninja's output, if the compiler has -fdiagnostics-color support.
|
||||
# Rationale in https://github.com/ninja-build/ninja/issues/814
|
||||
if (CMAKE_GENERATOR STREQUAL "Ninja" AND
|
||||
((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) OR
|
||||
(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5) OR
|
||||
(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.0)))
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-color=always")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
|
||||
endif()
|
||||
# Enable a whole bunch of warnings, but turn off:
|
||||
# - implicit fallthrough because that does not recognize some cases where it's desired (and I *really* want this one!)
|
||||
# - comment because we use a bunch of those, and they're not really all that harmful.
|
||||
# - address, because that occurs for our mkostemp check (weak-linking requires us to compare `&mkostemp == nullptr`).
|
||||
# - strict-aliasing, because on old GCCs (*Travis*) those are triggered by maybe.h, so you get it every time it is included.
|
||||
# - redundant-move, because we have one that is required on old libc
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra \
|
||||
-Wno-implicit-fallthrough \
|
||||
-Wno-comment \
|
||||
-Wno-address \
|
||||
-Wno-strict-aliasing \
|
||||
-Wno-redundant-move \
|
||||
")
|
||||
|
||||
# Set up PCRE2
|
||||
# This sets an environment variable that needs to be available before the Rust stanzas
|
||||
include(cmake/PCRE2.cmake)
|
||||
# Disable exception handling.
|
||||
add_compile_options(-fno-exceptions)
|
||||
|
||||
include(cmake/Rust.cmake)
|
||||
# Prefer the gold linker because it doesn't emit useless warnings about sys_nerr and _sys_errlist.
|
||||
if (UNIX AND NOT APPLE)
|
||||
execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version
|
||||
ERROR_QUIET OUTPUT_VARIABLE LD_VERSION)
|
||||
if ("${LD_VERSION}" MATCHES "GNU gold")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Hide the CMake Rules directories in Xcode projects.
|
||||
source_group("CMake Rules" REGULAR_EXPRESSION "^$")
|
||||
|
||||
# Put source and header files at top level under targets.
|
||||
source_group("Source Files" REGULAR_EXPRESSION "^$")
|
||||
source_group("Header Files" REGULAR_EXPRESSION "^$")
|
||||
source_group("Builtins" REGULAR_EXPRESSION "builtin_.*")
|
||||
|
||||
# Support folders.
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
||||
# Work around issue where archive-built libs go in the wrong place.
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
|
||||
|
||||
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
||||
set(FISH_IN_TREE_BUILD TRUE)
|
||||
else()
|
||||
set(FISH_IN_TREE_BUILD FALSE)
|
||||
endif()
|
||||
|
||||
# NetBSD does weird things with finding libraries,
|
||||
# making the tests fail by failing to find pcre.
|
||||
#
|
||||
# Keep the rpath used to build.
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL NetBSD)
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
endif()
|
||||
|
||||
# All objects that the system needs to build fish, except fish.cpp
|
||||
set(FISH_SRCS
|
||||
src/autoload.cpp src/builtin.cpp src/builtin_bg.cpp src/builtin_bind.cpp
|
||||
src/builtin_block.cpp src/builtin_builtin.cpp src/builtin_cd.cpp
|
||||
src/builtin_command.cpp src/builtin_commandline.cpp
|
||||
src/builtin_complete.cpp src/builtin_contains.cpp src/builtin_disown.cpp
|
||||
src/builtin_echo.cpp src/builtin_emit.cpp src/builtin_exit.cpp
|
||||
src/builtin_fg.cpp src/builtin_function.cpp src/builtin_functions.cpp
|
||||
src/builtin_argparse.cpp src/builtin_history.cpp src/builtin_jobs.cpp
|
||||
src/builtin_math.cpp src/builtin_printf.cpp src/builtin_pwd.cpp
|
||||
src/builtin_random.cpp src/builtin_read.cpp src/builtin_realpath.cpp
|
||||
src/builtin_return.cpp src/builtin_set.cpp src/builtin_set_color.cpp
|
||||
src/builtin_source.cpp src/builtin_status.cpp src/builtin_string.cpp
|
||||
src/builtin_test.cpp src/builtin_ulimit.cpp src/builtin_wait.cpp src/builtin_eval.cpp
|
||||
src/color.cpp src/common.cpp src/complete.cpp src/env.cpp src/env_dispatch.cpp
|
||||
src/env_universal_common.cpp src/event.cpp src/exec.cpp src/expand.cpp
|
||||
src/fallback.cpp src/fish_version.cpp src/function.cpp src/highlight.cpp
|
||||
src/history.cpp src/history_file.cpp src/input.cpp src/input_common.cpp src/intern.cpp
|
||||
src/io.cpp src/iothread.cpp src/kill.cpp src/output.cpp src/pager.cpp
|
||||
src/parse_execution.cpp src/parse_productions.cpp src/parse_tree.cpp
|
||||
src/parse_util.cpp src/parser.cpp src/parser_keywords.cpp src/path.cpp
|
||||
src/postfork.cpp src/proc.cpp src/reader.cpp src/sanity.cpp src/screen.cpp
|
||||
src/signal.cpp src/tinyexpr.cpp src/tnode.cpp src/tokenizer.cpp src/utf8.cpp src/util.cpp
|
||||
src/wcstringutil.cpp src/wgetopt.cpp src/wildcard.cpp src/wutil.cpp
|
||||
src/future_feature_flags.cpp src/redirection.cpp src/topic_monitor.cpp
|
||||
src/flog.cpp src/trace.cpp src/timer.cpp src/null_terminated_array.cpp
|
||||
src/operation_context.cpp src/fd_monitor.cpp src/termsize.cpp
|
||||
)
|
||||
|
||||
# Header files are just globbed.
|
||||
file(GLOB FISH_HEADERS src/*.h)
|
||||
|
||||
# Set up config.h
|
||||
include(cmake/ConfigureChecks.cmake)
|
||||
include(cmake/gettext.cmake)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config_cmake.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# Set up standard directories.
|
||||
include(GNUInstallDirs)
|
||||
add_definitions(-D_UNICODE=1
|
||||
-DLOCALEDIR="${CMAKE_INSTALL_FULL_LOCALEDIR}"
|
||||
-DPREFIX=L"${CMAKE_INSTALL_PREFIX}"
|
||||
-DDATADIR=L"${CMAKE_INSTALL_FULL_DATADIR}"
|
||||
-DSYSCONFDIR=L"${CMAKE_INSTALL_FULL_SYSCONFDIR}"
|
||||
-DBINDIR=L"${CMAKE_INSTALL_FULL_BINDIR}"
|
||||
-DDOCDIR=L"${CMAKE_INSTALL_FULL_DOCDIR}")
|
||||
|
||||
# Set up the machinery around FISH-BUILD-VERSION-FILE
|
||||
# This defines the FBVF variable.
|
||||
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}"
|
||||
"FISH_USE_PREBUILT_DOCS=${USE_PREBUILT_DOCS}"
|
||||
)
|
||||
|
||||
# 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_SOURCE_DIR "${CMAKE_SOURCE_DIR}" REALPATH)
|
||||
add_definitions(-DCMAKE_BINARY_DIR="${REAL_CMAKE_BINARY_DIR}")
|
||||
add_definitions(-DCMAKE_SOURCE_DIR="${REAL_CMAKE_SOURCE_DIR}")
|
||||
|
||||
set(build_types Release RelWithDebInfo Debug "")
|
||||
if(NOT "${CMAKE_BUILD_TYPE}" IN_LIST build_types)
|
||||
message(WARNING "Unsupported build type ${CMAKE_BUILD_TYPE}. If this doesn't build, try one of Release, RelWithDebInfo or Debug")
|
||||
endif()
|
||||
# Teach fish_version.o to rebuild when FBVF changes.
|
||||
# The standard C++ include detection machinery misses this.
|
||||
set_source_files_properties(src/fish_version.cpp
|
||||
PROPERTIES OBJECT_DEPENDS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${FBVF})
|
||||
|
||||
# Define a function to build and link dependencies.
|
||||
function(CREATE_TARGET target)
|
||||
add_custom_target(
|
||||
${target} ALL
|
||||
COMMAND
|
||||
"${CMAKE_COMMAND}" -E
|
||||
env ${VARS_FOR_CARGO}
|
||||
${Rust_CARGO}
|
||||
build --bin ${target}
|
||||
$<$<CONFIG:Release>:--release>
|
||||
$<$<CONFIG:RelWithDebInfo>:--profile=release-with-debug>
|
||||
--target ${Rust_CARGO_TARGET}
|
||||
--no-default-features
|
||||
--features=${FISH_CARGO_FEATURES}
|
||||
${CARGO_FLAGS}
|
||||
&&
|
||||
"${CMAKE_COMMAND}" -E
|
||||
copy "${rust_target_dir}/${rust_profile}/${target}" "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
USES_TERMINAL
|
||||
)
|
||||
endfunction(CREATE_TARGET)
|
||||
# Enable thread-safe errno on Solaris (#5611)
|
||||
add_definitions(-D_REENTRANT)
|
||||
|
||||
# Set up PCRE2
|
||||
include(cmake/PCRE2.cmake)
|
||||
|
||||
# Define a function to link dependencies.
|
||||
function(FISH_LINK_DEPS_AND_SIGN target)
|
||||
target_link_libraries(${target} fishlib)
|
||||
codesign_on_mac(${target})
|
||||
endfunction(FISH_LINK_DEPS_AND_SIGN)
|
||||
|
||||
# Define libfish.a.
|
||||
add_library(fishlib STATIC ${FISH_SRCS})
|
||||
target_sources(fishlib PRIVATE ${FISH_HEADERS})
|
||||
target_link_libraries(fishlib
|
||||
${CURSES_LIBRARY} ${CURSES_EXTRA_LIBRARY} Threads::Threads ${CMAKE_DL_LIBS}
|
||||
${PCRE2_LIB} ${Intl_LIBRARIES} ${ATOMIC_LIBRARY})
|
||||
|
||||
# Define fish.
|
||||
create_target(fish)
|
||||
add_executable(fish src/fish.cpp)
|
||||
fish_link_deps_and_sign(fish)
|
||||
|
||||
# Define fish_indent.
|
||||
create_target(fish_indent)
|
||||
add_executable(fish_indent
|
||||
src/fish_indent.cpp src/print_help.cpp)
|
||||
fish_link_deps_and_sign(fish_indent)
|
||||
|
||||
# Define fish_key_reader.
|
||||
create_target(fish_key_reader)
|
||||
add_executable(fish_key_reader
|
||||
src/fish_key_reader.cpp src/print_help.cpp)
|
||||
fish_link_deps_and_sign(fish_key_reader)
|
||||
|
||||
# Set up the docs.
|
||||
include(cmake/Docs.cmake)
|
||||
|
||||
# A helper for running tests.
|
||||
add_executable(fish_test_helper src/fish_test_helper.cpp)
|
||||
|
||||
# Set up tests.
|
||||
include(cmake/Tests.cmake)
|
||||
@@ -102,5 +211,20 @@ include(cmake/Install.cmake)
|
||||
# Mac app.
|
||||
include(cmake/MacApp.cmake)
|
||||
|
||||
# Lint targets
|
||||
# This could be implemented as target properties, but the script has the useful feature of only
|
||||
# checking the currently-staged commands
|
||||
# The generator expressions below rebuild the command line for the fishlib targets
|
||||
# CMake does not support the "iquote" flag - https://gitlab.kitware.com/cmake/cmake/issues/15491
|
||||
set(LINT_ARGS "-D$<JOIN:$<TARGET_PROPERTY:fishlib,COMPILE_DEFINITIONS>, -D>" "-I$<JOIN:$<TARGET_PROPERTY:fishlib,INCLUDE_DIRECTORIES>, -I>")
|
||||
add_custom_target(lint
|
||||
COMMAND build_tools/lint.fish -p ${CMAKE_BINARY_DIR} -- ${LINT_ARGS}
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
)
|
||||
add_custom_target(lint-all
|
||||
COMMAND build_tools/lint.fish --all -p ${CMAKE_BINARY_DIR} -- ${LINT_ARGS}
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
)
|
||||
|
||||
include(FeatureSummary)
|
||||
feature_summary(WHAT ALL)
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
643
CONTRIBUTING.rst
643
CONTRIBUTING.rst
@@ -1,136 +1,187 @@
|
||||
####################
|
||||
Contributing To Fish
|
||||
####################
|
||||
Guidelines For Developers
|
||||
=========================
|
||||
|
||||
This document tells you how you can contribute to fish.
|
||||
This document provides guidelines for making changes to the fish-shell
|
||||
project. This includes rules for how to format the code, naming
|
||||
conventions, et cetera. Generally known as the style of the code. It
|
||||
also includes recommended best practices such as creating a Travis CI
|
||||
account so you can verify that your changes pass all the tests before
|
||||
making a pull request.
|
||||
|
||||
Fish is free and open source software, distributed under the terms of the GPLv2.
|
||||
See the bottom of this document for help on installing the linting and
|
||||
style reformatting tools discussed in the following sections.
|
||||
|
||||
Contributions are welcome, and there are many ways to contribute!
|
||||
Fish source should limit the C++ features it uses to those available in
|
||||
C++11. It should not use exceptions.
|
||||
|
||||
Whether you want to change some of the core Rust source, enhance or add a completion script or function,
|
||||
improve the documentation or translate something, this document will tell you how.
|
||||
Before introducing a new dependency, please make it optional with
|
||||
graceful failure if possible. Add any new dependencies to the README.rst
|
||||
under the *Running* and/or *Building* sections.
|
||||
|
||||
Versioning
|
||||
----------
|
||||
|
||||
Mailing List
|
||||
============
|
||||
The fish version is constructed by the *build_tools/git_version_gen.sh*
|
||||
script. For developers the version is the branch name plus the output of
|
||||
``git describe --always --dirty``. Normally the main part of the version
|
||||
will be the closest annotated tag. Which itself is usually the most
|
||||
recent release number (e.g., ``2.6.0``).
|
||||
|
||||
Send patches to the public mailing list: mailto:~krobelus/fish-shell@lists.sr.ht.
|
||||
Archives are available at https://lists.sr.ht/~krobelus/fish-shell/.
|
||||
Include What You Use
|
||||
--------------------
|
||||
|
||||
GitHub
|
||||
======
|
||||
You should not depend on symbols being visible to a ``*.cpp`` module
|
||||
from ``#include`` statements inside another header file. In other words
|
||||
if your module does ``#include "common.h"`` and that header does
|
||||
``#include "signal.h"`` your module should not assume the sub-include is
|
||||
present. It should instead directly ``#include "signal.h"`` if it needs
|
||||
any symbol from that header. That makes the actual dependencies much
|
||||
clearer. It also makes it easy to modify the headers included by a
|
||||
specific header file without having to worry that will break any module
|
||||
(or header) that includes a particular header.
|
||||
|
||||
Fish is available on Github, at https://github.com/fish-shell/fish-shell.
|
||||
To help enforce this rule the ``make lint`` (and ``make lint-all``)
|
||||
command will run the
|
||||
`include-what-you-use <https://include-what-you-use.org/>`__ tool. You
|
||||
can find the IWYU project on
|
||||
`github <https://github.com/include-what-you-use/include-what-you-use>`__.
|
||||
|
||||
First, you'll need an account there, and you'll need a git clone of fish.
|
||||
Fork it on Github and then run::
|
||||
To install the tool on OS X you’ll need to add a
|
||||
`formula <https://github.com/jasonmp85/homebrew-iwyu>`__ then install
|
||||
it:
|
||||
|
||||
git clone https://github.com/<USERNAME>/fish-shell.git
|
||||
::
|
||||
|
||||
This will create a copy of the fish repository in the directory fish-shell in your current working directory.
|
||||
brew tap jasonmp85/iwyu
|
||||
brew install iwyu
|
||||
|
||||
Also, for most changes you want to run the tests and so you'd get a setup to compile fish.
|
||||
For that, you'll require:
|
||||
On Ubuntu you can install it via ``apt-get``:
|
||||
|
||||
- Rust - when in doubt, try rustup
|
||||
- CMake
|
||||
- PCRE2 (headers and libraries) - optional, this will be downloaded if missing
|
||||
- gettext (only the msgfmt tool) - optional, for translation support
|
||||
- Sphinx - optional, to build the documentation
|
||||
::
|
||||
|
||||
Of course not everything is required always - if you just want to contribute something to the documentation you'll just need Sphinx,
|
||||
and if the change is very simple and obvious you can just send it in. Use your judgement!
|
||||
sudo apt-get install iwyu
|
||||
|
||||
Once you have your changes, open a pull request on https://github.com/fish-shell/fish-shell/pulls.
|
||||
Lint Free Code
|
||||
--------------
|
||||
|
||||
Guidelines
|
||||
==========
|
||||
Automated analysis tools like cppcheck and oclint can point out
|
||||
potential bugs or code that is extremely hard to understand. They also
|
||||
help ensure the code has a consistent style and that it avoids patterns
|
||||
that tend to confuse people.
|
||||
|
||||
In short:
|
||||
Ultimately we want lint free code. However, at the moment a lot of
|
||||
cleanup is required to reach that goal. For now simply try to avoid
|
||||
introducing new lint.
|
||||
|
||||
- Be conservative in what you need (keep to the agreed minimum supported Rust version, limit new dependencies)
|
||||
- Use automated tools to help you (``build_tools/check.sh``)
|
||||
To make linting the code easy there are two make targets: ``lint`` and
|
||||
``lint-all``. The latter does exactly what the name implies. The former
|
||||
will lint any modified but not committed ``*.cpp`` files. If there is no
|
||||
uncommitted work it will lint the files in the most recent commit.
|
||||
|
||||
Contributing completions
|
||||
========================
|
||||
Fish has custom cppcheck rules in the file ``.cppcheck.rule``. These
|
||||
help catch mistakes such as using ``wcwidth()`` rather than
|
||||
``fish_wcwidth()``. Please add a new rule if you find similar mistakes
|
||||
being made.
|
||||
|
||||
Completion scripts are the most common contribution to fish, and they are very welcome.
|
||||
Fish also depends on ``diff`` and ``expect`` for its tests.
|
||||
|
||||
In general, we'll take all well-written completion scripts for a command that is publicly available.
|
||||
This means no private tools or personal scripts, and we do reserve the right to reject for other reasons.
|
||||
Dealing With Lint Warnings
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Before you try to contribute them to fish, consider if the authors of the tool you are completing want to maintain the script instead.
|
||||
Often that makes more sense, specifically because they can add new options to the script immediately once they add them,
|
||||
and don't have to maintain one completion script for multiple versions. If the authors no longer wish to maintain the script,
|
||||
they can of course always contact the fish maintainers to hand it over, preferably by opening a PR.
|
||||
This isn't a requirement - if the authors don't want to maintain it, or you simply don't want to contact them,
|
||||
you can contribute your script to fish.
|
||||
You are strongly encouraged to address a lint warning by refactoring the
|
||||
code, changing variable names, or whatever action is implied by the
|
||||
warning.
|
||||
|
||||
Completion scripts should
|
||||
Suppressing Lint Warnings
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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)
|
||||
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.
|
||||
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.
|
||||
5. Run ``fish_indent`` on your script.
|
||||
6. Try not to use minor convenience features right after they are available in fish - we do try to keep completion scripts backportable.
|
||||
If something has a real impact on the correctness or performance, feel free to use it,
|
||||
but if it is just a shortcut, please leave it.
|
||||
Once in a while the lint tools emit a false positive warning. For
|
||||
example, cppcheck might suggest a memory leak is present when that is
|
||||
not the case. To suppress that cppcheck warning you should insert a line
|
||||
like the following immediately prior to the line cppcheck warned about:
|
||||
|
||||
Put your completion script into share/completions/name-of-command.fish. If you have multiple commands, you need multiple files.
|
||||
::
|
||||
|
||||
If you want to add tests, you probably want to add a littlecheck test. See below for details.
|
||||
// cppcheck-suppress memleak // addr not really leaked
|
||||
|
||||
Contributing documentation
|
||||
==========================
|
||||
The explanatory portion of the suppression comment is optional. For
|
||||
other types of warnings replace “memleak” with the value inside the
|
||||
parenthesis (e.g., “nullPointerRedundantCheck”) from a warning like the
|
||||
following:
|
||||
|
||||
The documentation is stored in ``doc_src/``, and written in ReStructured Text and built with Sphinx.
|
||||
::
|
||||
|
||||
To build it locally, run from the main fish-shell directory::
|
||||
[src/complete.cpp:1727]: warning (nullPointerRedundantCheck): Either the condition 'cmd_node' is redundant or there is possible null pointer dereference: cmd_node.
|
||||
|
||||
sphinx-build -j 8 -b html -n doc_src/ /tmp/fish-doc/
|
||||
Suppressing oclint warnings is more complicated to describe so I’ll
|
||||
refer you to the `OCLint
|
||||
HowTo <http://docs.oclint.org/en/latest/howto/suppress.html#annotations>`__
|
||||
on the topic.
|
||||
|
||||
which will build the docs as html in /tmp/fish-doc. You can open it in a browser and see that it looks okay.
|
||||
Ensuring Your Changes Conform to the Style Guides
|
||||
-------------------------------------------------
|
||||
|
||||
The builtins and various functions shipped with fish are documented in doc_src/cmds/.
|
||||
The following sections discuss the specific rules for the style that
|
||||
should be used when writing fish code. To ensure your changes conform to
|
||||
the style rules you simply need to run
|
||||
|
||||
Code Style
|
||||
==========
|
||||
::
|
||||
|
||||
For formatting, we use:
|
||||
build_tools/style.fish
|
||||
|
||||
- ``rustfmt`` for Rust
|
||||
- ``fish_indent`` (shipped with fish) for fish script
|
||||
- ``ruff format`` for Python
|
||||
before committing your change. That will run ``git-clang-format`` to
|
||||
rewrite only the lines you’re modifying.
|
||||
|
||||
To reformat files, there is a script
|
||||
If you’ve already committed your changes that’s okay since it will then
|
||||
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 somefile.rs some.fish
|
||||
|
||||
Fish Script Style Guide
|
||||
-----------------------
|
||||
That command will refuse to restyle any files if you have uncommitted
|
||||
changes.
|
||||
|
||||
1. All fish scripts, such as those in the *share/functions* and *tests*
|
||||
directories, should be formatted using the ``fish_indent`` command.
|
||||
Configuring Your Editor for Fish C++ Code
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
2. Function names should be in all lowercase with words separated by
|
||||
underscores. Private functions should begin with an underscore. The
|
||||
first word should be ``fish`` if the function is unique to fish.
|
||||
ViM
|
||||
^^^
|
||||
|
||||
3. The first word of global variable names should generally be ``fish``
|
||||
for public vars or ``_fish`` for private vars to minimize the
|
||||
possibility of name clashes with user defined vars.
|
||||
As of ViM 7.4 it does not recognize triple-slash comments as used by
|
||||
Doxygen and the OS X Xcode IDE to flag comments that explain the
|
||||
following C symbol. This means the ``gq`` key binding to reformat such
|
||||
comments doesn’t behave as expected. You can fix that by adding the
|
||||
following to your vimrc:
|
||||
|
||||
::
|
||||
|
||||
autocmd Filetype c,cpp setlocal comments^=:///
|
||||
|
||||
If you use ViM I recommend the `vim-clang-format
|
||||
plugin <https://github.com/rhysd/vim-clang-format>`__ by
|
||||
[@rhysd](https://github.com/rhysd).
|
||||
|
||||
You can also get ViM to provide reasonably correct behavior by
|
||||
installing
|
||||
|
||||
http://www.vim.org/scripts/script.php?script_id=2636
|
||||
|
||||
Emacs
|
||||
^^^^^
|
||||
|
||||
If you use Emacs: TBD
|
||||
|
||||
Configuring Your Editor for Fish Scripts
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you use Vim: Install `vim-fish <https://github.com/dag/vim-fish>`__,
|
||||
If you use ViM: Install `vim-fish <https://github.com/dag/vim-fish>`__,
|
||||
make sure you have syntax and filetype functionality in ``~/.vimrc``:
|
||||
|
||||
::
|
||||
@@ -163,212 +214,286 @@ made to run fish_indent via e.g.
|
||||
(add-hook 'fish-mode-hook (lambda ()
|
||||
(add-hook 'before-save-hook 'fish_indent-before-save)))
|
||||
|
||||
Minimum Supported Rust Version (MSRV) Policy
|
||||
--------------------------------------------
|
||||
Suppressing Reformatting of C++ Code
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We support at least the version of ``rustc`` available in Debian Stable.
|
||||
If you have a good reason for doing so you can tell ``clang-format`` to
|
||||
not reformat a block of code by enclosing it in comments like this:
|
||||
|
||||
::
|
||||
|
||||
// clang-format off
|
||||
code to ignore
|
||||
// clang-format on
|
||||
|
||||
However, as I write this there are no places in the code where we use
|
||||
this and I can’t think of any legitimate reasons for exempting blocks of
|
||||
code from clang-format.
|
||||
|
||||
Fish Script Style Guide
|
||||
-----------------------
|
||||
|
||||
1. All fish scripts, such as those in the *share/functions* and *tests*
|
||||
directories, should be formatted using the ``fish_indent`` command.
|
||||
|
||||
2. Function names should be in all lowercase with words separated by
|
||||
underscores. Private functions should begin with an underscore. The
|
||||
first word should be ``fish`` if the function is unique to fish.
|
||||
|
||||
3. The first word of global variable names should generally be ``fish``
|
||||
for public vars or ``_fish`` for private vars to minimize the
|
||||
possibility of name clashes with user defined vars.
|
||||
|
||||
C++ Style Guide
|
||||
---------------
|
||||
|
||||
1. The `Google C++ Style
|
||||
Guide <https://google.github.io/styleguide/cppguide.html>`__ forms
|
||||
the basis of the fish C++ style guide. There are two major deviations
|
||||
for the fish project. First, a four, rather than two, space indent.
|
||||
Second, line lengths up to 100, rather than 80, characters.
|
||||
|
||||
2. The ``clang-format`` command is authoritative with respect to
|
||||
indentation, whitespace around operators, etc.
|
||||
|
||||
3. All names in code should be ``small_snake_case``. No Hungarian
|
||||
notation is used. The names for classes and structs should be
|
||||
followed by ``_t``.
|
||||
|
||||
4. Always attach braces to the surrounding context.
|
||||
|
||||
5. Indent with spaces, not tabs and use four spaces per indent.
|
||||
|
||||
6. Document the purpose of a function or class with doxygen-style
|
||||
comment blocks. e.g.:
|
||||
|
||||
::
|
||||
|
||||
/**
|
||||
* Sum numbers in a vector.
|
||||
*
|
||||
* @param values Container whose values are summed.
|
||||
* @return sum of `values`, or 0.0 if `values` is empty.
|
||||
*/
|
||||
double sum(std::vector<double> & const values) {
|
||||
...
|
||||
}
|
||||
*/
|
||||
|
||||
or
|
||||
|
||||
::
|
||||
|
||||
/// brief description of somefunction()
|
||||
void somefunction() {
|
||||
|
||||
Testing
|
||||
=======
|
||||
-------
|
||||
|
||||
The source code for fish includes a large collection of tests. If you
|
||||
are making any changes to fish, running these tests is a good way to make
|
||||
are making any changes to fish, running these tests is mandatory to make
|
||||
sure the behaviour remains consistent and regressions are not
|
||||
introduced. Even if you don’t run the tests on your machine, they will
|
||||
still be run via Github Actions.
|
||||
still be run via the `Travis
|
||||
CI <https://travis-ci.org/fish-shell/fish-shell>`__ service.
|
||||
|
||||
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
|
||||
regressions in the future (i.e., we don’t reintroduce the bug).
|
||||
|
||||
Unit tests live next to the implementation in Rust source files, in inline submodules (``mod tests {}``).
|
||||
|
||||
System tests live in ``tests/``:
|
||||
|
||||
- ``tests/checks`` are run by `littlecheck <https://github.com/ridiculousfish/littlecheck>`__
|
||||
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/>`__
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
-------------
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The tests can be run on your local system::
|
||||
|
||||
cargo build
|
||||
# Run unit 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.
|
||||
In this example we're in the root of the workspace and have run ``cargo build`` without ``--release``, so it's a debug build.
|
||||
|
||||
To run all tests and linters, use::
|
||||
|
||||
build_tools/check.sh
|
||||
|
||||
Contributing Translations
|
||||
=========================
|
||||
|
||||
Fish uses GNU gettext to translate messages from English to other languages.
|
||||
We use custom tools for extracting messages from source files and to localize at runtime.
|
||||
This means that we do not have a runtime dependency on the gettext library.
|
||||
It also means that some features are not supported, such as message context and plurals.
|
||||
We also expect all files to be UTF-8-encoded.
|
||||
In practice, this should not matter much for contributing translations.
|
||||
|
||||
Translation sources are
|
||||
stored in the ``po`` directory, named ``ll_CC.po``, where ``ll`` is the
|
||||
two (or possibly three) letter ISO 639-1 language code of the target language
|
||||
(e.g. ``pt`` for Portuguese). ``CC`` is an ISO 3166 country/territory code,
|
||||
(e.g. ``BR`` for Brazil).
|
||||
An example for a valid name is ``pt_BR.po``, indicating Brazilian Portuguese.
|
||||
These are the files you will interact with when adding translations.
|
||||
|
||||
Adding translations for a new language
|
||||
--------------------------------------
|
||||
|
||||
Creating new translations requires the Gettext tools.
|
||||
More specifically, you will need ``msguniq`` and ``msgmerge`` for creating translations for a new
|
||||
language.
|
||||
To create a new translation, run::
|
||||
|
||||
build_tools/update_translations.fish po/ll_CC.po
|
||||
|
||||
This will create a new PO file containing all messages available for translation.
|
||||
If the file already exists, it will be updated.
|
||||
|
||||
After modifying a PO file, you can recompile fish, and it will integrate the modifications you made.
|
||||
This requires that the ``msgfmt`` utility is installed (comes as part of ``gettext``).
|
||||
It is important that the ``localize-messages`` cargo feature is enabled, which it is by default.
|
||||
You can explicitly enable it using::
|
||||
|
||||
cargo build --features=localize-messages
|
||||
|
||||
Use environment variables to tell fish which language to use, e.g.::
|
||||
|
||||
LANG=pt_BR.utf8 fish
|
||||
|
||||
or within the running fish shell::
|
||||
|
||||
set LANG pt_BR.utf8
|
||||
|
||||
For more options regarding how to choose languages, see
|
||||
`the corresponding gettext documentation
|
||||
<https://www.gnu.org/software/gettext/manual/html_node/Locale-Environment-Variables.html>`__.
|
||||
One neat thing you can do is set a list of languages to check for translations in the order defined
|
||||
using the ``LANGUAGE`` variable, e.g.::
|
||||
|
||||
set LANGUAGE pt_BR de_DE
|
||||
|
||||
to try to translate messages to Portuguese, if that fails try German, and if that fails too you will
|
||||
see the English version defined in the source code.
|
||||
|
||||
Modifying existing translations
|
||||
-------------------------------
|
||||
|
||||
If you want to work on translations for a language which already has a corresponding ``po`` file, it
|
||||
is sufficient to edit this file. No other changes are necessary.
|
||||
|
||||
After recompiling fish, you should be able to see your translations in action. See the previous
|
||||
section for details.
|
||||
|
||||
Editing PO files
|
||||
----------------
|
||||
|
||||
Many tools are available for editing translation files, including
|
||||
command-line and graphical user interface programs. For simple use, you can use your text editor.
|
||||
|
||||
Open up the PO file, for example ``po/sv.po``, and you'll see something like::
|
||||
|
||||
msgid "%s: No suitable job\n"
|
||||
msgstr ""
|
||||
|
||||
The ``msgid`` here is the "name" of the string to translate, typically the English string to translate.
|
||||
The second line (``msgstr``) is where your translation goes.
|
||||
|
||||
For example::
|
||||
|
||||
msgid "%s: No suitable job\n"
|
||||
msgstr "%s: Inget passande jobb\n"
|
||||
|
||||
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.
|
||||
|
||||
Our tests run ``msgfmt --check-format /path/to/file``, so they would catch mismatched placeholders - otherwise fish would crash at runtime when the string is about to be used.
|
||||
|
||||
Be cautious about blindly updating an existing translation file.
|
||||
``msgid`` strings should never be updated manually, only by running the appropriate script.
|
||||
|
||||
Modifications to strings in source files
|
||||
----------------------------------------
|
||||
|
||||
If a string changes in the sources, the old translations will no longer work.
|
||||
They will be preserved in the PO files, but commented-out (starting with ``#~``).
|
||||
If you add/remove/change a translatable strings in a source file,
|
||||
run ``build_tools/update_translations.fish`` to propagate this to all translation files (``po/*.po``).
|
||||
This is only relevant for developers modifying the source files of fish or fish scripts.
|
||||
|
||||
Setting Code Up For Translations
|
||||
--------------------------------
|
||||
|
||||
All non-debug messages output for user consumption should be marked for
|
||||
translation. In Rust, this requires the use of the ``wgettext!`` or ``wgettext_fmt!``
|
||||
macros:
|
||||
The tests can be run on your local computer on all operating systems.
|
||||
|
||||
::
|
||||
|
||||
streams.out.append(wgettext_fmt!("%s: There are no jobs\n", argv[0]));
|
||||
cmake path/to/fish-shell
|
||||
make test
|
||||
|
||||
Travis CI Build and Test
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The Travis Continuous Integration services can be used to test your
|
||||
changes using multiple configurations. This is the same service that the
|
||||
fish-shell project uses to ensure new changes haven’t broken anything.
|
||||
Thus it is a really good idea that you leverage Travis CI before making
|
||||
a pull request to avoid potential embarrassment at breaking the build.
|
||||
|
||||
You will need to `fork the fish-shell repository on
|
||||
GitHub <https://help.github.com/articles/fork-a-repo/>`__, then setup
|
||||
Travis to test your changes before making a pull request.
|
||||
|
||||
1. `Sign in to Travis CI <https://travis-ci.org/auth>`__ with your
|
||||
GitHub account, accepting the GitHub access permissions confirmation.
|
||||
2. Once you’re signed in and your repositories are synchronized, go to
|
||||
your `profile page <https://travis-ci.org/profile>`__ and enable the
|
||||
fish-shell repository.
|
||||
3. Push your changes to GitHub.
|
||||
|
||||
You’ll receive an email when the tests are complete telling you whether
|
||||
or not any tests failed.
|
||||
|
||||
You’ll find the configuration used to control Travis in the
|
||||
``.travis.yml`` file.
|
||||
|
||||
Git hooks
|
||||
~~~~~~~~~
|
||||
|
||||
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
|
||||
while read from _ to _; do
|
||||
if [ "x$to" = "xrefs/heads/$protected_branch" ]; then
|
||||
isprotected=1
|
||||
fi
|
||||
done
|
||||
if [ "x$isprotected" = x1 ]; then
|
||||
echo "Running tests before push to master"
|
||||
make test
|
||||
RESULT=$?
|
||||
if [ $RESULT -ne 0 ]; then
|
||||
echo "Tests failed for a push to master, we can't let you do that" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
exit 0
|
||||
|
||||
This will check if the push is to the master branch and, if it is, only
|
||||
allow the push if running ``make test`` 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.
|
||||
|
||||
Coverity Scan
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
We use Coverity’s static analysis tool which offers free access to open
|
||||
source projects. While access to the tool itself is restricted,
|
||||
fish-shell organization members should know that they can login
|
||||
`here <https://scan.coverity.com/projects/fish-shell-fish-shell?tab=overview>`__
|
||||
with their GitHub account. Currently, tests are triggered upon merging
|
||||
the ``master`` branch into ``coverity_scan_master``. Even if you are not
|
||||
a fish developer, you can keep an eye on our statistics there.
|
||||
|
||||
Installing the Required Tools
|
||||
-----------------------------
|
||||
|
||||
Installing the Linting Tools
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To install the lint checkers on Mac OS X using Homebrew:
|
||||
|
||||
::
|
||||
|
||||
brew tap oclint/formulae
|
||||
brew install oclint
|
||||
brew install cppcheck
|
||||
|
||||
To install the lint checkers on Debian-based Linux distributions:
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install clang
|
||||
sudo apt-get install oclint
|
||||
sudo apt-get install cppcheck
|
||||
|
||||
Installing the Reformatting Tools
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Mac OS X:
|
||||
|
||||
::
|
||||
|
||||
brew install clang-format
|
||||
|
||||
Debian-based:
|
||||
|
||||
::
|
||||
|
||||
apt-cache search clang-format
|
||||
|
||||
Above will list all the versions available. Pick the newest one
|
||||
available (3.9 for Ubuntu 16.10 as I write this) and install it:
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install clang-format-3.9
|
||||
sudo ln -s /usr/bin/clang-format-3.9 /usr/bin/clang-format
|
||||
|
||||
Message Translations
|
||||
--------------------
|
||||
|
||||
Fish uses the GNU gettext library to translate messages from English to
|
||||
other languages.
|
||||
|
||||
All non-debug messages output for user consumption should be marked for
|
||||
translation. In C++, this requires the use of the ``_`` (underscore)
|
||||
macro:
|
||||
|
||||
::
|
||||
|
||||
streams.out.append_format(_(L"%ls: There are no jobs\n"), argv[0]);
|
||||
|
||||
All messages in fish script must be enclosed in single or double quote
|
||||
characters for our message extraction script to find them.
|
||||
They must also be translated via a command substitution. This means
|
||||
characters. They must also be translated via a subcommand. This means
|
||||
that the following are **not** valid:
|
||||
|
||||
::
|
||||
|
||||
echo (_ hello)
|
||||
_ "goodbye"
|
||||
echo (_ hello)
|
||||
_ "goodbye"
|
||||
|
||||
Above should be written like this instead:
|
||||
|
||||
::
|
||||
|
||||
echo (_ "hello")
|
||||
echo (_ "goodbye")
|
||||
echo (_ "hello")
|
||||
echo (_ "goodbye")
|
||||
|
||||
You can use either single or double quotes to enclose the
|
||||
Note that you can use either single or double quotes to enclose the
|
||||
message to be translated. You can also optionally include spaces after
|
||||
the opening parentheses or before the closing parentheses.
|
||||
the opening parentheses and once again before the closing parentheses.
|
||||
|
||||
Updating Dependencies
|
||||
=====================
|
||||
Creating and updating translations requires the Gettext tools, including
|
||||
``xgettext``, ``msgfmt`` and ``msgmerge``. Translation sources are
|
||||
stored in the ``po`` directory, named ``LANG.po``, where ``LANG`` is the
|
||||
two letter ISO 639-1 language code of the target language (eg ``de`` for
|
||||
German).
|
||||
|
||||
To update dependencies, run ``build_tools/update-dependencies.sh``.
|
||||
This currently requires `updatecli <https://github.com/updatecli/updatecli>`__ and a few other tools.
|
||||
To create a new translation, for example for German: \* generate a
|
||||
``messages.pot`` file by running ``build_tools/fish_xgettext.fish`` from
|
||||
the source tree \* copy ``messages.pot`` to ``po/LANG.po`` ()
|
||||
|
||||
Versioning
|
||||
==========
|
||||
To update a translation: \* generate a ``messages.pot`` file by running
|
||||
``build_tools/fish_xgettext.fish`` from the source tree \* update the
|
||||
existing translation by running
|
||||
``msgmerge --update --no-fuzzy-matching po/LANG.po messages.pot``
|
||||
|
||||
The fish version is constructed by the *build_tools/git_version_gen.sh*
|
||||
script. For developers the version is the branch name plus the output of
|
||||
``git describe --always --dirty``. Normally the main part of the version
|
||||
will be the closest annotated tag. Which itself is usually the most
|
||||
recent release number (e.g., ``2.6.0``).
|
||||
Many tools are available for editing translation files, including
|
||||
command-line and graphical user interface programs.
|
||||
|
||||
Be cautious about blindly updating an existing translation file. Trivial
|
||||
changes to an existing message (eg changing the punctuation) will cause
|
||||
existing translations to be removed, since the tools do literal string
|
||||
matching. Therefore, in general, you need to carefully review any
|
||||
recommended deletions.
|
||||
|
||||
Read the `translations
|
||||
wiki <https://github.com/fish-shell/fish-shell/wiki/Translations>`__ for
|
||||
more information.
|
||||
|
||||
8
COPYING
8
COPYING
@@ -1,7 +1,7 @@
|
||||
Fish is a smart and user-friendly command line shell.
|
||||
|
||||
Copyright (C) 2005-2009 Axel Liljencrantz
|
||||
Copyright (C) 2009- fish-shell contributors
|
||||
Copyright (C) 2009-2020 fish-shell contributors
|
||||
|
||||
fish is free software.
|
||||
|
||||
@@ -9,10 +9,10 @@ Most of fish is licensed under the GNU General Public License version 2, and
|
||||
you can redistribute it and/or modify it under the terms of the GNU GPL as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
fish also includes software licensed under the Python Software Foundation License version 2, the MIT
|
||||
license, and the GNU Library General Public License version 2.
|
||||
fish also includes software licensed under the GNU Lesser General Public
|
||||
License version 2, the OpenBSD license, the ISC license, and the NetBSD license.
|
||||
|
||||
Full licensing information is contained in doc_src/license.rst.
|
||||
Full licensing information is contained in doc_src/license.hdr.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
|
||||
956
Cargo.lock
generated
956
Cargo.lock
generated
@@ -1,956 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
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]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4"
|
||||
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",
|
||||
"libc",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "cfg_aliases"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "errno"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127"
|
||||
|
||||
[[package]]
|
||||
name = "fish"
|
||||
version = "4.2.1"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"errno",
|
||||
"fish-build-helper",
|
||||
"fish-build-man-pages",
|
||||
"fish-gettext-extraction",
|
||||
"fish-gettext-maps",
|
||||
"fish-gettext-mo-file-parser",
|
||||
"fish-printf",
|
||||
"fish-tempfile",
|
||||
"libc",
|
||||
"lru",
|
||||
"macro_rules_attribute",
|
||||
"nix",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"pcre2",
|
||||
"phf 0.12.1",
|
||||
"phf_codegen 0.12.1",
|
||||
"portable-atomic",
|
||||
"rand",
|
||||
"rsconf",
|
||||
"rust-embed",
|
||||
"serial_test",
|
||||
"terminfo",
|
||||
"unix_path",
|
||||
"widestring",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fish-build-helper"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rsconf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fish-build-man-pages"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"fish-build-helper",
|
||||
"rsconf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fish-gettext-extraction"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fish-gettext-maps"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"fish-build-helper",
|
||||
"fish-gettext-mo-file-parser",
|
||||
"phf 0.12.1",
|
||||
"phf_codegen 0.12.1",
|
||||
"rsconf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fish-gettext-mo-file-parser"
|
||||
version = "0.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "fish-printf"
|
||||
version = "0.2.1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
"widestring",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fish-tempfile"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"nix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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 = [
|
||||
"allocator-api2",
|
||||
"equivalent",
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
|
||||
dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.177"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "lock_api"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
|
||||
|
||||
[[package]]
|
||||
name = "lru"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "macro_rules_attribute"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65049d7923698040cd0b1ddcced9b0eb14dd22c5f86ae59c3740eab64a676520"
|
||||
dependencies = [
|
||||
"macro_rules_attribute-proc_macro",
|
||||
"paste",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "macro_rules_attribute-proc_macro"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "670fdfda89751bc4a84ac13eaa63e205cf0fd22b4c9a5fbfa085b63c1f1d3a30"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.30.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "option-ext"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||
|
||||
[[package]]
|
||||
name = "pcre2"
|
||||
version = "0.2.9"
|
||||
source = "git+https://github.com/fish-shell/rust-pcre2?tag=0.2.9-utf32#85b7afba1a9d9bd445779800e5bcafeb732e4421"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"pcre2-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pcre2-sys"
|
||||
version = "0.2.9"
|
||||
source = "git+https://github.com/fish-shell/rust-pcre2?tag=0.2.9-utf32#85b7afba1a9d9bd445779800e5bcafeb732e4421"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
|
||||
dependencies = [
|
||||
"phf_shared 0.11.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7"
|
||||
dependencies = [
|
||||
"phf_shared 0.12.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_codegen"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
|
||||
dependencies = [
|
||||
"phf_generator 0.11.3",
|
||||
"phf_shared 0.11.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_codegen"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efbdcb6f01d193b17f0b9c3360fa7e0e620991b193ff08702f78b3ce365d7e61"
|
||||
dependencies = [
|
||||
"phf_generator 0.12.1",
|
||||
"phf_shared 0.12.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
|
||||
dependencies = [
|
||||
"phf_shared 0.11.3",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2cbb1126afed61dd6368748dae63b1ee7dc480191c6262a3b4ff1e29d86a6c5b"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"phf_shared 0.12.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
|
||||
dependencies = [
|
||||
"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]]
|
||||
name = "rsconf"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd2af859f1af0401e7fc7577739c87b0d239d8a5da400d717183bca92336bcdc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed"
|
||||
version = "8.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb44e1917075637ee8c7bcb865cf8830e3a92b5b1189e44e3a0ab5a0d5be314b"
|
||||
dependencies = [
|
||||
"rust-embed-impl",
|
||||
"rust-embed-utils",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-impl"
|
||||
version = "8.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "382499b49db77a7c19abd2a574f85ada7e9dbe125d5d1160fa5cad7c4cf71fc9"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rust-embed-utils",
|
||||
"shellexpand",
|
||||
"syn",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-utils"
|
||||
version = "8.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21fcbee55c2458836bcdbfffb6ec9ba74bbc23ca7aa6816015a3dd2c4d8fc185"
|
||||
dependencies = [
|
||||
"globset",
|
||||
"sha2",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scc"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46e6f046b7fef48e2660c57ed794263155d713de679057f2d0c169bfc6e756cc"
|
||||
dependencies = [
|
||||
"sdd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "sdd"
|
||||
version = "3.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "serial_test"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"scc",
|
||||
"serial_test_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serial_test_derive"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shellexpand"
|
||||
version = "3.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b1fdf65dd6331831494dd616b30351c38e96e45921a27745cf98490458b90bb"
|
||||
dependencies = [
|
||||
"dirs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "terminfo"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4ea810f0692f9f51b382fff5893887bb4580f5fa246fde546e0b13e7fcee662"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"nom",
|
||||
"phf 0.11.3",
|
||||
"phf_codegen 0.11.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
||||
|
||||
[[package]]
|
||||
name = "unix_path"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af8e291873ae77c4c8d9c9b34d0bee68a35b048fb39c263a5155e0e353783eaf"
|
||||
dependencies = [
|
||||
"unix_str",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unix_str"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ace0b4755d0a2959962769239d56267f8a024fef2d9b32666b3dcd0946b0906"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
|
||||
189
Cargo.toml
189
Cargo.toml
@@ -1,189 +0,0 @@
|
||||
[workspace]
|
||||
members = ["crates/*"]
|
||||
|
||||
[workspace.package]
|
||||
# To build revisions that use Corrosion (those before 2024-01), use CMake 3.19, Rustc 1.78 and Rustup 1.27.
|
||||
rust-version = "1.85"
|
||||
edition = "2024"
|
||||
repository = "https://github.com/fish-shell/fish-shell"
|
||||
|
||||
[workspace.dependencies]
|
||||
bitflags = "2.5.0"
|
||||
cc = "1.0.94"
|
||||
cfg-if = "1.0.3"
|
||||
errno = "0.3.0"
|
||||
fish-build-helper = { path = "crates/build-helper" }
|
||||
fish-build-man-pages = { path = "crates/build-man-pages" }
|
||||
fish-gettext-extraction = { path = "crates/gettext-extraction" }
|
||||
fish-gettext-maps = { path = "crates/gettext-maps" }
|
||||
fish-gettext-mo-file-parser = { path = "crates/gettext-mo-file-parser" }
|
||||
fish-printf = { path = "crates/printf", features = ["widestring"] }
|
||||
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.
|
||||
# disabling default features uses the stdlib instead, but it doubles the time to rewrite the history
|
||||
# files as of 22 April 2024.
|
||||
lru = "0.13.0"
|
||||
nix = { version = "0.30.1", default-features = false, features = [
|
||||
"event",
|
||||
"inotify",
|
||||
"resource",
|
||||
"fs",
|
||||
] }
|
||||
num-traits = "0.2.19"
|
||||
once_cell = "1.19.0"
|
||||
pcre2 = { git = "https://github.com/fish-shell/rust-pcre2", tag = "0.2.9-utf32", default-features = false, features = [
|
||||
"utf32",
|
||||
] }
|
||||
phf = { version = "0.12", default-features = false }
|
||||
phf_codegen = { version = "0.12" }
|
||||
portable-atomic = { version = "1", default-features = false, features = [
|
||||
"fallback",
|
||||
] }
|
||||
proc-macro2 = "1.0"
|
||||
# Don't use the "getrandom" feature as it requires "getentropy" which was not
|
||||
# available on macOS < 10.12. We can enable "getrandom" when we raise the
|
||||
# minimum supported version to 10.12.
|
||||
rand = { version = "0.8.5", default-features = false, features = ["small_rng"] }
|
||||
rsconf = "0.2.2"
|
||||
rust-embed = { version = "8.7.2", features = [
|
||||
"deterministic-timestamps",
|
||||
"include-exclude",
|
||||
"interpolate-folder-path",
|
||||
] }
|
||||
|
||||
serial_test = { version = "3", default-features = false }
|
||||
# We need 0.9.0 specifically for some crash fixes.
|
||||
terminfo = "0.9.0"
|
||||
widestring = "1.2.0"
|
||||
unicode-segmentation = "1.12.0"
|
||||
unicode-width = "0.2.0"
|
||||
unix_path = "1.0.1"
|
||||
|
||||
[profile.release]
|
||||
overflow-checks = true
|
||||
lto = true
|
||||
|
||||
[profile.release-with-debug]
|
||||
inherits = "release"
|
||||
debug = true
|
||||
|
||||
[package]
|
||||
name = "fish"
|
||||
version = "4.2.1"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
default-run = "fish"
|
||||
# see doc_src/license.rst for details
|
||||
# don't forget to update COPYING and debian/copyright too
|
||||
license = "GPL-2.0-only AND LGPL-2.0-or-later AND MIT AND PSF-2.0"
|
||||
homepage = "https://fishshell.com"
|
||||
readme = "README.rst"
|
||||
|
||||
[dependencies]
|
||||
bitflags.workspace = true
|
||||
cfg-if.workspace = true
|
||||
errno.workspace = true
|
||||
fish-build-helper.workspace = true
|
||||
fish-build-man-pages = { workspace = true, optional = true }
|
||||
fish-gettext-extraction = { workspace = true, optional = true }
|
||||
fish-gettext-maps = { workspace = true, optional = true }
|
||||
fish-printf.workspace = true
|
||||
fish-tempfile.workspace = true
|
||||
libc.workspace = true
|
||||
lru.workspace = true
|
||||
macro_rules_attribute = "0.2.2"
|
||||
nix.workspace = true
|
||||
num-traits.workspace = true
|
||||
once_cell.workspace = true
|
||||
pcre2.workspace = true
|
||||
phf = { workspace = true, optional = true }
|
||||
rand.workspace = true
|
||||
terminfo.workspace = true
|
||||
widestring.workspace = true
|
||||
|
||||
[target.'cfg(not(target_has_atomic = "64"))'.dependencies]
|
||||
portable-atomic.workspace = true
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
rust-embed = { workspace = true, optional = true, features = [
|
||||
"deterministic-timestamps",
|
||||
"debug-embed",
|
||||
"include-exclude",
|
||||
"interpolate-folder-path",
|
||||
] }
|
||||
[target.'cfg(not(windows))'.dependencies]
|
||||
rust-embed = { workspace = true, optional = true, features = [
|
||||
"deterministic-timestamps",
|
||||
"include-exclude",
|
||||
"interpolate-folder-path",
|
||||
] }
|
||||
|
||||
[dev-dependencies]
|
||||
serial_test.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
cc.workspace = true
|
||||
fish-build-helper.workspace = true
|
||||
fish-gettext-mo-file-parser.workspace = true
|
||||
phf_codegen = { workspace = true, optional = true }
|
||||
rsconf.workspace = true
|
||||
|
||||
[target.'cfg(windows)'.build-dependencies]
|
||||
unix_path.workspace = true
|
||||
|
||||
[lib]
|
||||
crate-type = ["rlib"]
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "fish"
|
||||
path = "src/bin/fish.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "fish_indent"
|
||||
path = "src/bin/fish_indent.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "fish_key_reader"
|
||||
path = "src/bin/fish_key_reader.rs"
|
||||
|
||||
[features]
|
||||
default = ["embed-data", "localize-messages"]
|
||||
benchmark = []
|
||||
embed-data = ["dep:rust-embed", "dep:fish-build-man-pages"]
|
||||
# Enable gettext localization at runtime. Requires the `msgfmt` tool to generate catalog data at
|
||||
# build time.
|
||||
localize-messages = ["dep:phf", "dep:fish-gettext-maps"]
|
||||
# This feature is used to enable extracting messages from the source code for localization.
|
||||
# It only needs to be enabled if updating these messages (and the corresponding PO files) is
|
||||
# desired. This happens when running tests via `build_tools/check.sh` and when calling
|
||||
# `build_tools/update_translations.fish`, so there should not be a need to enable it manually.
|
||||
gettext-extract = ["dep:fish-gettext-extraction"]
|
||||
|
||||
# The following features are auto-detected by the build-script and should not be enabled manually.
|
||||
asan = []
|
||||
tsan = []
|
||||
|
||||
[workspace.lints]
|
||||
rust.non_camel_case_types = "allow"
|
||||
rust.non_upper_case_globals = "allow"
|
||||
rust.unknown_lints = "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.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.
|
||||
# These lints flag their use.
|
||||
# In the future, they might change to flag other methods of printing.
|
||||
clippy.print_stdout = "deny"
|
||||
clippy.print_stderr = "deny"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -3,7 +3,7 @@ FROM centos:latest
|
||||
# Build dependency
|
||||
RUN yum update -y &&\
|
||||
yum install -y epel-release &&\
|
||||
yum install -y clang cmake3 gcc-c++ make &&\
|
||||
yum install -y clang cmake3 gcc-c++ make ncurses-devel &&\
|
||||
yum clean all
|
||||
|
||||
# Test dependency
|
||||
@@ -16,3 +16,4 @@ WORKDIR /src
|
||||
RUN cmake3 . &&\
|
||||
make &&\
|
||||
make install
|
||||
|
||||
|
||||
15
GNUmakefile
15
GNUmakefile
@@ -31,19 +31,16 @@ else
|
||||
|
||||
all: .begin build/fish
|
||||
|
||||
.PHONY: .begin
|
||||
PHONY: .begin
|
||||
.begin:
|
||||
@which $(CMAKE) > /dev/null 2> /dev/null || \
|
||||
(echo 'Please install CMake and then re-run the `make` command!' 1>&2 && false)
|
||||
|
||||
.PHONY: build/fish
|
||||
build/fish: build/$(BUILDFILE)
|
||||
$(CMAKE) --build build
|
||||
|
||||
# Use build as an order-only dependency. This prevents the target from always being outdated
|
||||
# after a make run, and more importantly, doesn't clobber manually specified CMake options.
|
||||
build/$(BUILDFILE): | build
|
||||
cd build; $(CMAKE) .. -G "$(GENERATOR)" \
|
||||
build/$(BUILDFILE): build
|
||||
cd build; $(CMAKE) .. -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -G "$(GENERATOR)" \
|
||||
-DCMAKE_INSTALL_PREFIX="$(PREFIX)" -DCMAKE_EXPORT_COMPILE_COMMANDS=1
|
||||
|
||||
build:
|
||||
@@ -55,11 +52,7 @@ clean:
|
||||
|
||||
.PHONY: test
|
||||
test: build/fish
|
||||
$(CMAKE) --build build --target fish_run_tests
|
||||
|
||||
.PHONY: fish_run_tests
|
||||
fish_run_tests: build/fish
|
||||
$(CMAKE) --build build --target fish_run_tests
|
||||
$(CMAKE) --build build --target test
|
||||
|
||||
.PHONY: install
|
||||
install: build/fish
|
||||
|
||||
187
README.rst
187
README.rst
@@ -1,16 +1,13 @@
|
||||
.. |Cirrus CI| image:: https://api.cirrus-ci.com/github/fish-shell/fish-shell.svg?branch=master
|
||||
:target: https://cirrus-ci.com/github/fish-shell/fish-shell
|
||||
:alt: Cirrus CI Build Status
|
||||
|
||||
`fish <https://fishshell.com/>`__ - the friendly interactive shell |Build Status| |Cirrus CI|
|
||||
=============================================================================================
|
||||
`fish <https://fishshell.com/>`__ - the friendly interactive shell |Build Status|
|
||||
=================================================================================
|
||||
|
||||
fish is a smart and user-friendly command line shell for macOS, Linux,
|
||||
and the rest of the family. fish includes features like syntax
|
||||
highlighting, autosuggest-as-you-type, and fancy tab completions that
|
||||
just work, with no configuration required.
|
||||
|
||||
For downloads, screenshots and more, go to https://fishshell.com/.
|
||||
For more on fish’s design philosophy, see the `design
|
||||
document <https://fishshell.com/docs/current/design.html>`__.
|
||||
|
||||
Quick Start
|
||||
-----------
|
||||
@@ -23,6 +20,11 @@ magic phrase “unlike other shells”.
|
||||
Detailed user documentation is available by running ``help`` within
|
||||
fish, and also at https://fishshell.com/docs/current/index.html
|
||||
|
||||
You can quickly play with fish right in your browser by clicking the
|
||||
button below:
|
||||
|
||||
|Try in browser|
|
||||
|
||||
Getting fish
|
||||
------------
|
||||
|
||||
@@ -37,8 +39,6 @@ fish can be installed:
|
||||
- using the `installer from fishshell.com <https://fishshell.com/>`__
|
||||
- as a `standalone app from fishshell.com <https://fishshell.com/>`__
|
||||
|
||||
Note: The minimum supported macOS version is 10.10 "Yosemite".
|
||||
|
||||
Packages for Linux
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -47,14 +47,14 @@ Linux/CentOS are available from the `openSUSE Build
|
||||
Service <https://software.opensuse.org/download.html?project=shells%3Afish&package=fish>`__.
|
||||
|
||||
Packages for Ubuntu are available from the `fish
|
||||
PPA <https://launchpad.net/~fish-shell/+archive/ubuntu/release-4>`__,
|
||||
PPA <https://launchpad.net/~fish-shell/+archive/ubuntu/release-3>`__,
|
||||
and can be installed using the following commands:
|
||||
|
||||
::
|
||||
|
||||
sudo apt-add-repository ppa:fish-shell/release-4
|
||||
sudo apt update
|
||||
sudo apt install fish
|
||||
sudo apt-add-repository ppa:fish-shell/release-3
|
||||
sudo apt-get update
|
||||
sudo apt-get install fish
|
||||
|
||||
Instructions for other distributions may be found at
|
||||
`fishshell.com <https://fishshell.com>`__.
|
||||
@@ -62,12 +62,12 @@ Instructions for other distributions may be found at
|
||||
Windows
|
||||
~~~~~~~
|
||||
|
||||
- On Windows 10/11, fish can be installed under the WSL Windows Subsystem
|
||||
- On Windows 10, fish can be installed under the WSL Windows Subsystem
|
||||
for Linux with the instructions for the appropriate distribution
|
||||
listed above under “Packages for Linux”, or from source with the
|
||||
instructions below.
|
||||
- Fish can also be installed on all versions of Windows using
|
||||
`Cygwin <https://cygwin.com/>`__ or `MSYS2 <https://github.com/Berrysoft/fish-msys2>`__.
|
||||
`Cygwin <https://cygwin.com/>`__ (from the **Shells** category).
|
||||
|
||||
Building from source
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -76,7 +76,7 @@ If packages are not available for your platform, GPG-signed tarballs are
|
||||
available from `fishshell.com <https://fishshell.com/>`__ and
|
||||
`fish-shell on
|
||||
GitHub <https://github.com/fish-shell/fish-shell/releases>`__. See the
|
||||
`Building <#building>`_ section for instructions.
|
||||
*Building* section for instructions.
|
||||
|
||||
Running fish
|
||||
------------
|
||||
@@ -88,116 +88,128 @@ Dependencies
|
||||
|
||||
Running fish requires:
|
||||
|
||||
- curses or ncurses (preinstalled on most \*nix systems)
|
||||
- some common \*nix system utilities (currently ``mktemp``), in
|
||||
addition to the basic POSIX utilities (``cat``, ``cut``, ``dirname``,
|
||||
``ls``, ``mkdir``, ``mkfifo``, ``rm``, ``sh``, ``sort``, ``tee``, ``tr``,
|
||||
``uname`` and ``sed`` at least, but the full coreutils plus ``find`` and
|
||||
``awk`` is preferred)
|
||||
``ls``, ``mkdir``, ``mkfifo``, ``rm``, ``sort``, ``tee``, ``tr``,
|
||||
``uname`` and ``sed`` at least, but the full coreutils plus find, sed
|
||||
and awk is preferred)
|
||||
- gettext (library and ``gettext`` command), if compiled with
|
||||
translation support
|
||||
|
||||
The following optional features also have specific requirements:
|
||||
|
||||
- builtin commands that have the ``--help`` option or print usage
|
||||
messages require ``man`` for display
|
||||
- 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 :ref:`alt-o <shared-binds-alt-o>` binding requires the ``file`` program.
|
||||
messages require ``ul`` and either ``nroff`` or ``mandoc`` for
|
||||
display
|
||||
- automated completion generation from manual pages requires Python
|
||||
(2.7+ or 3.3+) and possibly the ``backports.lzma`` module for Python
|
||||
2.7
|
||||
- the ``fish_config`` web configuration tool requires Python (2.7+ or
|
||||
3.3 +) and a web browser
|
||||
- system clipboard integration (with the default Ctrl-V and Ctrl-X
|
||||
bindings) require either the ``xsel``, ``xclip``,
|
||||
``wl-copy``/``wl-paste`` or ``pbcopy``/``pbpaste`` utilities
|
||||
- full completions for ``yarn`` and ``npm`` require the
|
||||
``all-the-package-names`` NPM module
|
||||
- ``colorls`` is used, if installed, to add color when running ``ls`` on platforms
|
||||
that do not have color support (such as OpenBSD)
|
||||
|
||||
Switching to fish
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you wish to use fish as your default shell, use the following
|
||||
command:
|
||||
|
||||
::
|
||||
|
||||
chsh -s /usr/local/bin/fish
|
||||
|
||||
``chsh`` will prompt you for your password and change your default
|
||||
shell. (Substitute ``/usr/local/bin/fish`` with whatever path fish was
|
||||
installed to, if it differs.) Log out, then log in again for the changes
|
||||
to take effect.
|
||||
|
||||
Use the following command if fish isn’t already added to ``/etc/shells``
|
||||
to permit fish to be your login shell:
|
||||
|
||||
::
|
||||
|
||||
echo /usr/local/bin/fish | sudo tee -a /etc/shells
|
||||
|
||||
To switch your default shell back, you can run ``chsh -s /bin/bash``
|
||||
(substituting ``/bin/bash`` with ``/bin/tcsh`` or ``/bin/zsh`` as
|
||||
appropriate).
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
.. _dependencies-1:
|
||||
|
||||
Dependencies
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Compiling fish requires:
|
||||
|
||||
- Rust (version 1.85 or later)
|
||||
- CMake (version 3.15 or later)
|
||||
- a C compiler (for system feature detection and the test helper binary)
|
||||
- PCRE2 (headers and libraries) - optional, this will be downloaded if missing
|
||||
- gettext (only the msgfmt tool) - optional, for translation support
|
||||
- an Internet connection, as other dependencies will be downloaded automatically
|
||||
- a C++11 compiler (g++ 4.8 or later, or clang 3.3 or later)
|
||||
- CMake (version 3.2 or later)
|
||||
- a curses implementation such as ncurses (headers and libraries)
|
||||
- PCRE2 (headers and libraries) - a copy is included with fish
|
||||
- gettext (headers and libraries) - optional, for translation support
|
||||
|
||||
Sphinx is also optionally required to build the documentation from a
|
||||
cloned git repository.
|
||||
|
||||
Additionally, running the full test suite requires diff, git, Python 3.5+, pexpect, less, tmux and wget.
|
||||
|
||||
Building from source with CMake
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Rather than building from source, consider using a packaged build for your platform. Using the
|
||||
steps below makes fish difficult to uninstall or upgrade. Release packages are available from the
|
||||
links above, and up-to-date `development builds of fish are available for many platforms
|
||||
<https://github.com/fish-shell/fish-shell/wiki/Development-builds>`__
|
||||
Building from source (all platforms) - Makefile generator
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To install into ``/usr/local``, run:
|
||||
|
||||
.. code:: shell
|
||||
.. code:: bash
|
||||
|
||||
mkdir build; cd build
|
||||
cmake ..
|
||||
cmake --build .
|
||||
sudo cmake --install .
|
||||
make
|
||||
sudo make install
|
||||
|
||||
The install directory can be changed using the
|
||||
``-DCMAKE_INSTALL_PREFIX`` parameter for ``cmake``.
|
||||
|
||||
CMake Build options
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
Building from source (macOS) - Xcode
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In addition to the normal CMake build options (like ``CMAKE_INSTALL_PREFIX``), fish's CMake build has some other options available to customize it.
|
||||
.. code:: bash
|
||||
|
||||
- Rust_COMPILER=path - the path to rustc. If not set, cmake will check $PATH and ~/.cargo/bin
|
||||
- Rust_CARGO=path - the path to cargo. If not set, cmake will check $PATH and ~/.cargo/bin
|
||||
- Rust_CARGO_TARGET=target - the target to pass to cargo. Set this for cross-compilation.
|
||||
- BUILD_DOCS=ON|OFF - whether to build the documentation. This is automatically set to OFF when Sphinx isn't installed.
|
||||
- INSTALL_DOCS=ON|OFF - whether to install the docs. This is automatically set to on when BUILD_DOCS is or prebuilt documentation is available (like when building in-tree from a tarball).
|
||||
- FISH_USE_SYSTEM_PCRE2=ON|OFF - whether to use an installed pcre2. This is normally autodetected.
|
||||
- MAC_CODESIGN_ID=String|OFF - the codesign ID to use on Mac, or "OFF" to disable codesigning.
|
||||
- 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
|
||||
mkdir build; cd build
|
||||
cmake .. -G Xcode
|
||||
|
||||
Building fish with Cargo
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
An Xcode project will now be available in the ``build`` subdirectory.
|
||||
You can open it with Xcode, or run the following to build and install in
|
||||
``/usr/local``:
|
||||
|
||||
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.
|
||||
.. code:: bash
|
||||
|
||||
.. code:: shell
|
||||
xcodebuild
|
||||
xcodebuild -scheme install
|
||||
|
||||
git clone https://github.com/fish-shell/fish-shell
|
||||
cd fish-shell
|
||||
The install directory can be changed using the
|
||||
``-DCMAKE_INSTALL_PREFIX`` parameter for ``cmake``.
|
||||
|
||||
# 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)"
|
||||
Help, it didn’t build!
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
uv run --no-managed-python \
|
||||
cargo install --path .
|
||||
If fish reports that it could not find curses, try installing a curses
|
||||
development package and build again.
|
||||
|
||||
This will place standalone binaries in ``~/.cargo/bin/``, but you can move them wherever you want.
|
||||
On Debian or Ubuntu you want:
|
||||
|
||||
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.
|
||||
sudo apt-get install build-essential cmake ncurses-dev libncurses5-dev libpcre2-dev gettext
|
||||
|
||||
Here are the remaining advantages of a full installation, as currently done by CMake:
|
||||
On RedHat, CentOS, or Amazon EC2:
|
||||
|
||||
- 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}``.
|
||||
::
|
||||
|
||||
sudo yum install ncurses-devel
|
||||
|
||||
Contributing Changes to the Code
|
||||
--------------------------------
|
||||
@@ -209,13 +221,18 @@ Contact Us
|
||||
|
||||
Questions, comments, rants and raves can be posted to the official fish
|
||||
mailing list at https://lists.sourceforge.net/lists/listinfo/fish-users
|
||||
or join us on our `matrix
|
||||
channel <https://matrix.to/#/#fish-shell:matrix.org>`__. Or use the `fish tag
|
||||
on Unix & Linux Stackexchange <https://unix.stackexchange.com/questions/tagged/fish>`__.
|
||||
There is also a fish tag on Stackoverflow, but it is typically a poor fit.
|
||||
or join us on our `gitter.im
|
||||
channel <https://gitter.im/fish-shell/fish-shell>`__. Or use the `fish
|
||||
tag on
|
||||
Stackoverflow <https://stackoverflow.com/questions/tagged/fish>`__ for
|
||||
questions related to fish script and the `fish tag on
|
||||
Superuser <https://superuser.com/questions/tagged/fish>`__ for all other
|
||||
questions (e.g., customizing colors, changing key bindings).
|
||||
|
||||
Found a bug? Have an awesome idea? Please `open an
|
||||
issue <https://github.com/fish-shell/fish-shell/issues/new>`__.
|
||||
|
||||
.. |Build Status| image:: https://github.com/fish-shell/fish-shell/workflows/make%20test/badge.svg
|
||||
:target: https://github.com/fish-shell/fish-shell/actions
|
||||
.. |Build Status| image:: https://travis-ci.org/fish-shell/fish-shell.svg?branch=master
|
||||
:target: https://travis-ci.org/fish-shell/fish-shell
|
||||
.. |Try in browser| image:: https://cdn.rawgit.com/rootnroll/library/assets/try.svg
|
||||
:target: https://rootnroll.com/d/fish-shell/
|
||||
|
||||
35
SECURITY.md
35
SECURITY.md
@@ -1,35 +0,0 @@
|
||||
# Security Reporting
|
||||
|
||||
If you wish to report a security vulnerability privately, we appreciate your diligence. Please follow the guidelines below to submit your report.
|
||||
|
||||
## Reporting
|
||||
|
||||
To report a security vulnerability, please provide the following information:
|
||||
|
||||
1. **PROJECT**
|
||||
|
||||
- Include the URL of the project repository - Example: <https://github.com/fish-shell/fish-shell>
|
||||
|
||||
2. **PUBLIC**
|
||||
|
||||
- Indicate whether this vulnerability has already been publicly discussed or disclosed.
|
||||
- If so, provide relevant links.
|
||||
|
||||
3. **DESCRIPTION**
|
||||
- Provide a detailed description of the security vulnerability.
|
||||
- Include as much information as possible to help us understand and address the issue.
|
||||
|
||||
Send this information, along with any additional relevant details, to <rf@fishshell.com>.
|
||||
|
||||
## Confidentiality
|
||||
|
||||
We kindly ask you to keep the report confidential until a public announcement is made.
|
||||
|
||||
## Notes
|
||||
|
||||
- Vulnerabilities will be handled on a best-effort basis.
|
||||
- You may request an advance copy of the patched release, but we cannot guarantee early access before the public release.
|
||||
- You will be notified via email simultaneously with the public announcement.
|
||||
- We will respond within a few weeks to confirm whether your report has been accepted or rejected.
|
||||
|
||||
Thank you for helping to improve the security of our project!
|
||||
@@ -1089,3 +1089,4 @@ alias alias1020='something --arg1020'
|
||||
alias alias1021='something --arg1021'
|
||||
alias alias1022='something --arg1022'
|
||||
alias alias1023='something --arg1023'
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
for i in (seq 1000)
|
||||
for i in (seq 2000)
|
||||
command true
|
||||
end
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# Glob fish's source directory.
|
||||
# This timing is bound to change if the repo does,
|
||||
# so it's best to build two fishes, check out one version of the repo,
|
||||
# and then run this script with both.
|
||||
set -l dir (dirname (status current-filename))
|
||||
# No repetitions, this is plenty slow enough.
|
||||
echo $dir/../../**
|
||||
@@ -1,11 +0,0 @@
|
||||
set -l compdir (status dirname)/../../share/completions
|
||||
cd $compdir
|
||||
for file in *.fish
|
||||
set -l bname (string replace -r '.fish$' '' -- $file)
|
||||
if type -q $bname
|
||||
source $file >/dev/null
|
||||
if test $status -gt 0
|
||||
echo FAILING FILE $file
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,3 +0,0 @@
|
||||
for i in (seq 100000)
|
||||
math $i + $i
|
||||
end
|
||||
@@ -1,6 +0,0 @@
|
||||
set -l path (status dirname)
|
||||
set -l fish (status fish-path)
|
||||
for f in (seq 100)
|
||||
echo $fish -n $path/aliases.fish
|
||||
$fish -n $path/aliases.fish
|
||||
end
|
||||
@@ -1 +0,0 @@
|
||||
printf (string repeat -n 200 \\x7f)%s\n (string repeat -n 2000 aaa\n)
|
||||
@@ -1,5 +0,0 @@
|
||||
for i in (seq 100000)
|
||||
printf '%f\n' $i.$i
|
||||
end
|
||||
|
||||
exit 0
|
||||
@@ -1,7 +0,0 @@
|
||||
set -l tmp (mktemp)
|
||||
string repeat -n 2000 >$tmp
|
||||
for i in (seq 1000)
|
||||
cat $tmp | read -l foo
|
||||
end
|
||||
|
||||
true
|
||||
@@ -1,3 +1,3 @@
|
||||
for i in (seq 10000)
|
||||
for i in (seq 1000)
|
||||
echo $i
|
||||
end
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
for abc in (seq 100000)
|
||||
set -l def
|
||||
end
|
||||
@@ -1,3 +0,0 @@
|
||||
for i in (string repeat -n 100 \n)
|
||||
string repeat -n 50000 a\n
|
||||
end
|
||||
@@ -1,3 +0,0 @@
|
||||
for i in (seq 100000)
|
||||
string match '*o' fooooooo
|
||||
end
|
||||
@@ -1,3 +0,0 @@
|
||||
for i in (seq 100000)
|
||||
string match -r '^.*$' fooooooo
|
||||
end | string match -re o
|
||||
@@ -1,43 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$#" -gt 2 ] || [ "$#" -eq 0 ]; then
|
||||
echo "Usage: driver.sh /path/to/fish [/path/to/other/fish]"
|
||||
exit 1
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: driver.sh /path/to/fish"
|
||||
fi
|
||||
|
||||
FISH_PATH=$1
|
||||
FISH2_PATH=$2
|
||||
BENCHMARKS_DIR=$(dirname "$0")/benchmarks
|
||||
|
||||
quote() {
|
||||
# Single-quote the given string for a POSIX shell, except in common cases that don't need it.
|
||||
printf %s "$1" |
|
||||
sed "/[^[:alnum:]\/.-]/ {
|
||||
s/'/'\\\''/g
|
||||
s/^/'/
|
||||
s/\$/'/
|
||||
}"
|
||||
}
|
||||
|
||||
for benchmark in "$BENCHMARKS_DIR"/*; do
|
||||
basename "$benchmark"
|
||||
# If we have hyperfine, use it first to warm up the cache
|
||||
${FISH_PATH} --print-rusage-self "$benchmark" > /dev/null
|
||||
if command -v hyperfine >/dev/null 2>&1; then
|
||||
cmd1="$(quote "${FISH_PATH}") --no-config $(quote "$benchmark")"
|
||||
if [ -n "$FISH2_PATH" ]; then
|
||||
cmd2="$(quote "${FISH2_PATH}") --no-config $(quote "$benchmark")"
|
||||
hyperfine --warmup 3 "$cmd1" "$cmd2"
|
||||
else
|
||||
hyperfine --warmup 3 "$cmd1"
|
||||
fi
|
||||
hyperfine "${FISH_PATH} $benchmark > /dev/null"
|
||||
fi
|
||||
|
||||
[ -n "$FISH2_PATH" ] && echo "$FISH_PATH"
|
||||
"${FISH_PATH}" --print-rusage-self "$benchmark" > /dev/null
|
||||
if [ -n "$FISH2_PATH" ]; then
|
||||
echo "$FISH2_PATH"
|
||||
"${FISH2_PATH}" --print-rusage-self "$benchmark" > /dev/null
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
|
||||
323
build.rs
323
build.rs
@@ -1,323 +0,0 @@
|
||||
use fish_build_helper::{env_var, fish_build_dir, workspace_root};
|
||||
use rsconf::Target;
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
fn canonicalize<P: AsRef<Path>>(path: P) -> PathBuf {
|
||||
std::fs::canonicalize(path).unwrap()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
setup_paths();
|
||||
|
||||
// Add our default to enable tools that don't go through CMake, like "cargo test" and the
|
||||
// language server.
|
||||
|
||||
rsconf::set_env_value(
|
||||
"FISH_RESOLVED_BUILD_DIR",
|
||||
// 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.
|
||||
canonicalize(fish_build_dir()).to_str().unwrap(),
|
||||
);
|
||||
|
||||
// We need to canonicalize (i.e. realpath) the manifest dir because we want to be able to
|
||||
// compare it directly as a string at runtime.
|
||||
rsconf::set_env_value(
|
||||
"CARGO_MANIFEST_DIR",
|
||||
canonicalize(workspace_root()).to_str().unwrap(),
|
||||
);
|
||||
|
||||
// Some build info
|
||||
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_PROFILE", &env_var("PROFILE").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,
|
||||
// the source directory is the current working directory of the build script
|
||||
rsconf::set_env_value("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,
|
||||
// but only in release builds (because rust-embed in debug builds reads from the filesystem).
|
||||
#[cfg(feature = "embed-data")]
|
||||
#[cfg(any(windows, not(debug_assertions)))]
|
||||
rsconf::rebuild_if_path_changed("share");
|
||||
|
||||
#[cfg(feature = "gettext-extract")]
|
||||
rsconf::rebuild_if_env_changed("FISH_GETTEXT_EXTRACTION_FILE");
|
||||
|
||||
let build = cc::Build::new();
|
||||
let mut target = Target::new_from(build).unwrap();
|
||||
// Keep verbose mode on until we've ironed out rust build script stuff
|
||||
target.set_verbose(true);
|
||||
detect_cfgs(&mut target);
|
||||
|
||||
#[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."
|
||||
);
|
||||
}
|
||||
|
||||
/// Check target system support for certain functionality dynamically when the build is invoked,
|
||||
/// without their having to be explicitly enabled in the `cargo build --features xxx` invocation.
|
||||
///
|
||||
/// We are using [`rsconf::enable_cfg()`] instead of [`rsconf::enable_feature()`] as rust features
|
||||
/// should be used for things that a user can/would reasonably enable or disable to tweak or coerce
|
||||
/// behavior, but here we are testing for whether or not things are supported altogether.
|
||||
///
|
||||
/// This can be used to enable features that we check for and conditionally compile according to in
|
||||
/// our own codebase, but [can't be used to pull in dependencies](0) even if they're gated (in
|
||||
/// `Cargo.toml`) behind a feature we just enabled.
|
||||
///
|
||||
/// [0]: https://github.com/rust-lang/cargo/issues/5499
|
||||
#[rustfmt::skip]
|
||||
fn detect_cfgs(target: &mut Target) {
|
||||
for (name, handler) in [
|
||||
// Ignore the first entry, it just sets up the type inference. Model new entries after the
|
||||
// second line.
|
||||
("", &(|_: &Target| false) as &dyn Fn(&Target) -> bool),
|
||||
("apple", &detect_apple),
|
||||
("bsd", &detect_bsd),
|
||||
("using_cmake", &|_| option_env!("FISH_CMAKE_BINARY_DIR").is_some()),
|
||||
("use_prebuilt_docs", &|_| env_var("FISH_USE_PREBUILT_DOCS").is_some_and(|v| v == "TRUE") ),
|
||||
("cygwin", &detect_cygwin),
|
||||
("small_main_stack", &has_small_stack),
|
||||
// See if libc supports the thread-safe localeconv_l(3) alternative to localeconv(3).
|
||||
("localeconv_l", &|target| {
|
||||
target.has_symbol("localeconv_l")
|
||||
}),
|
||||
("FISH_USE_POSIX_SPAWN", &|target| {
|
||||
target.has_header("spawn.h")
|
||||
}),
|
||||
("HAVE_PIPE2", &|target| {
|
||||
target.has_symbol("pipe2")
|
||||
}),
|
||||
("HAVE_EVENTFD", &|target| {
|
||||
// FIXME: NetBSD 10 has eventfd, but the libc crate does not expose it.
|
||||
if cfg!(target_os = "netbsd") {
|
||||
false
|
||||
} else {
|
||||
target.has_header("sys/eventfd.h")
|
||||
}
|
||||
}),
|
||||
("HAVE_WAITSTATUS_SIGNAL_RET", &|target| {
|
||||
target.r#if("WEXITSTATUS(0x007f) == 0x7f", &["sys/wait.h"])
|
||||
}),
|
||||
] {
|
||||
rsconf::declare_cfg(name, handler(target))
|
||||
}
|
||||
}
|
||||
|
||||
fn detect_apple(_: &Target) -> bool {
|
||||
cfg!(any(target_os = "ios", target_os = "macos"))
|
||||
}
|
||||
|
||||
fn detect_cygwin(_: &Target) -> bool {
|
||||
// Cygwin target is usually cross-compiled.
|
||||
env_var("CARGO_CFG_TARGET_OS").unwrap() == "cygwin"
|
||||
}
|
||||
|
||||
/// Detect if we're being compiled for a BSD-derived OS, allowing targeting code conditionally with
|
||||
/// `#[cfg(bsd)]`.
|
||||
///
|
||||
/// Rust offers fine-grained conditional compilation per-os for the popular operating systems, but
|
||||
/// doesn't necessarily include less-popular forks nor does it group them into families more
|
||||
/// specific than "windows" vs "unix" so we can conditionally compile code for BSD systems.
|
||||
fn detect_bsd(_: &Target) -> bool {
|
||||
// Instead of using `uname`, we can inspect the TARGET env variable set by Cargo. This lets us
|
||||
// support cross-compilation scenarios.
|
||||
let mut target = env_var("TARGET").unwrap();
|
||||
if !target.chars().all(|c| c.is_ascii_lowercase()) {
|
||||
target = target.to_ascii_lowercase();
|
||||
}
|
||||
let is_bsd = target.ends_with("bsd") || target.ends_with("dragonfly");
|
||||
#[cfg(any(
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
))]
|
||||
assert!(is_bsd, "Target incorrectly detected as not BSD!");
|
||||
is_bsd
|
||||
}
|
||||
|
||||
/// Rust sets the stack size of newly created threads to a sane value, but is at at the mercy of the
|
||||
/// OS when it comes to the size of the main stack. Some platforms we support default to a tiny
|
||||
/// 0.5 MiB main stack, which is insufficient for fish's MAX_EVAL_DEPTH/MAX_STACK_DEPTH values.
|
||||
///
|
||||
/// 0.5 MiB is small enough that we'd have to drastically reduce MAX_STACK_DEPTH to less than 10, so
|
||||
/// we instead use a workaround to increase the main thread size.
|
||||
fn has_small_stack(_: &Target) -> bool {
|
||||
#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "netbsd")))]
|
||||
return false;
|
||||
|
||||
// NetBSD 10 also needs this but can't find pthread_get_stacksize_np.
|
||||
#[cfg(target_os = "netbsd")]
|
||||
return true;
|
||||
|
||||
#[cfg(any(target_os = "ios", target_os = "macos"))]
|
||||
{
|
||||
use core::ffi;
|
||||
|
||||
unsafe extern "C" {
|
||||
unsafe fn pthread_get_stacksize_np(thread: *const ffi::c_void) -> usize;
|
||||
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.
|
||||
// Modern macOS versions default to an 8 MiB main stack but legacy OS X have a 0.5 MiB one.
|
||||
let stack_size = unsafe { pthread_get_stacksize_np(pthread_self()) };
|
||||
const TWO_MIB: usize = 2 * 1024 * 1024 - 1;
|
||||
stack_size <= TWO_MIB
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_paths() {
|
||||
#[cfg(windows)]
|
||||
use unix_path::{Path, PathBuf};
|
||||
|
||||
fn overridable_path(
|
||||
env_var_name: &str,
|
||||
f: impl FnOnce(Option<String>) -> Option<PathBuf>,
|
||||
) -> 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());
|
||||
}
|
||||
maybe_path
|
||||
}
|
||||
|
||||
fn join_if_relative(parent_if_relative: &Path, path: String) -> PathBuf {
|
||||
let path = PathBuf::from(path);
|
||||
if path.is_relative() {
|
||||
parent_if_relative.join(path)
|
||||
} else {
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
let prefix = overridable_path("PREFIX", |env_prefix| {
|
||||
Some(PathBuf::from(
|
||||
env_prefix.unwrap_or("/usr/local".to_string()),
|
||||
))
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
overridable_path("SYSCONFDIR", |env_sysconfdir| {
|
||||
Some(join_if_relative(
|
||||
&prefix,
|
||||
env_sysconfdir.unwrap_or(
|
||||
// Embedded builds use "/etc," not "$PREFIX/etc".
|
||||
if cfg!(feature = "embed-data") {
|
||||
"/etc/"
|
||||
} else {
|
||||
"etc/"
|
||||
}
|
||||
.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 {
|
||||
use std::fs::read_to_string;
|
||||
use std::process::Command;
|
||||
|
||||
if let Some(var) = env_var("FISH_BUILD_VERSION") {
|
||||
return var;
|
||||
}
|
||||
|
||||
let path = src_dir.join("version");
|
||||
if let Ok(strver) = read_to_string(path) {
|
||||
return strver;
|
||||
}
|
||||
|
||||
let args = &["describe", "--always", "--dirty=-dirty"];
|
||||
if let Ok(output) = Command::new("git").args(args).output() {
|
||||
let rev = String::from_utf8_lossy(&output.stdout).trim().to_string();
|
||||
if !rev.is_empty() {
|
||||
// If it contains a ".", we have a proper version like "3.7",
|
||||
// or "23.2.1-1234-gfab1234"
|
||||
if rev.contains('.') {
|
||||
return rev;
|
||||
}
|
||||
// If it doesn't, we probably got *just* the commit SHA,
|
||||
// like "f1242abcdef".
|
||||
// So we prepend the crate version so it at least looks like
|
||||
// "3.8-gf1242abcdef"
|
||||
// This lacks the commit *distance*, but that can't be helped without
|
||||
// tags.
|
||||
let version = env!("CARGO_PKG_VERSION").to_owned();
|
||||
return version + "-g" + &rev;
|
||||
}
|
||||
}
|
||||
|
||||
// git did not tell us a SHA either because it isn't installed,
|
||||
// or because it refused (safe.directory applies to `git describe`!)
|
||||
// So we read the SHA ourselves.
|
||||
fn get_git_hash() -> Result<String, Box<dyn std::error::Error>> {
|
||||
let workspace_root = workspace_root();
|
||||
let gitdir = workspace_root.join(".git");
|
||||
let jjdir = workspace_root.join(".jj");
|
||||
let commit_id = if gitdir.exists() {
|
||||
// .git/HEAD contains ref: refs/heads/branch
|
||||
let headpath = gitdir.join("HEAD");
|
||||
let headstr = read_to_string(headpath)?;
|
||||
let headref = headstr.split(' ').nth(1).unwrap().trim();
|
||||
|
||||
// .git/refs/heads/branch contains the SHA
|
||||
let refpath = gitdir.join(headref);
|
||||
// Shorten to 9 characters (what git describe does currently)
|
||||
read_to_string(refpath)?
|
||||
} else if jjdir.exists() {
|
||||
let output = Command::new("jj")
|
||||
.args([
|
||||
"log",
|
||||
"--revisions",
|
||||
"@",
|
||||
"--no-graph",
|
||||
"--ignore-working-copy",
|
||||
"--template",
|
||||
"commit_id",
|
||||
])
|
||||
.output()
|
||||
.unwrap();
|
||||
String::from_utf8_lossy(&output.stdout).to_string()
|
||||
} else {
|
||||
return Err("did not find either of .git or .jj".into());
|
||||
};
|
||||
let refstr = &commit_id[0..9];
|
||||
let refstr = refstr.trim();
|
||||
|
||||
let version = env!("CARGO_PKG_VERSION").to_owned();
|
||||
Ok(version + "-g" + refstr)
|
||||
}
|
||||
|
||||
get_git_hash().expect("Could not get a version. Either set $FISH_BUILD_VERSION or install git.")
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
{
|
||||
set -ex
|
||||
|
||||
lint=true
|
||||
if [ "$FISH_CHECK_LINT" = false ]; then
|
||||
lint=false
|
||||
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
|
||||
target_triple=$FISH_CHECK_TARGET_TRIPLE
|
||||
if [ -n "$target_triple" ]; then
|
||||
cargo_args="$cargo_args --target=$FISH_CHECK_TARGET_TRIPLE"
|
||||
fi
|
||||
|
||||
cargo() {
|
||||
subcmd=$1
|
||||
shift
|
||||
# shellcheck disable=2086
|
||||
command cargo "$subcmd" $cargo_args "$@"
|
||||
}
|
||||
|
||||
cleanup () {
|
||||
if [ -n "$template_file" ] && [ -e "$template_file" ]; then
|
||||
rm "$template_file"
|
||||
fi
|
||||
}
|
||||
|
||||
trap cleanup EXIT INT TERM HUP
|
||||
|
||||
if $lint; then
|
||||
export RUSTFLAGS="--deny=warnings ${RUSTFLAGS}"
|
||||
export RUSTDOCFLAGS="--deny=warnings ${RUSTDOCFLAGS}"
|
||||
fi
|
||||
|
||||
workspace_root="$(dirname "$0")/.."
|
||||
target_dir=${CARGO_TARGET_DIR:-$workspace_root/target}
|
||||
if [ -n "$target_triple" ]; then
|
||||
target_dir="$target_dir/$target_triple"
|
||||
fi
|
||||
# The directory containing the binaries produced by cargo/rustc.
|
||||
# Currently, all builds are debug builds.
|
||||
build_dir="$target_dir/debug"
|
||||
|
||||
if [ -n "$FISH_TEST_MAX_CONCURRENCY" ]; then
|
||||
export RUST_TEST_THREADS="$FISH_TEST_MAX_CONCURRENCY"
|
||||
export CARGO_BUILD_JOBS="$FISH_TEST_MAX_CONCURRENCY"
|
||||
fi
|
||||
|
||||
template_file=$(mktemp)
|
||||
(
|
||||
export FISH_GETTEXT_EXTRACTION_FILE="$template_file"
|
||||
cargo build --workspace --all-targets --features=gettext-extract
|
||||
)
|
||||
if $lint; then
|
||||
PATH="$build_dir:$PATH" "$workspace_root/build_tools/style.fish" --all --check
|
||||
for features in "" --no-default-features; do
|
||||
cargo clippy --workspace --all-targets $features
|
||||
done
|
||||
fi
|
||||
cargo test --no-default-features --workspace --all-targets
|
||||
cargo test --doc --workspace
|
||||
if $lint; then
|
||||
cargo doc --workspace
|
||||
fi
|
||||
FISH_GETTEXT_EXTRACTION_FILE=$template_file "$workspace_root/tests/test_driver.py" "$build_dir"
|
||||
|
||||
exit
|
||||
}
|
||||
3
build_tools/cppcheck.sh
Executable file
3
build_tools/cppcheck.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/usr/local/bin/fish
|
||||
|
||||
cppcheck --enable=all --std=posix --quiet ./src/
|
||||
15
build_tools/diff_profiles.fish
Executable file → Normal file
15
build_tools/diff_profiles.fish
Executable file → Normal file
@@ -5,13 +5,6 @@
|
||||
#
|
||||
# Usage: ./diff_profiles.fish profile1.log profile2.log > profile_diff.log
|
||||
|
||||
if test (count $argv) -ne 2
|
||||
|
||||
echo "Incorrect number of arguments."
|
||||
echo "Usage: "(status filename)" profile1.log profile2.log"
|
||||
exit 1
|
||||
end
|
||||
|
||||
set -l profile1 (cat $argv[1])
|
||||
set -l profile2 (cat $argv[2])
|
||||
|
||||
@@ -22,13 +15,13 @@ while set -l next_line_no (math $line_no + 1) && set -q profile1[$next_line_no]
|
||||
set -l line1 $profile1[$line_no]
|
||||
set -l line2 $profile2[$line_no]
|
||||
|
||||
if not string match -qr '^\s*\d+\s+\d+' $line1
|
||||
if not string match -qr '^\d+\t\d+' $line1
|
||||
echo $line1
|
||||
continue
|
||||
end
|
||||
|
||||
set -l results1 (string match -r '^\s*(\d+)\s+(\d+)\s+(.*)' $line1)
|
||||
set -l results2 (string match -r '^\s*(\d+)\s+(\d+)\s+(.*)' $line2)
|
||||
set -l results1 (string match -r '^(\d+)\t(\d+)\s+(.*)' $line1)
|
||||
set -l results2 (string match -r '^(\d+)\t(\d+)\s+(.*)' $line2)
|
||||
|
||||
# times from both files
|
||||
set -l time1 $results1[2..3]
|
||||
@@ -49,5 +42,5 @@ while set -l next_line_no (math $line_no + 1) && set -q profile1[$next_line_no]
|
||||
set diff[1] (math $time1[1] - $time2[1])
|
||||
set diff[2] (math $time1[2] - $time2[2])
|
||||
|
||||
printf '%10d %10d %s\n' $diff[1] $diff[2] $remainder1
|
||||
echo $diff[1] $diff[2] $remainder1
|
||||
end
|
||||
|
||||
112
build_tools/find_globals.fish
Executable file
112
build_tools/find_globals.fish
Executable file
@@ -0,0 +1,112 @@
|
||||
#!/usr/bin/env fish
|
||||
|
||||
# Finds global variables by parsing the output of 'nm'
|
||||
# for object files in this directory.
|
||||
# This was written for macOS nm.
|
||||
|
||||
set -l FISH_SOURCE_DIR $argv[1]
|
||||
if not test -d "$FISH_SOURCE_DIR"
|
||||
echo "FISH_SOURCE_DIR not given"
|
||||
exit 1
|
||||
end
|
||||
|
||||
set -g whitelist \
|
||||
# unclear what this is \
|
||||
l_constinit \
|
||||
# hacks to work around missing ncurses strings on mac \
|
||||
sitm_esc ritm_esc dim_esc \
|
||||
|
||||
|
||||
# In our nm regex, we are interested in data (dD) and bss (bB) segments.
|
||||
set -g nm_regex '^([^ ]+) ([dDbB])'
|
||||
|
||||
set -l total_globals 0
|
||||
set -l boring_files \
|
||||
fish_key_reader.cpp.o \
|
||||
fish_tests.cpp.o \
|
||||
fish_indent.cpp.o \
|
||||
|
||||
|
||||
# return if we should ignore the given symbol name
|
||||
function should_ignore
|
||||
set -l symname $argv[1]
|
||||
string match -q '*guard variable for*' $symname
|
||||
and return 0
|
||||
contains $symname $whitelist
|
||||
and return 0
|
||||
return 1
|
||||
end
|
||||
|
||||
# echo a cleaned-up symbol name, e.g. replacing template gunk
|
||||
function cleanup_syname
|
||||
set -l symname $argv[1]
|
||||
set symname (string replace --all 'std::__1::basic_string<wchar_t, std::__1::char_traits<wchar_t>, std::__1::allocator<wchar_t> >' 'wcstring' $symname)
|
||||
set symname (string replace --all 'std::__1::vector<wcstring, std::__1::allocator<wcstring > >' 'wcstring_list_t' $symname)
|
||||
echo $symname
|
||||
end
|
||||
|
||||
# Output the declaration for a symbol name in a given file.
|
||||
function print_decl -a FISH_SOURCE_DIR objfile symname
|
||||
set -l varname (string split '::' $symname)[-1]
|
||||
set -l srcfile (basename $objfile .o)
|
||||
set -l srcpath $FISH_SOURCE_DIR/src/$srcfile
|
||||
|
||||
# A leading underscore indicates a global, strip it.
|
||||
set varname (string replace --regex '^_' '' $varname)
|
||||
|
||||
if not test -f "$srcpath"
|
||||
echo "Could not find $srcpath"
|
||||
end
|
||||
# Guess the variable as the first usage of the name.
|
||||
# Strip everything after the first =.
|
||||
set -l vardecl (egrep -m 1 " $varname\\b" $srcpath | cut -f -1 -d '=' | string trim)
|
||||
if test -z "$vardecl"
|
||||
echo "COULD_NOT_FIND_$varname"
|
||||
return 1
|
||||
end
|
||||
echo $vardecl
|
||||
return 0
|
||||
end
|
||||
|
||||
# Return if a variable declaration is "thread safe".
|
||||
function decl_is_threadsafe
|
||||
set -l vardecl $argv[1]
|
||||
# decls starting with 'const ' or containing ' const ' are assumed safe.
|
||||
string match -q --regex '(^|\\*| )const ' $vardecl
|
||||
and return 0
|
||||
|
||||
# Ordinary types indicating a safe variable.
|
||||
set -l safes relaxed_atomic_bool_t std::mutex std::condition_variable std::once_flag sig_atomic_t
|
||||
for safe in $safes
|
||||
string match -q "*$safe*" $vardecl
|
||||
and return 0
|
||||
end
|
||||
|
||||
# Template types indicate a safe variable.
|
||||
set safes owning_lock mainthread_t std::atomic relaxed_atomic_t latch_t
|
||||
for safe in $safes
|
||||
string match -q "*$safe<*" $vardecl
|
||||
and return 0
|
||||
end
|
||||
end
|
||||
|
||||
for file in ./**.o
|
||||
set -l filename (basename $file)
|
||||
# Skip boring files.
|
||||
contains $filename $boring_files
|
||||
and continue
|
||||
for line in (nm -p -P -U $file | egrep $nm_regex)
|
||||
set -l matches (string match --regex $nm_regex -- $line)
|
||||
or continue
|
||||
set -l symname (cleanup_syname (echo $matches[2] | c++filt))
|
||||
should_ignore $symname
|
||||
and continue
|
||||
set -l vardecl (print_decl $FISH_SOURCE_DIR $filename $symname)
|
||||
decl_is_threadsafe $vardecl
|
||||
and continue
|
||||
echo $filename $symname $matches[3] ":" $vardecl
|
||||
set total_globals (math $total_globals + 1)
|
||||
end
|
||||
end
|
||||
|
||||
echo "Total: $total_globals"
|
||||
@@ -1,147 +1,55 @@
|
||||
#!/usr/bin/env fish
|
||||
#
|
||||
# Tool to generate gettext messages template file.
|
||||
# Writes to stdout.
|
||||
# Intended to be called from `update_translations.fish`.
|
||||
# Tool to generate messages.pot
|
||||
# Extended to replace the old Makefile rule which did not port easily to CMak
|
||||
|
||||
argparse use-existing-template= -- $argv
|
||||
or exit $status
|
||||
# This script was originally motivated to work around a quirk (or bug depending on your viewpoint)
|
||||
# of the xgettext command. See https://lists.gnu.org/archive/html/bug-gettext/2014-11/msg00006.html.
|
||||
# However, it turns out that even if that quirk did not exist we would still need something like
|
||||
# this script to properly extract descriptions. That's because we need to normalize the strings to
|
||||
# a format that xgettext will handle correctly. Also, `xgettext -LShell` doesn't correctly extract
|
||||
# all the strings we want translated. So we extract and normalize all such strings into a format
|
||||
# that `xgettext` can handle.
|
||||
|
||||
begin
|
||||
# Write header. This is required by msguniq.
|
||||
# Note that this results in the file being overwritten.
|
||||
# This is desired behavior, to get rid of the results of prior invocations
|
||||
# of this script.
|
||||
begin
|
||||
echo 'msgid ""'
|
||||
echo 'msgstr ""'
|
||||
echo '"Content-Type: text/plain; charset=UTF-8\n"'
|
||||
echo ""
|
||||
end
|
||||
# Start with the C++ source
|
||||
xgettext -k -k_ -kN_ -LC++ --no-wrap -o messages.pot src/*.cpp src/*.h
|
||||
|
||||
set -g workspace_root (path resolve (status dirname)/..)
|
||||
# This regex handles descriptions for `complete` and `function` statements. These messages are not
|
||||
# particularly important to translate. Hence the "implicit" label.
|
||||
set -l implicit_regex '(?:^| +)(?:complete|function).*? (?:-d|--description) (([\'"]).+?(?<!\\\\)\\2).*'
|
||||
|
||||
set -l rust_extraction_file
|
||||
if set -l --query _flag_use_existing_template
|
||||
set rust_extraction_file $_flag_use_existing_template
|
||||
else
|
||||
set rust_extraction_file (mktemp)
|
||||
# We need to build to ensure that the proc macro for extracting strings runs.
|
||||
FISH_GETTEXT_EXTRACTION_FILE=$rust_extraction_file cargo check --no-default-features --features=gettext-extract
|
||||
or exit 1
|
||||
end
|
||||
# This regex handles explicit requests to translate a message. These are more important to translate
|
||||
# than messages which should be implicitly translated.
|
||||
set -l explicit_regex '.*\( *_ (([\'"]).+?(?<!\\\\)\\2) *\).*'
|
||||
|
||||
function mark_section
|
||||
set -l section_name $argv[1]
|
||||
echo 'msgid "fish-section-'$section_name'"'
|
||||
echo 'msgstr ""'
|
||||
echo ''
|
||||
end
|
||||
rm -r /tmp/fish
|
||||
|
||||
mark_section tier1-from-rust
|
||||
mkdir -p /tmp/fish/implicit/share/completions /tmp/fish/implicit/share/functions
|
||||
mkdir -p /tmp/fish/explicit/share/completions /tmp/fish/explicit/share/functions
|
||||
|
||||
# Get rid of duplicates and sort.
|
||||
msguniq --no-wrap --sort-output $rust_extraction_file
|
||||
or exit 1
|
||||
for f in share/config.fish share/completions/*.fish share/functions/*.fish
|
||||
# Extract explicit attempts to translate a message. That is, those that are of the form
|
||||
# `(_ "message")`.
|
||||
string replace --filter --regex $explicit_regex 'echo $1' <$f | fish >/tmp/fish/explicit/$f.tmp ^/dev/null
|
||||
while read description
|
||||
echo 'N_ "'(string replace --all '"' '\\"' -- $description)'"'
|
||||
end </tmp/fish/explicit/$f.tmp >/tmp/fish/explicit/$f
|
||||
rm /tmp/fish/explicit/$f.tmp
|
||||
|
||||
if not set -l --query _flag_use_existing_template
|
||||
rm $rust_extraction_file
|
||||
end
|
||||
# Handle `complete` / `function` description messages. The `| fish` is subtle. It basically
|
||||
# avoids the need to use `source` with a command substitution that could affect the current
|
||||
# shell.
|
||||
string replace --filter --regex $implicit_regex 'echo $1' <$f | fish >/tmp/fish/implicit/$f.tmp ^/dev/null
|
||||
while read description
|
||||
# We don't use `string escape` as shown in the next comment because it produces output that
|
||||
# is not parsed correctly by xgettext. Instead just escape double-quotes and quote the
|
||||
# resulting string.
|
||||
echo 'N_ "'(string replace --all '"' '\\"' -- $description)'"'
|
||||
end </tmp/fish/implicit/$f.tmp >/tmp/fish/implicit/$f
|
||||
rm /tmp/fish/implicit/$f.tmp
|
||||
end
|
||||
|
||||
function extract_fish_script_messages_impl
|
||||
set -l regex $argv[1]
|
||||
set -e argv[1]
|
||||
# Using xgettext causes more trouble than it helps.
|
||||
# This is due to handling of escaping in fish differing from formats xgettext understands
|
||||
# (e.g. POSIX shell strings).
|
||||
# We work around this issue by manually writing the file content.
|
||||
xgettext -j -k -kN_ -LShell --from-code=UTF-8 -cDescription --no-wrap -o messages.pot /tmp/fish/explicit/share/*/*.fish
|
||||
xgettext -j -k -kN_ -LShell --from-code=UTF-8 -cDescription --no-wrap -o messages.pot /tmp/fish/implicit/share/*/*.fish
|
||||
|
||||
# Steps:
|
||||
# 1. We extract strings to be translated from the relevant files and drop the rest. This step
|
||||
# depends on the regex matching the entire line, and the first capture group matching the
|
||||
# string.
|
||||
# 2. We unescape. This gets rid of some escaping necessary in fish strings.
|
||||
# 3. The resulting strings are sorted alphabetically. This step is optional. Not sorting would
|
||||
# result in strings from the same file appearing together. Removing duplicates is also
|
||||
# optional, since msguniq takes care of that later on as well.
|
||||
# 4. Single backslashes are replaced by double backslashes. This results in the backslashes
|
||||
# being interpreted as literal backslashes by gettext tooling.
|
||||
# 5. Double quotes are escaped, such that they are not interpreted as the start or end of
|
||||
# a msgid.
|
||||
# 6. We transform the string into the format expected in a PO file.
|
||||
cat $argv |
|
||||
string replace --filter --regex $regex '$1' |
|
||||
string unescape |
|
||||
sort -u |
|
||||
sed -E -e 's_\\\\_\\\\\\\\_g' -e 's_"_\\\\"_g' -e 's_^(.*)$_msgid "\1"\nmsgstr ""\n_'
|
||||
end
|
||||
|
||||
function extract_fish_script_messages
|
||||
set -l tier $argv[1]
|
||||
set -e argv[1]
|
||||
if not set -q argv[1]
|
||||
return
|
||||
end
|
||||
# This regex handles explicit requests to translate a message. These are more important to translate
|
||||
# than messages which should be implicitly translated.
|
||||
set -l explicit_regex '.*\( *_ (([\'"]).+?(?<!\\\\)\\2) *\).*'
|
||||
mark_section "$tier-from-script-explicitly-added"
|
||||
extract_fish_script_messages_impl $explicit_regex $argv
|
||||
|
||||
# This regex handles descriptions for `complete` and `function` statements. These messages are not
|
||||
# particularly important to translate. Hence the "implicit" label.
|
||||
set -l implicit_regex '^(?:\s|and |or )*(?:complete|function).*? (?:-d|--description) (([\'"]).+?(?<!\\\\)\\2).*'
|
||||
mark_section "$tier-from-script-implicitly-added"
|
||||
extract_fish_script_messages_impl $implicit_regex $argv
|
||||
end
|
||||
|
||||
set -g share_dir $workspace_root/share
|
||||
|
||||
set -l tier1 $share_dir/config.fish
|
||||
set -l tier2
|
||||
set -l tier3
|
||||
|
||||
for file in $share_dir/completions/*.fish $share_dir/functions/*.fish
|
||||
# set -l tier (string match -r '^# localization: .*' <$file)
|
||||
set -l tier (string replace -rf -m1 \
|
||||
'^# localization: (.*)$' '$1' <$file)
|
||||
if set -q tier[1]
|
||||
switch "$tier"
|
||||
case tier1 tier2 tier3
|
||||
set -a $tier $file
|
||||
case 'skip*'
|
||||
case '*'
|
||||
echo >&2 "$file:1 unexpected localization tier: $tier"
|
||||
exit 1
|
||||
end
|
||||
continue
|
||||
end
|
||||
set -l dirname (path basename (path dirname $file))
|
||||
set -l command_name (path basename --no-extension $file)
|
||||
if test $dirname = functions &&
|
||||
string match -q -- 'fish_*' $command_name
|
||||
set -a tier1 $file
|
||||
continue
|
||||
end
|
||||
if test $dirname != completions
|
||||
echo >&2 "$file:1 missing localization tier for function file"
|
||||
exit 1
|
||||
end
|
||||
if test -e $workspace_root/doc_src/cmds/$command_name.rst
|
||||
set -a tier1 $file
|
||||
else
|
||||
set -a tier3 $file
|
||||
end
|
||||
end
|
||||
|
||||
extract_fish_script_messages tier1 $tier1
|
||||
extract_fish_script_messages tier2 $tier2
|
||||
extract_fish_script_messages tier3 $tier3
|
||||
end |
|
||||
# At this point, all extracted strings have been written to stdout,
|
||||
# starting with the ones taken from the Rust sources,
|
||||
# followed by strings explicitly marked for translation in fish scripts,
|
||||
# and finally the strings from fish scripts which get translated implicitly.
|
||||
# Because we do not eliminate duplicates across these categories,
|
||||
# we do it here, since other gettext tools expect no duplicates.
|
||||
msguniq --no-wrap
|
||||
rm -r /tmp/fish
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env sh
|
||||
# Originally from the git sources (GIT-VERSION-GEN)
|
||||
# Presumably (C) Junio C Hamano <junkio@cox.net>
|
||||
# Reused under GPL v2.0
|
||||
@@ -9,26 +9,14 @@ set -e
|
||||
# Find the fish directory as two levels up from script directory.
|
||||
FISH_BASE_DIR="$( cd "$( dirname "$( dirname "$0" )" )" && pwd )"
|
||||
DEF_VER=unknown
|
||||
git_permission_failed=0
|
||||
|
||||
# First see if there is a version file (included in release tarballs),
|
||||
# then try git-describe, then default.
|
||||
if test -f version
|
||||
then
|
||||
VN=$(cat version) || VN="$DEF_VER"
|
||||
else
|
||||
if VN=$(git -C "$FISH_BASE_DIR" describe --always --dirty 2>/dev/null); then
|
||||
:
|
||||
else
|
||||
if test $? = 128; then
|
||||
# Current git versions return status 128
|
||||
# when run in a repo owned by another user.
|
||||
# Even for describe and everything.
|
||||
# This occurs for `sudo make install`.
|
||||
git_permission_failed=1
|
||||
fi
|
||||
VN="$DEF_VER"
|
||||
fi
|
||||
elif ! VN=$(git -C "$FISH_BASE_DIR" describe --always --dirty 2>/dev/null); then
|
||||
VN="$DEF_VER"
|
||||
fi
|
||||
|
||||
# If the first param is --stdout, then output to stdout and exit.
|
||||
@@ -40,31 +28,22 @@ fi
|
||||
|
||||
# Set the output directory as either the first param or cwd.
|
||||
test -n "$1" && OUTPUT_DIR=$1/ || OUTPUT_DIR=
|
||||
FBVF="${OUTPUT_DIR}FISH-BUILD-VERSION-FILE"
|
||||
FBVF=${OUTPUT_DIR}FISH-BUILD-VERSION-FILE
|
||||
|
||||
if test "$VN" = unknown && test -r "$FBVF" && test "$git_permission_failed" = 1
|
||||
if test -r $FBVF
|
||||
then
|
||||
# HACK: Git failed, so we keep the current version file.
|
||||
# This helps in case you built fish as a normal user
|
||||
# and then try to `sudo make install` it.
|
||||
date +%s > "${OUTPUT_DIR}"fish-build-version-witness.txt
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -r "$FBVF"
|
||||
then
|
||||
VC=$(cat "$FBVF")
|
||||
VC=$(grep -v '^#' $FBVF | tr -d '"' | sed -e 's/^FISH_BUILD_VERSION=//')
|
||||
else
|
||||
VC="unset"
|
||||
fi
|
||||
|
||||
# Maybe output the FBVF
|
||||
# It looks like "2.7.1-621-ga2f065e6"
|
||||
# It looks like FISH_BUILD_VERSION="2.7.1-621-ga2f065e6"
|
||||
test "$VN" = "$VC" || {
|
||||
echo >&2 "$VN"
|
||||
echo "$VN" >"$FBVF"
|
||||
echo >&2 "FISH_BUILD_VERSION=$VN"
|
||||
echo "FISH_BUILD_VERSION=\"$VN\"" >${FBVF}
|
||||
}
|
||||
|
||||
# Output the fish-build-version-witness.txt
|
||||
# See https://cmake.org/cmake/help/v3.4/policy/CMP0058.html
|
||||
date +%s > "${OUTPUT_DIR}"fish-build-version-witness.txt
|
||||
date +%s > ${OUTPUT_DIR}fish-build-version-witness.txt
|
||||
|
||||
@@ -1,392 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>platform-application</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.no-container</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.container-manager</key>
|
||||
<true/>
|
||||
<key>com.apple.private.skip-library-validation</key>
|
||||
<true/>
|
||||
<key>com.apple.private.MobileContainerManager.allowed</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.adprivacyd</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.amfid</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.AppBundles</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.AppDataContainers</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.automation-mode</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Biome</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Calendar</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.CallHistory</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.CarrierBundles</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.chronod</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.CloudDocsDB</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.CloudKit</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.containers</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.CoreFollowUp</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.CoreKnowledge</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Cryptex</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.demo_backup</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.DocumentRevisions</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.DumpPanic</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.ExposureNotification</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.FaceTime</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.familycircled</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.FindMy</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.fpsd</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Health</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.HomeAI</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.HomeKit</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.iCloudDrive</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.idcredd</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.IdentityServices</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.kbd</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Keychains</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Lockdown</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Mail</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Messages</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.MessagesMetaData</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.MobileContainerManager</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.MobileDocuments</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.MobileIdentityService</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.mobilesync</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.multimodalsearchd</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.NanoTimeKit.FaceSupport</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.News</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Notes</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Photos</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.PhotosLibraries</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.pipelined</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.preferences</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.PrivacyAccounting</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Safari</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.SearchParty</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.SecureElementService</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.SensorKit</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.SFAnalytics</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.SiriInference</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.SiriReferenceResolution</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.SiriVocabulary</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.SoC</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.SpeechPersonalizedLM</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Spotlight</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.StatusKit</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Stocks</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Suggestions</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.SymptomFramework</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.sysdagnose.ScreenshotServicesService</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.TCC</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.TimeMachine</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.triald</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.trustd</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.trustd-private</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.universalaccess</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Voicemail</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Wireless</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.disk-device-access</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.ane_model_cache</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.apfs_boot_mount</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.clientScripter</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.mediaanalysisd</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.CarPlayAppBlacklist</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.DeviceCheck</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.DictionaryServices.dictionary2</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.DuetExpertCenterAsset</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.EmbeddedNL</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.Font5</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.Font6</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.HealthKt.FeatureAvailability</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.HomeKit</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.MacinTalkVoiceAssets</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.MailDynamicData</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.MXLongFormVideoApps</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.network.networknomicon</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.PKITrustSupplementals</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.SharingDeviceAssets</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.SiriShortcutsMobileAsset</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.TimeZoneUpdate</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.VoiceServices.CombinedVocalizerVoices</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.VoiceServices.CustomVoice</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.VoiceServices.GryphonVoice</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.VoiceServicesVocalizerVoice</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.VoiceServices.VoiceResources</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.VoiceTriggerAssets</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.CoreAnalytics</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.coreduet_knowledge_store</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.coreidvd</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.coreknowledge</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.CoreRoutine</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.CoreSpeech</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.dmd</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.dprivacyd_storage</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.ExtensibleSSO</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.facekit</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.fpsd</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.MobileStorageMounter</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.MusicApp</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.nsurlsessiond</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.pearl-field-diagnostics</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.proactivepredictions</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.QLThumbnailCache</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.remotemanagementd</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.RoleAccountStaging</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.sensorkit</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.shortcuts</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.siriremembers</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.timezone</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.triald</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.voiceshortcuts</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage-exempt.heritable</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.AppleMediaServices</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.ContactlessReader</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.CoreRoutine</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.DiagnosticReports</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.DiagnosticReports.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.DoNotDisturb</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Home</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.IntelligencePlatform</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Location</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.ManagedConfiguration</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.MapsSync</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.MobileBackup</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.MobileStorageMounter</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.PassKit</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.SiriFeatureStore</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.SiriSELF</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.SoundProfileAsset</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.TextUnderstanding</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.Weather</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.appleaccountd</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.ciconia</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.clipserviced</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.coreduet_knowledge_store</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.driverkitd</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.geoanalyticsd</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.geod</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.launchd</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.sessionkitd</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.sysdiagnose.ScreenshotServicesService</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.sysdiagnose.sysdiagnose</key>
|
||||
<true/>
|
||||
<key>com.apple.private.security.storage.tmp</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.critical</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.datavault.metadata</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.install</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.install.heritable</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.restricted-block-devices</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.MobileAssetDownload</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.amsengagementd</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.HealthKit.FeatureAvailability</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriDialogAssets</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriExperienceCam</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriFindMyConfigurationFiles</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriInferredHelpfulness</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriTextToSpeech</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriUnderstandingAsrAssistant</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriUnderstandingAsrHammer</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriUnderstandingAsrUaap</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriUnderstandingAttentionAssets</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriUnderstandingMorphun</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriUnderstandingNL</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.com.apple.MobileAsset.Trial.Siri.SiriUnderstandingNLOverrides</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.coreparsec_feedbacks</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.coreparsec_uploadables</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.early_boot_mount</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.storage.screentime</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.volume.ISCRecovery</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.volume.Preboot</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.volume.Recovery</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.volume.Update</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.volume.VM</key>
|
||||
<true/>
|
||||
<key>com.apple.rootless.volume.iSCPreboot</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
28
build_tools/iwyu.linux.imp
Normal file
28
build_tools/iwyu.linux.imp
Normal file
@@ -0,0 +1,28 @@
|
||||
# Map file for the include-what-you-use tool on Linux.
|
||||
[
|
||||
{ include: ["<bits/fcntl-linux.h>", "private", "<fcntl.h>", "public"] },
|
||||
{ include: ["<bits/mman-linux.h>", "private", "<sys/mman.h>", "public"] },
|
||||
{ include: ["<bits/socket-linux.h>", "private", "<sys/socket.h>", "public"] },
|
||||
{ include: ["<bits/socket_type.h>", "private", "<sys/socket.h>", "public"] },
|
||||
{ include: ["<bits/local_lim.h>", "private", "<limits.h>", "public"] },
|
||||
{ include: ["<tr1/memory>", "public", "<memory>", "public"] },
|
||||
{ include: ["<features.h>", "public", "<stdio.h>", "public"] },
|
||||
{ include: ["<features.h>", "public", "<stddef.h>", "public"] },
|
||||
{ include: ["<features.h>", "public", "<unistd.h>", "public"] },
|
||||
|
||||
{ symbol: ["size_t", "private", "<unistd.h>", "public"] },
|
||||
{ symbol: ["size_t", "private", "<stddef.h>", "public"] },
|
||||
{ symbol: ["size_t", "private", "<stdlib.h>", "public"] },
|
||||
{ symbol: ["intmax_t", "private", "<sys/stdint.h>", "public"] },
|
||||
{ symbol: ["intmax_t", "private", "<sys/types.h>", "public"] },
|
||||
{ symbol: ["uint32_t", "private", "<sys/stdint.h>", "public"] },
|
||||
{ symbol: ["uint32_t", "private", "<sys/types.h>", "public"] },
|
||||
{ symbol: ["uint64_t", "private", "<sys/stdint.h>", "public"] },
|
||||
{ symbol: ["uint64_t", "private", "<sys/types.h>", "public"] },
|
||||
{ symbol: ["uintmax_t", "private", "<sys/stdint.h>", "public"] },
|
||||
{ symbol: ["uintmax_t", "private", "<sys/types.h>", "public"] },
|
||||
{ symbol: ["clock_gettime", "private", "<sys/time.h>", "public"] },
|
||||
{ symbol: ["timespec", "private", "<sys/time.h>", "public"] },
|
||||
{ symbol: ["memset", "private", "<string.h>", "public"] },
|
||||
{ symbol: ["strerror", "private", "<string.h>", "public"] },
|
||||
]
|
||||
109
build_tools/iwyu.osx.imp
Normal file
109
build_tools/iwyu.osx.imp
Normal file
@@ -0,0 +1,109 @@
|
||||
# Map file for the include-what-you-use tool on OS X. For some reason
|
||||
# the version installed by HomeBrew doesn't have useful mappings for the
|
||||
# system provided headers. This also has mappings for FreeBSD.
|
||||
[
|
||||
{ include: ["<sys/_pthread/_pthread_once_t.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_pthread/_pthread_mutex_t.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_pthread/_pthread_rwlock_t.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_pthread/_pthread_mutexattr_t.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_pthread/_pthread_cond_t.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_pthread/_pthread_t.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_pthread/_pthread_key_t.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_pthreadtypes.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_types/_posix_vdisable.h>", "private", "<pthread.h>", "public"] },
|
||||
{ include: ["<sys/_types/_time_t.h>", "private", "<time.h>", "public"] },
|
||||
{ include: ["<sys/_types/_suseconds_t.h>", "private", "<time.h>", "public"] },
|
||||
{ include: ["<sys/_types/_suseconds_t.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/errno.h>", "private", "<errno.h>", "public"] },
|
||||
{ include: ["<sys/unistd.h>", "private", "<unistd.h>", "public"] },
|
||||
{ include: ["<_wctype.h>", "private", "<wctype.h>", "public"] },
|
||||
{ include: ["<sys/fcntl.h>", "private", "<fcntl.h>", "public"] },
|
||||
{ include: ["<sys/_types/_seek_set.h>", "private", "<fcntl.h>", "public"] },
|
||||
{ include: ["<sys/_types/_mbstate_t.h>", "private", "<wchar.h>", "public"] },
|
||||
{ include: ["<iosfwd>", "private", "<string>", "public"] },
|
||||
{ include: ["<sys/_stdint.h>", "private", "<stdint.h>", "public"] },
|
||||
{ include: ["<sys/_types/_s_ifmt.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_size_t.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_size_t.h>", "private", "<stdlib.h>", "public"] },
|
||||
{ include: ["<sys/_types/_mode_t.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_pid_t.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_fd_def.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_fd_isset.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_fd_set.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_fd_zero.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_timeval.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_uid_t.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<_types/_intmax_t.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<_types/_uintmax_t.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<_types/_uint8_t.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_int32_t.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<_types/_uint64_t.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_uintptr_t.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_dev_t.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_ino_t.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_va_list.h>", "private", "<stdio.h>", "public"] },
|
||||
{ include: ["<__functional_base>", "private", "<memory>", "public"] },
|
||||
{ include: ["<__functional_base>", "private", "<vector>", "public"] },
|
||||
{ include: ["<__functional_base>", "private", "<string>", "public"] },
|
||||
{ include: ["<__tree>", "private", "<map>", "public"] },
|
||||
{ include: ["<__tree>", "private", "<set>", "public"] },
|
||||
{ include: ["<_types/_uint32_t.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_va_list.h>", "private", "<sys/types.h>", "public"] },
|
||||
{ include: ["<sys/_types/_sigset_t.h>", "private", "<signal.h>", "public"] },
|
||||
{ include: ["<sys/signal.h>", "private", "<signal.h>", "public"] },
|
||||
{ include: ["<strings.h>", "private", "<string.h>", "public"] },
|
||||
{ include: ["<sys/termios.h>", "private", "<termios.h>", "public"] },
|
||||
{ include: ["<sys/_termios.h>", "private", "<termios.h>", "public"] },
|
||||
{ include: ["<sys/ttycom.h>", "private", "<termios.h>", "public"] },
|
||||
{ include: ["<sys/syslimits.h>", "private", "<limits.h>", "public"] },
|
||||
{ include: ["<i386/limits.h>", "private", "<limits.h>", "public"] },
|
||||
{ include: ["<sys/limits.h>", "private", "<limits.h>", "public"] },
|
||||
{ include: ["<sys/_types/_wint_t.h>", "private", "<stddef.h>", "public"] },
|
||||
{ include: ["<sys/_select.h>", "private", "<select.h>", "public"] },
|
||||
{ include: ["<sys/cdefs.h>", "private", "<unistd.h>", "public"] },
|
||||
{ include: ["<istream>", "private", "<iostream>", "public"] },
|
||||
{ include: ["<sys/_endian.h>", "private", "<netinet/in.h>", "public"] },
|
||||
{ include: ["<sys/_types/_timespec.h>", "private", "<time.h>", "public"] },
|
||||
{ include: ["<sys/_timespec.h>", "private", "<time.h>", "public"] },
|
||||
{ include: ["<sys/spawn.h>", "private", "<spawn.h>", "public"] },
|
||||
{ include: ["<sys/dirent.h>", "private", "<dirent.h>", "public"] },
|
||||
{ include: ["<__mutex_base>", "private", "<mutex>", "public"] },
|
||||
{ include: ["<__hash_table>", "private", "<unordered_map>", "public"] },
|
||||
{ include: ["<__hash_table>", "private", "<unordered_set>", "public"] },
|
||||
# { include: ["<>", "private", "<>", "public"] },
|
||||
|
||||
{ symbol: ["size_t", "private", "<cstddef>", "public"] },
|
||||
{ symbol: ["mutex", "private", "<mutex>", "public"] },
|
||||
{ symbol: ["sig_atomic_t", "private", "<csignal>", "public"] },
|
||||
{ symbol: ["va_end", "private", "<stdarg.h>", "public"] },
|
||||
{ symbol: ["va_list", "private", "<stdarg.h>", "public"] },
|
||||
{ symbol: ["va_start", "private", "<stdarg.h>", "public"] },
|
||||
{ symbol: ["NULL", "private", "<stddef.h>", "public"] },
|
||||
{ symbol: ["NULL", "private", "<stdlib.h>", "public"] },
|
||||
{ symbol: ["NULL", "private", "<stdio.h>", "public"] },
|
||||
{ symbol: ["NULL", "private", "<unistd.h>", "public"] },
|
||||
{ symbol: ["off_t", "private", "<unistd.h>", "public"] },
|
||||
{ symbol: ["off_t", "private", "<sys/types.h>", "public"] },
|
||||
{ symbol: ["size_t", "private", "<stddef.h>", "public"] },
|
||||
{ symbol: ["ssize_t", "private", "<stddef.h>", "public"] },
|
||||
{ symbol: ["intptr_t", "private", "<unistd.h>", "public"] },
|
||||
{ symbol: ["gid_t", "private", "<unistd.h>", "public"] },
|
||||
{ symbol: ["uid_t", "private", "<unistd.h>", "public"] },
|
||||
{ symbol: ["pid_t", "private", "<unistd.h>", "public"] },
|
||||
{ symbol: ["pid_t", "private", "<sys/types.h>", "public"] },
|
||||
{ symbol: ["uid_t", "private", "<sys/types.h>", "public"] },
|
||||
{ symbol: ["gid_t", "private", "<sys/types.h>", "public"] },
|
||||
{ symbol: ["timeval", "private", "<sys/time.h>", "public"] },
|
||||
{ symbol: ["__uint32_t", "private", "<stdint.h>", "public"] },
|
||||
{ symbol: ["uint32_t", "private", "<stdint.h>", "public"] },
|
||||
{ symbol: ["intptr_t", "private", "<stdint.h>", "public"] },
|
||||
{ symbol: ["tparm", "private", "<ncurses.h>", "public"] },
|
||||
{ symbol: ["tigetflag", "private", "<ncurses.h>", "public"] },
|
||||
{ symbol: ["ERR", "private", "<ncurses.h>", "public"] },
|
||||
{ symbol: ["OK", "private", "<ncurses.h>", "public"] },
|
||||
{ symbol: ["select", "private", "<sys/select.h>", "public"] },
|
||||
{ symbol: ["_LIBCPP_VERSION", "private", "<stddef.h>", "public"] },
|
||||
{ symbol: ["_LIBCPP_VERSION", "private", "<unistd.h>", "public"] },
|
||||
{ symbol: ["MB_CUR_MAX", "private", "<xlocale.h>", "public"] },
|
||||
{ symbol: ["MB_CUR_MAX", "private", "<stdlib.h>", "public"] },
|
||||
]
|
||||
132
build_tools/lint.fish
Executable file
132
build_tools/lint.fish
Executable file
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env fish
|
||||
#
|
||||
# This is meant to be run by "make lint" or "make lint-all". It is not meant to
|
||||
# be run directly from a shell prompt.
|
||||
#
|
||||
|
||||
# We don't include "missingInclude" as that doesn't find our config.h.
|
||||
# Missing includes will quickly be found by... compiling the thing anyway.
|
||||
set -l cppchecks warning,performance,portability,information #,missingInclude
|
||||
set -l cppcheck_args
|
||||
set -l c_files
|
||||
set -l all no
|
||||
set -l kernel_name (uname -s)
|
||||
set -l machine_type (uname -m)
|
||||
|
||||
argparse a/all p/project= -- $argv
|
||||
|
||||
# We only want -D and -I options to be passed thru to cppcheck.
|
||||
for arg in $argv
|
||||
if string match -q -- '-D*' $arg
|
||||
set cppcheck_args $cppcheck_args $arg
|
||||
else if string match -q -- '-I*' $arg
|
||||
set cppcheck_args $cppcheck_args $arg
|
||||
else if string match -q -- '-iquote*' $arg
|
||||
set cppcheck_args $cppcheck_args $arg
|
||||
end
|
||||
end
|
||||
|
||||
# Not sure when this became necessary but without these flags cppcheck no longer works on macOS.
|
||||
# It complains that "Cppcheck cannot find all the include files." Adding these include paths should
|
||||
# be harmless everywhere else.
|
||||
set cppcheck_args $cppcheck_args -I /usr/include -I .
|
||||
|
||||
if test "$machine_type" = x86_64
|
||||
set cppcheck_args -D__x86_64__ -D__LP64__ $cppcheck_args
|
||||
end
|
||||
|
||||
if set -q _flag_all
|
||||
set c_files src/*.cpp
|
||||
set cppchecks "$cppchecks,unusedFunction"
|
||||
else
|
||||
# We haven't been asked to lint all the source. If there are uncommitted
|
||||
# changes lint those, else lint the files in the most recent commit.
|
||||
# Select (cached files) (modified but not cached, and untracked files)
|
||||
set -l files (git diff-index --cached HEAD --name-only)
|
||||
set files $files (git ls-files --exclude-standard --others --modified)
|
||||
if not set -q files[1]
|
||||
# No pending changes so lint the files in the most recent commit.
|
||||
set files (git diff-tree --no-commit-id --name-only -r HEAD)
|
||||
end
|
||||
|
||||
# Extract just the C/C++ files that exist.
|
||||
set c_files
|
||||
for file in (string match -r '.*\.c(?:pp)?$' -- $files)
|
||||
test -f $file; and set c_files $c_files $file
|
||||
end
|
||||
end
|
||||
|
||||
# We now have a list of files to check so run the linters.
|
||||
if set -q c_files[1]
|
||||
if type -q include-what-you-use
|
||||
echo
|
||||
echo ========================================
|
||||
echo Running IWYU
|
||||
echo ========================================
|
||||
for c_file in $c_files
|
||||
switch $kernel_name
|
||||
case Darwin FreeBSD
|
||||
include-what-you-use -Xiwyu --no_default_mappings -Xiwyu \
|
||||
--mapping_file=build_tools/iwyu.osx.imp --std=c++11 \
|
||||
$cppcheck_args $c_file 2>&1
|
||||
case Linux
|
||||
include-what-you-use -Xiwyu --mapping_file=build_tools/iwyu.linux.imp \
|
||||
$cppcheck_args $c_file 2>&1
|
||||
case '*' # hope for the best
|
||||
include-what-you-use --std=c++11 $cppcheck_args $c_file 2>&1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if type -q cppcheck
|
||||
echo
|
||||
echo ========================================
|
||||
echo Running cppcheck
|
||||
echo ========================================
|
||||
# The stderr to stdout redirection is because cppcheck, incorrectly IMHO, writes its
|
||||
# diagnostic messages to stderr. Anyone running this who wants to capture its output will
|
||||
# expect those messages to be written to stdout.
|
||||
set -l cn (set_color normal)
|
||||
set -l cb (set_color --bold)
|
||||
set -l cu (set_color --underline)
|
||||
set -l cm (set_color magenta)
|
||||
set -l cbrm (set_color brmagenta)
|
||||
set -l template "[$cb$cu{file}$cn$cb:{line}$cn] $cbrm{severity}$cm ({id}):$cn\n {message}"
|
||||
set cppcheck_args -q --verbose --std=c++11 --std=posix --language=c++ --template $template \
|
||||
--suppress=missingIncludeSystem --inline-suppr --enable=$cppchecks \
|
||||
--rule-file=.cppcheck.rules --suppressions-list=.cppcheck.suppressions $cppcheck_args
|
||||
|
||||
cppcheck $cppcheck_args $c_files 2>&1
|
||||
|
||||
echo
|
||||
echo ========================================
|
||||
echo 'Running `cppcheck --check-config` to identify missing includes and similar problems.'
|
||||
echo 'Ignore unmatchedSuppression warnings as they are probably false positives we'
|
||||
echo 'cannot suppress.'
|
||||
echo ========================================
|
||||
cppcheck $cppcheck_args --check-config $c_files 2>&1
|
||||
end
|
||||
|
||||
if type -q oclint
|
||||
echo
|
||||
echo ========================================
|
||||
echo Running oclint
|
||||
echo ========================================
|
||||
# The stderr to stdout redirection is because oclint, incorrectly writes its final summary
|
||||
# counts of the errors detected to stderr. Anyone running this who wants to capture its
|
||||
# output will expect those messages to be written to stdout.
|
||||
oclint $c_files -- $argv 2>&1
|
||||
end
|
||||
|
||||
if type -q clang-tidy; and set -q _flag_project
|
||||
echo
|
||||
echo ========================================
|
||||
echo Running clang-tidy
|
||||
echo ========================================
|
||||
clang-tidy -p $_flag_project $c_files
|
||||
end
|
||||
else
|
||||
echo
|
||||
echo 'WARNING: No C/C++ files to check'
|
||||
echo
|
||||
end
|
||||
@@ -13,9 +13,7 @@ if not contains -- $TAG (git tag)
|
||||
end
|
||||
|
||||
set -l committers_to_tag (mktemp)
|
||||
or exit 1
|
||||
set -l committers_from_tag (mktemp)
|
||||
or exit 1
|
||||
|
||||
# You might think it would be better to case-insensitively sort/compare the names
|
||||
# to produce a more natural-looking list.
|
||||
|
||||
560
build_tools/littlecheck.py
Executable file
560
build_tools/littlecheck.py
Executable file
@@ -0,0 +1,560 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
""" Command line test driver. """
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
from collections import deque
|
||||
import datetime
|
||||
import io
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
# A regex showing how to run the file.
|
||||
RUN_RE = re.compile(r"\s*#\s*RUN:\s+(.*)\n")
|
||||
|
||||
# A regex capturing lines that should be checked against stdout.
|
||||
CHECK_STDOUT_RE = re.compile(r"\s*#\s*CHECK:\s+(.*)\n")
|
||||
|
||||
# A regex capturing lines that should be checked against stderr.
|
||||
CHECK_STDERR_RE = re.compile(r"\s*#\s*CHECKERR:\s+(.*)\n")
|
||||
|
||||
|
||||
class Config(object):
|
||||
def __init__(self):
|
||||
# Whether to have verbose output.
|
||||
self.verbose = False
|
||||
# Whether output gets ANSI colorization.
|
||||
self.colorize = False
|
||||
# Whether to show which file was tested.
|
||||
self.progress = False
|
||||
# How many after lines to print
|
||||
self.after = 5
|
||||
# How many before lines to print
|
||||
self.before = 5
|
||||
|
||||
def colors(self):
|
||||
""" Return a dictionary mapping color names to ANSI escapes """
|
||||
|
||||
def ansic(n):
|
||||
return "\033[%dm" % n if self.colorize else ""
|
||||
|
||||
return {
|
||||
"RESET": ansic(0),
|
||||
"BOLD": ansic(1),
|
||||
"NORMAL": ansic(39),
|
||||
"BLACK": ansic(30),
|
||||
"RED": ansic(31),
|
||||
"GREEN": ansic(32),
|
||||
"YELLOW": ansic(33),
|
||||
"BLUE": ansic(34),
|
||||
"MAGENTA": ansic(35),
|
||||
"CYAN": ansic(36),
|
||||
"LIGHTGRAY": ansic(37),
|
||||
"DARKGRAY": ansic(90),
|
||||
"LIGHTRED": ansic(91),
|
||||
"LIGHTGREEN": ansic(92),
|
||||
"LIGHTYELLOW": ansic(93),
|
||||
"LIGHTBLUE": ansic(94),
|
||||
"LIGHTMAGENTA": ansic(95),
|
||||
"LIGHTCYAN": ansic(96),
|
||||
"WHITE": ansic(97),
|
||||
}
|
||||
|
||||
|
||||
def output(*args):
|
||||
print("".join(args) + "\n")
|
||||
|
||||
|
||||
import unicodedata
|
||||
|
||||
|
||||
def esc(m):
|
||||
map = {
|
||||
"\n": "\\n",
|
||||
"\\": "\\\\",
|
||||
"'": "\\'",
|
||||
'"': '\\"',
|
||||
"\a": "\\a",
|
||||
"\b": "\\b",
|
||||
"\f": "\\f",
|
||||
"\r": "\\r",
|
||||
"\t": "\\t",
|
||||
"\v": "\\v",
|
||||
}
|
||||
if m in map:
|
||||
return map[m]
|
||||
if unicodedata.category(m)[0] == "C":
|
||||
return "\\x{:02x}".format(ord(m))
|
||||
else:
|
||||
return m
|
||||
|
||||
|
||||
def escape_string(s):
|
||||
return "".join(esc(ch) for ch in s)
|
||||
|
||||
|
||||
class CheckerError(Exception):
|
||||
"""Exception subclass for check line parsing.
|
||||
|
||||
Attributes:
|
||||
line: the Line object on which the exception occurred.
|
||||
"""
|
||||
|
||||
def __init__(self, message, line=None):
|
||||
super(CheckerError, self).__init__(message)
|
||||
self.line = line
|
||||
|
||||
|
||||
class Line(object):
|
||||
""" A line that remembers where it came from. """
|
||||
|
||||
def __init__(self, text, number, file):
|
||||
self.text = text
|
||||
self.number = number
|
||||
self.file = file
|
||||
|
||||
def subline(self, text):
|
||||
""" Return a substring of our line with the given text, preserving number and file. """
|
||||
return Line(text, self.number, self.file)
|
||||
|
||||
@staticmethod
|
||||
def readfile(file, name):
|
||||
return [Line(text, idx + 1, name) for idx, text in enumerate(file)]
|
||||
|
||||
def is_empty_space(self):
|
||||
return not self.text or self.text.isspace()
|
||||
|
||||
|
||||
class RunCmd(object):
|
||||
""" A command to run on a given Checker.
|
||||
|
||||
Attributes:
|
||||
args: Unexpanded shell command as a string.
|
||||
"""
|
||||
|
||||
def __init__(self, args, line):
|
||||
self.args = args
|
||||
self.line = line
|
||||
|
||||
@staticmethod
|
||||
def parse(line):
|
||||
if not shlex.split(line.text):
|
||||
raise CheckerError("Invalid RUN command", line)
|
||||
return RunCmd(line.text, line)
|
||||
|
||||
|
||||
class TestFailure(object):
|
||||
def __init__(self, line, check, testrun, before=None, after=None):
|
||||
self.line = line
|
||||
self.check = check
|
||||
self.testrun = testrun
|
||||
self.error_annotation_line = None
|
||||
# The output that comes *after* the failure.
|
||||
self.after = after
|
||||
self.before = before
|
||||
|
||||
def message(self):
|
||||
afterlines = self.testrun.config.after
|
||||
fields = self.testrun.config.colors()
|
||||
fields["name"] = self.testrun.name
|
||||
fields["subbed_command"] = self.testrun.subbed_command
|
||||
if self.line:
|
||||
fields.update(
|
||||
{
|
||||
"output_file": self.line.file,
|
||||
"output_lineno": self.line.number,
|
||||
"output_line": self.line.text.rstrip("\n"),
|
||||
}
|
||||
)
|
||||
if self.check:
|
||||
fields.update(
|
||||
{
|
||||
"input_file": self.check.line.file,
|
||||
"input_lineno": self.check.line.number,
|
||||
"input_line": self.check.line.text,
|
||||
"check_type": self.check.type,
|
||||
}
|
||||
)
|
||||
filemsg = "" if self.testrun.config.progress else " in {name}"
|
||||
fmtstrs = ["{RED}Failure{RESET}" + filemsg + ":", ""]
|
||||
if self.line and self.check:
|
||||
fmtstrs += [
|
||||
" The {check_type} on line {input_lineno} wants:",
|
||||
" {BOLD}{input_line}{RESET}",
|
||||
"",
|
||||
" which failed to match line {output_file}:{output_lineno}:",
|
||||
" {BOLD}{output_line}{RESET}",
|
||||
"",
|
||||
]
|
||||
|
||||
elif self.check:
|
||||
fmtstrs += [
|
||||
" The {check_type} on line {input_lineno} wants:",
|
||||
" {BOLD}{input_line}{RESET}",
|
||||
"",
|
||||
" but there was no remaining output to match.",
|
||||
"",
|
||||
]
|
||||
else:
|
||||
fmtstrs += [
|
||||
" There were no remaining checks left to match {output_file}:{output_lineno}:",
|
||||
" {BOLD}{output_line}{RESET}",
|
||||
"",
|
||||
]
|
||||
if self.error_annotation_line:
|
||||
fields["error_annotation"] = self.error_annotation_line.text
|
||||
fields["error_annotation_lineno"] = self.error_annotation_line.number
|
||||
fmtstrs += [
|
||||
" additional output on stderr:{error_annotation_lineno}:",
|
||||
" {BOLD}{error_annotation}{RESET}",
|
||||
]
|
||||
if self.before:
|
||||
fields["before_output"] = " ".join(self.before)
|
||||
fields["additional_output"] = " ".join(self.after[:afterlines])
|
||||
fmtstrs += [
|
||||
" Context:",
|
||||
" {BOLD}{before_output} {RED}{output_line}{RESET} <= does not match '{LIGHTBLUE}{input_line}{RESET}'",
|
||||
" {BOLD}{additional_output}{RESET}",
|
||||
]
|
||||
elif self.after:
|
||||
fields["additional_output"] = " ".join(self.after[:afterlines])
|
||||
fmtstrs += [" additional output:", " {BOLD}{additional_output}{RESET}"]
|
||||
fmtstrs += [" when running command:", " {subbed_command}"]
|
||||
return "\n".join(fmtstrs).format(**fields)
|
||||
|
||||
def print_message(self):
|
||||
""" Print our message to stdout. """
|
||||
print(self.message())
|
||||
|
||||
|
||||
def perform_substitution(input_str, subs):
|
||||
""" Perform the substitutions described by subs to str
|
||||
Return the substituted string.
|
||||
"""
|
||||
# Sort our substitutions into a list of tuples (key, value), descending by length.
|
||||
# It needs to be descending because we need to try longer substitutions first.
|
||||
subs_ordered = sorted(subs.items(), key=lambda s: len(s[0]), reverse=True)
|
||||
|
||||
def subber(m):
|
||||
# We get the entire sequence of characters.
|
||||
# Replace just the prefix and return it.
|
||||
text = m.group(1)
|
||||
for key, replacement in subs_ordered:
|
||||
if text.startswith(key):
|
||||
return replacement + text[len(key) :]
|
||||
# No substitution found, so we default to running it as-is,
|
||||
# which will end up running it via $PATH.
|
||||
return text
|
||||
|
||||
return re.sub(r"%(%|[a-zA-Z0-9_-]+)", subber, input_str)
|
||||
|
||||
|
||||
class TestRun(object):
|
||||
def __init__(self, name, runcmd, checker, subs, config):
|
||||
self.name = name
|
||||
self.runcmd = runcmd
|
||||
self.subbed_command = perform_substitution(runcmd.args, subs)
|
||||
self.checker = checker
|
||||
self.subs = subs
|
||||
self.config = config
|
||||
|
||||
def check(self, lines, checks):
|
||||
# Reverse our lines and checks so we can pop off the end.
|
||||
lineq = lines[::-1]
|
||||
checkq = checks[::-1]
|
||||
# We keep the last couple of lines in a deque so we can show context.
|
||||
before = deque(maxlen=self.config.before)
|
||||
while lineq and checkq:
|
||||
line = lineq[-1]
|
||||
check = checkq[-1]
|
||||
if check.regex.match(line.text):
|
||||
# This line matched this checker, continue on.
|
||||
lineq.pop()
|
||||
checkq.pop()
|
||||
before.append(line)
|
||||
elif line.is_empty_space():
|
||||
# Skip all whitespace input lines.
|
||||
lineq.pop()
|
||||
else:
|
||||
# Failed to match.
|
||||
lineq.pop()
|
||||
line.text = escape_string(line.text.strip()) + "\n"
|
||||
# Add context, ignoring empty lines.
|
||||
return TestFailure(
|
||||
line,
|
||||
check,
|
||||
self,
|
||||
before=[escape_string(line.text.strip()) + "\n" for line in before],
|
||||
after=[
|
||||
escape_string(line.text.strip()) + "\n"
|
||||
for line in lineq[::-1]
|
||||
if not line.is_empty_space()
|
||||
],
|
||||
)
|
||||
# Drain empties.
|
||||
while lineq and lineq[-1].is_empty_space():
|
||||
lineq.pop()
|
||||
# If there's still lines or checkers, we have a failure.
|
||||
# Otherwise it's success.
|
||||
if lineq:
|
||||
return TestFailure(lineq[-1], None, self)
|
||||
elif checkq:
|
||||
return TestFailure(None, checkq[-1], self)
|
||||
else:
|
||||
return None
|
||||
|
||||
def run(self):
|
||||
""" Run the command. Return a TestFailure, or None. """
|
||||
|
||||
def split_by_newlines(s):
|
||||
""" Decode a string and split it by newlines only,
|
||||
retaining the newlines.
|
||||
"""
|
||||
return [s + "\n" for s in s.decode("utf-8").split("\n")]
|
||||
|
||||
PIPE = subprocess.PIPE
|
||||
if self.config.verbose:
|
||||
print(self.subbed_command)
|
||||
proc = subprocess.Popen(
|
||||
self.subbed_command,
|
||||
stdin=PIPE,
|
||||
stdout=PIPE,
|
||||
stderr=PIPE,
|
||||
shell=True,
|
||||
close_fds=True, # For Python 2.6 as shipped on RHEL 6
|
||||
)
|
||||
stdout, stderr = proc.communicate()
|
||||
# HACK: This is quite cheesy: POSIX specifies that sh should return 127 for a missing command.
|
||||
# Technically it's also possible to return it in other conditions.
|
||||
# Practically, that's *probably* not going to happen.
|
||||
status = proc.returncode
|
||||
if status == 127:
|
||||
raise CheckerError("Command could not be found: " + self.subbed_command)
|
||||
|
||||
outlines = [
|
||||
Line(text, idx + 1, "stdout")
|
||||
for idx, text in enumerate(split_by_newlines(stdout))
|
||||
]
|
||||
errlines = [
|
||||
Line(text, idx + 1, "stderr")
|
||||
for idx, text in enumerate(split_by_newlines(stderr))
|
||||
]
|
||||
outfail = self.check(outlines, self.checker.outchecks)
|
||||
errfail = self.check(errlines, self.checker.errchecks)
|
||||
# It's possible that something going wrong on stdout resulted in new
|
||||
# text being printed on stderr. If we have an outfailure, and either
|
||||
# non-matching or unmatched stderr text, then annotate the outfail
|
||||
# with it.
|
||||
if outfail and errfail and errfail.line:
|
||||
outfail.error_annotation_line = errfail.line
|
||||
return outfail if outfail else errfail
|
||||
|
||||
|
||||
class CheckCmd(object):
|
||||
def __init__(self, line, checktype, regex):
|
||||
self.line = line
|
||||
self.type = checktype
|
||||
self.regex = regex
|
||||
|
||||
@staticmethod
|
||||
def parse(line, checktype):
|
||||
# type: (Line) -> CheckCmd
|
||||
# Everything inside {{}} is a regular expression.
|
||||
# Everything outside of it is a literal string.
|
||||
# Split around {{...}}. Then every odd index will be a regex, and
|
||||
# evens will be literals.
|
||||
# Note that if {{...}} appears first we will get an empty string in
|
||||
# the split array, so the {{...}} matches are always at odd indexes.
|
||||
bracket_re = re.compile(
|
||||
r"""
|
||||
\{\{ # Two open brackets
|
||||
(.*?) # Nongreedy capture
|
||||
\}\} # Two close brackets
|
||||
""",
|
||||
re.VERBOSE,
|
||||
)
|
||||
pieces = bracket_re.split(line.text)
|
||||
even = True
|
||||
re_strings = []
|
||||
for piece in pieces:
|
||||
if even:
|
||||
# piece is a literal string.
|
||||
re_strings.append(re.escape(piece))
|
||||
else:
|
||||
# piece is a regex (found inside {{...}}).
|
||||
# Verify the regex can be compiled.
|
||||
try:
|
||||
re.compile(piece)
|
||||
except re.error:
|
||||
raise CheckerError("Invalid regular expression: '%s'" % piece, line)
|
||||
re_strings.append(piece)
|
||||
even = not even
|
||||
# Enclose each piece in a non-capturing group.
|
||||
# This ensures that lower-precedence operators don't trip up catenation.
|
||||
# For example: {{b|c}}d would result in /b|cd/ which is different.
|
||||
# Backreferences are assumed to match across the entire string.
|
||||
re_strings = ["(?:%s)" % s for s in re_strings]
|
||||
# Anchor at beginning and end (allowing arbitrary whitespace), and maybe
|
||||
# a terminating newline.
|
||||
# We need the anchors because Python's match() matches an arbitrary prefix,
|
||||
# not the entire string.
|
||||
re_strings = [r"^\s*"] + re_strings + [r"\s*\n?$"]
|
||||
full_re = re.compile("".join(re_strings))
|
||||
return CheckCmd(line, checktype, full_re)
|
||||
|
||||
|
||||
class Checker(object):
|
||||
def __init__(self, name, lines):
|
||||
self.name = name
|
||||
# Helper to yield subline containing group1 from all matching lines.
|
||||
def group1s(regex):
|
||||
for line in lines:
|
||||
m = regex.match(line.text)
|
||||
if m:
|
||||
yield line.subline(m.group(1))
|
||||
|
||||
# Find run commands.
|
||||
self.runcmds = [RunCmd.parse(sl) for sl in group1s(RUN_RE)]
|
||||
if not self.runcmds:
|
||||
# If no RUN command has been given, fall back to the shebang.
|
||||
if lines[0].text.startswith("#!"):
|
||||
# Remove the "#!" at the beginning, and the newline at the end.
|
||||
self.runcmds = [RunCmd(lines[0].text[2:-1] + " %s", lines[0])]
|
||||
else:
|
||||
raise CheckerError("No runlines ('# RUN') found")
|
||||
|
||||
# Find check cmds.
|
||||
self.outchecks = [
|
||||
CheckCmd.parse(sl, "CHECK") for sl in group1s(CHECK_STDOUT_RE)
|
||||
]
|
||||
self.errchecks = [
|
||||
CheckCmd.parse(sl, "CHECKERR") for sl in group1s(CHECK_STDERR_RE)
|
||||
]
|
||||
|
||||
|
||||
def check_file(input_file, name, subs, config, failure_handler):
|
||||
""" Check a single file. Return a True on success, False on error. """
|
||||
success = True
|
||||
lines = Line.readfile(input_file, name)
|
||||
checker = Checker(name, lines)
|
||||
for runcmd in checker.runcmds:
|
||||
failure = TestRun(name, runcmd, checker, subs, config).run()
|
||||
if failure:
|
||||
failure_handler(failure)
|
||||
success = False
|
||||
return success
|
||||
|
||||
|
||||
def check_path(path, subs, config, failure_handler):
|
||||
with io.open(path, encoding="utf-8") as fd:
|
||||
return check_file(fd, path, subs, config, failure_handler)
|
||||
|
||||
|
||||
def parse_subs(subs):
|
||||
""" Given a list of input substitutions like 'foo=bar',
|
||||
return a dictionary like {foo:bar}, or exit if invalid.
|
||||
"""
|
||||
result = {}
|
||||
for sub in subs:
|
||||
try:
|
||||
key, val = sub.split("=", 1)
|
||||
if not key:
|
||||
print("Invalid substitution %s: empty key" % sub)
|
||||
sys.exit(1)
|
||||
if not val:
|
||||
print("Invalid substitution %s: empty value" % sub)
|
||||
sys.exit(1)
|
||||
result[key] = val
|
||||
except ValueError:
|
||||
print("Invalid substitution %s: equal sign not found" % sub)
|
||||
sys.exit(1)
|
||||
return result
|
||||
|
||||
|
||||
def get_argparse():
|
||||
""" Return a littlecheck argument parser. """
|
||||
parser = argparse.ArgumentParser(
|
||||
description="littlecheck: command line tool tester."
|
||||
)
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--substitute",
|
||||
type=str,
|
||||
help="Add a new substitution for RUN lines. Example: bash=/bin/bash",
|
||||
action="append",
|
||||
default=[],
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--progress",
|
||||
action="store_true",
|
||||
dest="progress",
|
||||
help="Show the files to be checked",
|
||||
default=False,
|
||||
)
|
||||
parser.add_argument("file", nargs="+", help="File to check")
|
||||
parser.add_argument(
|
||||
"-A",
|
||||
"--after",
|
||||
type=int,
|
||||
help="How many non-empty lines of output after a failure to print (default: 5)",
|
||||
action="store",
|
||||
default=5,
|
||||
)
|
||||
parser.add_argument(
|
||||
"-B",
|
||||
"--before",
|
||||
type=int,
|
||||
help="How many non-empty lines of output before a failure to print (default: 5)",
|
||||
action="store",
|
||||
default=5,
|
||||
)
|
||||
return parser
|
||||
|
||||
|
||||
def main():
|
||||
args = get_argparse().parse_args()
|
||||
# Default substitution is %% -> %
|
||||
def_subs = {"%": "%"}
|
||||
def_subs.update(parse_subs(args.substitute))
|
||||
|
||||
failure_count = 0
|
||||
config = Config()
|
||||
config.colorize = sys.stdout.isatty()
|
||||
config.progress = args.progress
|
||||
fields = config.colors()
|
||||
config.after = args.after
|
||||
config.before = args.before
|
||||
if config.before < 0:
|
||||
raise ValueError("Before must be at least 0")
|
||||
if config.after < 0:
|
||||
raise ValueError("After must be at least 0")
|
||||
|
||||
for path in args.file:
|
||||
fields["path"] = path
|
||||
if config.progress:
|
||||
print("Testing file {path} ... ".format(**fields), end="")
|
||||
sys.stdout.flush()
|
||||
subs = def_subs.copy()
|
||||
subs["s"] = path
|
||||
starttime = datetime.datetime.now()
|
||||
if not check_path(path, subs, config, TestFailure.print_message):
|
||||
failure_count += 1
|
||||
elif config.progress:
|
||||
endtime = datetime.datetime.now()
|
||||
duration_ms = round((endtime - starttime).total_seconds() * 1000)
|
||||
print(
|
||||
"{GREEN}ok{RESET} ({duration} ms)".format(
|
||||
duration=duration_ms, **fields
|
||||
)
|
||||
)
|
||||
sys.exit(failure_count)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,3 +0,0 @@
|
||||
# LSAN can detect leaks tracing back to __asan::AsanThread::ThreadStart (probably caused by our
|
||||
# threads not exiting before their TLS dtors are called). Just ignore it.
|
||||
leak:AsanThread
|
||||
@@ -1,27 +1,83 @@
|
||||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Helper to notarize an .app.zip or .pkg file.
|
||||
# Based on https://www.logcg.com/en/archives/3222.html
|
||||
|
||||
set -e
|
||||
|
||||
die() { echo "$*" 1>&2 ; exit 1; }
|
||||
|
||||
check_status() {
|
||||
echo "STATUS" $1
|
||||
}
|
||||
|
||||
test "$#" -ge 1 || die "No paths specified."
|
||||
get_req_uuid() {
|
||||
RESPONSE=$(</dev/stdin)
|
||||
if echo "$RESPONSE" | egrep -q "RequestUUID"; then
|
||||
echo "$RESPONSE" | egrep RequestUUID | awk '{print $3'}
|
||||
elif echo "$RESPONSE" | egrep -q "The upload ID is "; then
|
||||
echo "$RESPONSE" | egrep -p "The upload ID is [-a-z0-9]+" | awk '{print $5}'
|
||||
else
|
||||
die "Could not get Request UUID"
|
||||
fi
|
||||
}
|
||||
|
||||
for INPUT in "$@"; do
|
||||
echo "Processing $INPUT"
|
||||
test -f "$INPUT" || die "Not a file: $INPUT"
|
||||
ext="${INPUT##*.}"
|
||||
{ test "$ext" = "zip" || test "$ext" = "pkg"; } || die "Unrecognized extension: $ext"
|
||||
INPUT=$1
|
||||
AC_USER=$2
|
||||
|
||||
xcrun notarytool submit "$INPUT" --keychain-profile AC_PASSWORD --wait
|
||||
test -z "$AC_USER" && die "AC_USER not specified as second param"
|
||||
test -z "$INPUT" && die "No path specified"
|
||||
test -f "$INPUT" || die "Not a file: $INPUT"
|
||||
|
||||
ext="${INPUT##*.}"
|
||||
(test "$ext" = "zip" || test "$ext" = "pkg") || die "Unrecognized extension: $ext"
|
||||
|
||||
LOGFILE=$(mktemp -t mac_notarize_log)
|
||||
AC_PASS="@keychain:AC_PASSWORD"
|
||||
echo "Logs at $LOGFILE"
|
||||
|
||||
NOTARIZE_UUID=$(xcrun altool --notarize-app \
|
||||
--primary-bundle-id "com.ridiculousfish.fish-shell" \
|
||||
--username "$AC_USER" \
|
||||
--password "$AC_PASS" \
|
||||
--file "$INPUT" 2>&1 |
|
||||
tee -a "$LOGFILE" |
|
||||
get_req_uuid)
|
||||
|
||||
test -z "$NOTARIZE_UUID" && cat "$LOGFILE" && die "Could not get RequestUUID"
|
||||
echo "RequestUUID: $NOTARIZE_UUID"
|
||||
|
||||
success=0
|
||||
for i in $(seq 20); do
|
||||
echo "Checking progress..."
|
||||
PROGRESS=$(xcrun altool --notarization-info "${NOTARIZE_UUID}" \
|
||||
-u "$AC_USER" \
|
||||
-p "$AC_PASS" 2>&1 |
|
||||
tee -a "$LOGFILE")
|
||||
echo "${PROGRESS}" | tail -n 1
|
||||
|
||||
if [ $? -ne 0 ] || [[ "${PROGRESS}" =~ "Invalid" ]] ; then
|
||||
echo "Error with notarization. Exiting"
|
||||
break
|
||||
fi
|
||||
|
||||
if ! [[ "${PROGRESS}" =~ "in progress" ]]; then
|
||||
success=1
|
||||
break
|
||||
else
|
||||
echo "Not completed yet. Sleeping for 30 seconds."
|
||||
fi
|
||||
sleep 30
|
||||
done
|
||||
|
||||
if [ $success -eq 1 ] ; then
|
||||
if test "$ext" = "zip"; then
|
||||
TMPDIR=$(mktemp -d)
|
||||
echo "Extracting to $TMPDIR"
|
||||
unzip -q "$INPUT" -d "$TMPDIR"
|
||||
STAPLE_TARGET=$(echo "$TMPDIR"/*)
|
||||
# Force glob expansion.
|
||||
STAPLE_TARGET="$TMPDIR"/*
|
||||
STAPLE_TARGET=$(echo $STAPLE_TARGET)
|
||||
else
|
||||
STAPLE_TARGET="$INPUT"
|
||||
fi
|
||||
@@ -33,11 +89,11 @@ for INPUT in "$@"; do
|
||||
INPUT_FULL=$(realpath "$INPUT")
|
||||
rm -f "$INPUT"
|
||||
cd "$(dirname "$STAPLE_TARGET")"
|
||||
zip -r -q "$INPUT_FULL" "$(basename "$STAPLE_TARGET")"
|
||||
zip -r -q "$INPUT_FULL" $(basename "$STAPLE_TARGET")
|
||||
fi
|
||||
echo "Processed $INPUT"
|
||||
fi
|
||||
echo "Processed $INPUT"
|
||||
|
||||
if test "$ext" = "zip"; then
|
||||
spctl -a -v "$STAPLE_TARGET"
|
||||
fi
|
||||
done
|
||||
if test "$ext" = "zip"; then
|
||||
spctl -a -v "$STAPLE_TARGET"
|
||||
fi
|
||||
|
||||
@@ -1,166 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Script to produce an OS X installer .pkg and .app(.zip)
|
||||
|
||||
usage() {
|
||||
echo "Build macOS packages, optionally signing and notarizing them."
|
||||
echo "Usage: $0 options"
|
||||
echo "Options:"
|
||||
echo " -s Enables code signing"
|
||||
echo " -f <APP_KEY.p12> Path to .p12 file for application signing"
|
||||
echo " -i <INSTALLER_KEY.p12> Path to .p12 file for installer signing"
|
||||
echo " -p <PASSWORD> Password for the .p12 files (necessary to access the certificates)"
|
||||
echo " -e <entitlements file> (Optional) Path to an entitlements XML file"
|
||||
echo " -n Enables notarization. This will fail if code signing is not also enabled."
|
||||
echo " -j <API_KEY.JSON> Path to JSON file generated with \`rcodesign encode-app-store-connect-api-key\` (required for notarization)"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
SIGN=
|
||||
NOTARIZE=
|
||||
|
||||
ARM64_DEPLOY_TARGET='MACOSX_DEPLOYMENT_TARGET=11.0'
|
||||
X86_64_DEPLOY_TARGET='MACOSX_DEPLOYMENT_TARGET=10.12'
|
||||
|
||||
while getopts "sf:i:p:e:nj:" opt; do
|
||||
case $opt in
|
||||
s) SIGN=1;;
|
||||
f) P12_APP_FILE=$(realpath "$OPTARG");;
|
||||
i) P12_INSTALL_FILE=$(realpath "$OPTARG");;
|
||||
p) P12_PASSWORD="$OPTARG";;
|
||||
e) ENTITLEMENTS_FILE=$(realpath "$OPTARG");;
|
||||
n) NOTARIZE=1;;
|
||||
j) API_KEY_FILE=$(realpath "$OPTARG");;
|
||||
\?) usage;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "$SIGN" ] && { [ -z "$P12_APP_FILE" ] || [ -z "$P12_INSTALL_FILE" ] || [ -z "$P12_PASSWORD" ]; }; then
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ -n "$NOTARIZE" ] && [ -z "$API_KEY_FILE" ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
VERSION=$(build_tools/git_version_gen.sh --stdout 2>/dev/null)
|
||||
|
||||
echo "Version is $VERSION"
|
||||
|
||||
PKGDIR=$(mktemp -d)
|
||||
echo "$PKGDIR"
|
||||
|
||||
SRC_DIR=$PWD
|
||||
OUTPUT_PATH=${FISH_ARTEFACT_PATH:-~/fish_built}
|
||||
|
||||
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.
|
||||
# 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.
|
||||
# Note CMAKE_OSX_ARCHITECTURES is still relevant for the Mac app.
|
||||
{ cd "$PKGDIR/build_arm64" \
|
||||
&& do_cmake -DRust_CARGO_TARGET=aarch64-apple-darwin \
|
||||
&& env $ARM64_DEPLOY_TARGET make VERBOSE=1 -j 12 \
|
||||
&& 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.
|
||||
{ cd "$PKGDIR/build_x86_64" \
|
||||
&& do_cmake -DRust_CARGO_TARGET=x86_64-apple-darwin \
|
||||
&& env $X86_64_DEPLOY_TARGET make VERBOSE=1 -j 12; }
|
||||
|
||||
# Fatten them up.
|
||||
for FILE in "$PKGDIR"/root/usr/local/bin/*; do
|
||||
X86_FILE="$PKGDIR/build_x86_64/$(basename "$FILE")"
|
||||
rcodesign macho-universal-create --output "$FILE" "$FILE" "$X86_FILE"
|
||||
chmod 755 "$FILE"
|
||||
done
|
||||
|
||||
if test -n "$SIGN"; then
|
||||
echo "Signing executables"
|
||||
ARGS=(
|
||||
--p12-file "$P12_APP_FILE"
|
||||
--p12-password "$P12_PASSWORD"
|
||||
--code-signature-flags runtime
|
||||
--for-notarization
|
||||
)
|
||||
if [ -n "$ENTITLEMENTS_FILE" ]; then
|
||||
ARGS+=(--entitlements-xml-file "$ENTITLEMENTS_FILE")
|
||||
fi
|
||||
for FILE in "$PKGDIR"/root/usr/local/bin/*; do
|
||||
(set +x; rcodesign sign "${ARGS[@]}" "$FILE")
|
||||
done
|
||||
fi
|
||||
|
||||
pkgbuild --scripts "$SRC_DIR/build_tools/osx_package_scripts" --root "$PKGDIR/root/" --identifier 'com.ridiculousfish.fish-shell-pkg' --version "$VERSION" "$PKGDIR/intermediates/fish.pkg"
|
||||
productbuild --package-path "$PKGDIR/intermediates" --distribution "$SRC_DIR/build_tools/osx_distribution.xml" --resources "$SRC_DIR/build_tools/osx_package_resources/" "$OUTPUT_PATH/fish-$VERSION.pkg"
|
||||
|
||||
if test -n "$SIGN"; then
|
||||
echo "Signing installer"
|
||||
ARGS=(
|
||||
--p12-file "$P12_INSTALL_FILE"
|
||||
--p12-password "$P12_PASSWORD"
|
||||
--code-signature-flags runtime
|
||||
--for-notarization
|
||||
)
|
||||
(set +x; rcodesign sign "${ARGS[@]}" "$OUTPUT_PATH/fish-$VERSION.pkg")
|
||||
fi
|
||||
|
||||
# Make the app
|
||||
(cd "$PKGDIR/build_arm64" && env $ARM64_DEPLOY_TARGET make -j 12 fish_macapp)
|
||||
(cd "$PKGDIR/build_x86_64" && env $X86_64_DEPLOY_TARGET make -j 12 fish_macapp)
|
||||
|
||||
# Make the app's /usr/local/bin binaries universal. Note fish.app/Contents/MacOS/fish already is, courtesy of CMake.
|
||||
cd "$PKGDIR/build_arm64"
|
||||
for FILE in fish.app/Contents/Resources/base/usr/local/bin/*; do
|
||||
X86_FILE="$PKGDIR/build_x86_64/fish.app/Contents/Resources/base/usr/local/bin/$(basename "$FILE")"
|
||||
rcodesign macho-universal-create --output "$FILE" "$FILE" "$X86_FILE"
|
||||
|
||||
# macho-universal-create screws up the permissions.
|
||||
chmod 755 "$FILE"
|
||||
done
|
||||
|
||||
if test -n "$SIGN"; then
|
||||
echo "Signing app"
|
||||
ARGS=(
|
||||
--p12-file "$P12_APP_FILE"
|
||||
--p12-password "$P12_PASSWORD"
|
||||
--code-signature-flags runtime
|
||||
--for-notarization
|
||||
)
|
||||
if [ -n "$ENTITLEMENTS_FILE" ]; then
|
||||
ARGS+=(--entitlements-xml-file "$ENTITLEMENTS_FILE")
|
||||
fi
|
||||
(set +x; rcodesign sign "${ARGS[@]}" "fish.app")
|
||||
|
||||
fi
|
||||
|
||||
cp -R "fish.app" "$OUTPUT_PATH/fish-$VERSION.app"
|
||||
cd "$OUTPUT_PATH"
|
||||
|
||||
# Maybe notarize.
|
||||
if test -n "$NOTARIZE"; then
|
||||
echo "Notarizing"
|
||||
rcodesign notarize --staple --wait --max-wait-seconds 1800 --api-key-file "$API_KEY_FILE" "$OUTPUT_PATH/fish-$VERSION.pkg"
|
||||
rcodesign notarize --staple --wait --max-wait-seconds 1800 --api-key-file "$API_KEY_FILE" "$OUTPUT_PATH/fish-$VERSION.app"
|
||||
fi
|
||||
|
||||
# Zip it up.
|
||||
zip -r "fish-$VERSION.app.zip" "fish-$VERSION.app" && rm -Rf "fish-$VERSION.app"
|
||||
|
||||
rm -rf "$PKGDIR"
|
||||
@@ -1 +0,0 @@
|
||||
make_macos_pkg.sh
|
||||
39
build_tools/make_pkg.sh
Executable file
39
build_tools/make_pkg.sh
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Script to produce an OS X installer .pkg and .app(.zip)
|
||||
|
||||
VERSION=$(git describe --always --dirty 2>/dev/null)
|
||||
if test -z "$VERSION" ; then
|
||||
echo "Could not get version from git"
|
||||
if test -f version; then
|
||||
VERSION=$(cat version)
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Version is $VERSION"
|
||||
|
||||
set -x
|
||||
|
||||
#Exit on error
|
||||
set -e
|
||||
|
||||
# Respect MAC_CODESIGN_ID and MAC_PRODUCTSIGN_ID, or default for ad-hoc.
|
||||
# Note the :- means "or default" and the following - is the value.
|
||||
MAC_CODESIGN_ID=${MAC_CODESIGN_ID:--}
|
||||
MAC_PRODUCTSIGN_ID=${MAC_PRODUCTSIGN_ID:--}
|
||||
|
||||
PKGDIR=$(mktemp -d)
|
||||
|
||||
SRC_DIR=$PWD
|
||||
OUTPUT_PATH=${FISH_ARTEFACT_PATH:-~/fish_built}
|
||||
|
||||
mkdir -p "$PKGDIR/build" "$PKGDIR/root" "$PKGDIR/intermediates" "$PKGDIR/dst"
|
||||
{ cd "$PKGDIR/build" && cmake -DMAC_INJECT_GET_TASK_ALLOW=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo -DMAC_CODESIGN_ID="${MAC_CODESIGN_ID}" "$SRC_DIR" && make -j 12 && env DESTDIR="$PKGDIR/root/" make install; }
|
||||
pkgbuild --scripts "$SRC_DIR/build_tools/osx_package_scripts" --root "$PKGDIR/root/" --identifier 'com.ridiculousfish.fish-shell-pkg' --version "$VERSION" "$PKGDIR/intermediates/fish.pkg"
|
||||
productbuild --package-path "$PKGDIR/intermediates" --distribution "$SRC_DIR/build_tools/osx_distribution.xml" --resources "$SRC_DIR/build_tools/osx_package_resources/" "$OUTPUT_PATH/fish-$VERSION.pkg"
|
||||
productsign --sign "${MAC_PRODUCTSIGN_ID}" "$OUTPUT_PATH/fish-$VERSION.pkg" "$OUTPUT_PATH/fish-$VERSION-signed.pkg" && mv "$OUTPUT_PATH/fish-$VERSION-signed.pkg" "$OUTPUT_PATH/fish-$VERSION.pkg"
|
||||
|
||||
# Make the app
|
||||
{ cd "$PKGDIR/build" && make signed_fish_macapp && zip -r "$OUTPUT_PATH/fish-$VERSION.app.zip" fish.app; }
|
||||
|
||||
rm -r "$PKGDIR"
|
||||
@@ -9,44 +9,30 @@
|
||||
# Exit on error
|
||||
set -e
|
||||
|
||||
# We will generate a tarball with a prefix "fish-VERSION"
|
||||
# We wil generate a tarball with a prefix "fish-VERSION"
|
||||
# git can do that automatically for us via git-archive
|
||||
# but to get the documentation in, we need to make a symlink called "fish-VERSION"
|
||||
# and tar from that, so that the documentation gets the right prefix
|
||||
|
||||
# Use Ninja if available, as it automatically parallelises
|
||||
BUILD_TOOL="make"
|
||||
BUILD_GENERATOR="Unix Makefiles"
|
||||
if command -v ninja >/dev/null; then
|
||||
BUILD_TOOL="ninja"
|
||||
BUILD_GENERATOR="Ninja"
|
||||
fi
|
||||
|
||||
# We need GNU tar as that supports the --mtime and --transform options
|
||||
TAR=notfound
|
||||
for try in tar gtar gnutar; do
|
||||
if $try -Pcf /dev/null --mtime now /dev/null >/dev/null 2>&1; then
|
||||
TAR=$try
|
||||
break
|
||||
fi
|
||||
if $try -Pcf /dev/null --mtime now /dev/null >/dev/null 2>&1; then
|
||||
TAR=$try
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$TAR" = "notfound" ]; then
|
||||
echo 'No suitable tar (supporting --mtime) found as tar/gtar/gnutar in PATH'
|
||||
exit 1
|
||||
echo 'No suitable tar (supporting --mtime) found as tar/gtar/gnutar in PATH'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the current directory, which we'll use for symlinks
|
||||
wd="$PWD"
|
||||
|
||||
# Get the version
|
||||
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
|
||||
)
|
||||
# Get the version from git-describe
|
||||
VERSION=$(git describe --dirty 2>/dev/null)
|
||||
|
||||
# The name of the prefix, which is the directory that you get when you untar
|
||||
prefix="fish-$VERSION"
|
||||
@@ -65,16 +51,13 @@ git archive --format=tar --prefix="$prefix"/ HEAD > "$path"
|
||||
PREFIX_TMPDIR=$(mktemp -d)
|
||||
cd "$PREFIX_TMPDIR"
|
||||
echo "$VERSION" > version
|
||||
cmake -G "$BUILD_GENERATOR" -DCMAKE_BUILD_TYPE=Debug "$wd"
|
||||
mkdir $PWD/user_doc/src
|
||||
FISH_SPHINX_BUILD_DATE=$tag_creation_date \
|
||||
FISH_SPHINX_HELP_SECTIONS_OUTPUT=$PWD/user_doc/src/help_sections.rs \
|
||||
$BUILD_TOOL doc
|
||||
cmake "$wd"
|
||||
make doc
|
||||
|
||||
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\//"
|
||||
$TAR_APPEND --no-recursion user_doc
|
||||
$TAR_APPEND user_doc/html user_doc/man user_doc/src/help_sections.rs
|
||||
$TAR_APPEND user_doc/html user_doc/man
|
||||
$TAR_APPEND version
|
||||
|
||||
cd -
|
||||
@@ -83,6 +66,6 @@ rm -r "$PREFIX_TMPDIR"
|
||||
# xz it
|
||||
xz "$path"
|
||||
|
||||
# Output what we did, and the sha256 hash
|
||||
# Output what we did, and the sha1 hash
|
||||
echo "Tarball written to $path".xz
|
||||
openssl dgst -sha256 "$path".xz
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script to generate a tarball of vendored (downloaded) Rust dependencies
|
||||
# and the cargo configuration to ensure they are used
|
||||
# This tarball should be unpacked into a fish source directory
|
||||
# Outputs to $FISH_ARTEFACT_PATH or ~/fish_built by default
|
||||
|
||||
# Exit on error
|
||||
set -e
|
||||
|
||||
# We need GNU tar as that supports the --mtime and --transform options
|
||||
TAR=notfound
|
||||
for try in tar gtar gnutar; do
|
||||
if $try -Pcf /dev/null --mtime now /dev/null >/dev/null 2>&1; then
|
||||
TAR=$try
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$TAR" = "notfound" ]; then
|
||||
echo 'No suitable tar (supporting --mtime) found as tar/gtar/gnutar in PATH'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the current directory, which we'll use for telling Cargo where to find the sources
|
||||
wd="$PWD"
|
||||
|
||||
# Get the version from git-describe
|
||||
VERSION=$(build_tools/git_version_gen.sh --stdout 2>/dev/null)
|
||||
|
||||
# The name of the prefix, which is the directory that you get when you untar
|
||||
prefix="fish-$VERSION"
|
||||
|
||||
# The path where we will output the tar file
|
||||
# Defaults to ~/fish_built
|
||||
path=${FISH_ARTEFACT_PATH:-~/fish_built}/$prefix-vendor.tar
|
||||
|
||||
# Clean up stuff we've written before
|
||||
rm -f "$path" "$path".xz
|
||||
|
||||
# Work in a temporary directory to avoid clobbering the source directory
|
||||
PREFIX_TMPDIR=$(mktemp -d)
|
||||
cd "$PREFIX_TMPDIR"
|
||||
|
||||
mkdir .cargo
|
||||
cargo vendor --manifest-path "$wd/Cargo.toml" > .cargo/config.toml
|
||||
|
||||
tar cfvJ "$path".xz vendor .cargo
|
||||
|
||||
cd -
|
||||
rm -r "$PREFIX_TMPDIR"
|
||||
|
||||
# Output what we did, and the sha256 hash
|
||||
echo "Tarball written to $path".xz
|
||||
openssl dgst -sha256 "$path".xz
|
||||
@@ -1,11 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<installer-gui-script minSpecVersion="1">
|
||||
<title>fish shell</title>
|
||||
<welcome file="welcome.html" mime-type="text/html"/>
|
||||
<welcome file="welcome.rtf"/>
|
||||
<background file="terminal_logo.png" scaling="proportional" alignment="bottomleft"/>
|
||||
<pkg-ref id="com.ridiculousfish.fish-shell-pkg"/>
|
||||
<options hostArchitectures="arm64,x86_64" rootVolumeOnly="true"/>
|
||||
<options customize="never" require-scripts="true"/>
|
||||
<options customize="never" require-scripts="false"/>
|
||||
<choices-outline>
|
||||
<line choice="default">
|
||||
<line choice="com.ridiculousfish.fish-shell-pkg"/>
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
font-family: system-ui, -apple-system, "Helvetica Neue", sans-serif;
|
||||
font-size: 10pt;
|
||||
}
|
||||
code, tt {
|
||||
font-family: ui-monospace, Menlo, monospace;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<strong>fish</strong> is a smart and user-friendly command line shell. For more information, visit <a href="https://fishshell.com">fishshell.com</a>.
|
||||
</p>
|
||||
<p>
|
||||
<strong>fish</strong> will be installed into <tt>/usr/local/</tt>, and its path will be added to <wbr><tt>/etc/shells</tt> if necessary.
|
||||
</p>
|
||||
<p>
|
||||
Your default shell will <em>not</em> be changed. To make <strong>fish</strong> your login shell after the installation, run:
|
||||
</p>
|
||||
<p>
|
||||
<code>chsh -s /usr/local/bin/fish</code>
|
||||
</p>
|
||||
<p>Enjoy! Bugs can be reported on <a href="https://github.org/fish-shell/fish-shell/">GitHub</a>.</p>
|
||||
</body>
|
||||
</html>
|
||||
26
build_tools/osx_package_resources/welcome.rtf
Normal file
26
build_tools/osx_package_resources/welcome.rtf
Normal file
@@ -0,0 +1,26 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf1485\cocoasubrtf410
|
||||
{\fonttbl\f0\fnil\fcharset0 HelveticaNeue;\f1\fnil\fcharset0 Menlo-Regular;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
{\*\expandedcolortbl;\csgenericrgb\c100000\c100000\c100000;}
|
||||
{\info
|
||||
{\author dlkfjslfjsfdlkfk}}\margl1440\margr1440\vieww10800\viewh8400\viewkind0
|
||||
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0
|
||||
|
||||
\f0\fs30 \cf0 Fish is a smart and user friendly command line shell. For more information, visit {\field{\*\fldinst{HYPERLINK "https://fishshell.com"}}{\fldrslt https://fishshell.com}}\
|
||||
\
|
||||
fish will be installed into
|
||||
\f1\fs26 /usr/local/
|
||||
\f0\fs30 , and fish will be added to
|
||||
\f1\fs26 /etc/shells
|
||||
\f0\fs30 if necessary.\
|
||||
\
|
||||
Your default shell will
|
||||
\i not
|
||||
\i0 be changed. To make fish your default, run:\
|
||||
\
|
||||
|
||||
\f1 chsh -s /usr/local/bin/fish
|
||||
\f0 \
|
||||
\
|
||||
Enjoy!\
|
||||
}
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
if test $# -eq 0
|
||||
then
|
||||
echo "usage: $0 shellname [shellname ...]"
|
||||
echo usage: $0 shellname [shellname ...]
|
||||
exit 1
|
||||
fi
|
||||
|
||||
scriptname=$(basename "$0")
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
scriptname=`basename "$0"`
|
||||
if [[ $UID -ne 0 ]]; then
|
||||
echo "${scriptname} must be run as root"
|
||||
exit 1
|
||||
fi
|
||||
@@ -20,7 +20,6 @@ tmpfile=${file}.tmp
|
||||
|
||||
set -o noclobber
|
||||
|
||||
# shellcheck disable=SC2064
|
||||
trap "rm -f $tmpfile" EXIT
|
||||
|
||||
if ! cat $file > $tmpfile
|
||||
@@ -33,13 +32,15 @@ EOF
|
||||
fi
|
||||
|
||||
# Append a newline if it doesn't exist
|
||||
[ -z "$(tail -c1 "$tmpfile")" ] || echo "" >> "$tmpfile"
|
||||
if [ "$(tail -c1 "$tmpfile"; echo x)" != $'\nx' ]; then
|
||||
echo "" >> "$tmpfile"
|
||||
fi
|
||||
|
||||
for i
|
||||
do
|
||||
if ! grep -q "^${i}$" "$tmpfile"
|
||||
then
|
||||
echo "$i" >> "$tmpfile"
|
||||
echo $i >> "$tmpfile"
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/bin/sh -x
|
||||
|
||||
./add-shell "${DSTVOLUME}"usr/local/bin/fish
|
||||
./add-shell /usr/local/bin/fish > /tmp/fish_postinstall_output.log
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/bin/sh -x
|
||||
|
||||
echo "Removing any previous installation"
|
||||
pkgutil --pkg-info "${INSTALL_PKG_SESSION_ID}" && pkgutil --only-files --files "${INSTALL_PKG_SESSION_ID}" | while read -r installed
|
||||
do rm -v "${DSTVOLUME}${installed}"
|
||||
done
|
||||
echo "... removed"
|
||||
319
build_tools/pexpect_helper.py
Normal file
319
build_tools/pexpect_helper.py
Normal file
@@ -0,0 +1,319 @@
|
||||
"""pexpect_helper provides a wrapper around the pexpect module.
|
||||
|
||||
This module exposes a single class SpawnedProc, which wraps pexpect.spawn().
|
||||
This exposes a pseudo-tty, which fish or another process may talk to.
|
||||
The send() function may be used to send data to fish, and the expect_* family
|
||||
of functions may be used to match what is output to the tty.
|
||||
|
||||
Example usage:
|
||||
sp = SpawnedProc() # this launches fish
|
||||
sp.expect_prompt() # wait for a prompt
|
||||
sp.sendline("echo hello world")
|
||||
sp.expect_prompt("hello world")
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import inspect
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
import pexpect
|
||||
|
||||
# Default timeout for failing to match.
|
||||
TIMEOUT_SECS = 5
|
||||
|
||||
|
||||
def get_prompt_re(counter):
|
||||
""" Return a regular expression for matching a with a given prompt counter. """
|
||||
return re.compile(
|
||||
r"""(?:\r\n?|^) # beginning of line
|
||||
(?:\[.\]\ )? # optional vi mode prompt
|
||||
"""
|
||||
+ (r"prompt\ %d>" % counter), # prompt with counter
|
||||
re.VERBOSE,
|
||||
)
|
||||
|
||||
|
||||
def get_callsite():
|
||||
""" Return a triple (filename, line_number, line_text) of the call site location. """
|
||||
callstack = inspect.getouterframes(inspect.currentframe())
|
||||
for f in callstack:
|
||||
if inspect.getmodule(f.frame) is not Message.MODULE:
|
||||
return (os.path.basename(f.filename), f.lineno, f.code_context)
|
||||
return ("Unknown", -1, "")
|
||||
|
||||
|
||||
def escape(s):
|
||||
""" Escape the string 's' to make it human-understandable. """
|
||||
res = []
|
||||
for c in s:
|
||||
if c == "\n":
|
||||
res.append("\\n")
|
||||
elif c == "\r":
|
||||
res.append("\\r")
|
||||
elif c == "\t":
|
||||
res.append("\\t")
|
||||
elif c.isprintable():
|
||||
res.append(c)
|
||||
else:
|
||||
res.append("\\x{:02x}".format(ord(c)))
|
||||
return "".join(res)
|
||||
|
||||
|
||||
def pexpect_error_type(err):
|
||||
""" Return a human-readable description of a pexpect error type. """
|
||||
if isinstance(err, pexpect.EOF):
|
||||
return "EOF"
|
||||
elif isinstance(err, pexpect.TIMEOUT):
|
||||
return "timeout"
|
||||
else:
|
||||
return "unknown error"
|
||||
|
||||
|
||||
class Message(object):
|
||||
""" Some text either sent-to or received-from the spawned proc.
|
||||
|
||||
Attributes:
|
||||
dir: the message direction, either DIR_INPUT or DIR_OUTPUT
|
||||
filename: the name of the file from which the message was sent
|
||||
text: the text of the messages
|
||||
when: a timestamp of when the message was sent
|
||||
"""
|
||||
|
||||
# Input is input into fish shell ("sent data").
|
||||
DIR_INPUT = " INPUT"
|
||||
|
||||
# Output means output from fish shell ("received data").
|
||||
DIR_OUTPUT = "OUTPUT"
|
||||
|
||||
MODULE = sys.modules[__name__]
|
||||
|
||||
def __init__(self, dir, text, when):
|
||||
""" Construct from a direction, message text and timestamp. """
|
||||
self.dir = dir
|
||||
self.filename, self.lineno, _ = get_callsite()
|
||||
self.text = text
|
||||
self.when = when
|
||||
|
||||
@staticmethod
|
||||
def sent_input(text, when):
|
||||
""" Return an input message with the given text. """
|
||||
return Message(Message.DIR_INPUT, text, when)
|
||||
|
||||
@staticmethod
|
||||
def received_output(text, when):
|
||||
""" Return a output message with the given text. """
|
||||
return Message(Message.DIR_OUTPUT, text, when)
|
||||
|
||||
|
||||
class SpawnedProc(object):
|
||||
""" A process, talking to our ptty. This wraps pexpect.spawn.
|
||||
|
||||
Attributes:
|
||||
colorize: whether error messages should have ANSI color escapes
|
||||
messages: list of Message sent and received, in-order
|
||||
start_time: the timestamp of the first message, or None if none yet
|
||||
spawn: the pexpect.spawn value
|
||||
prompt_counter: the index of the prompt. This cooperates with the fish_prompt
|
||||
function to ensure that each printed prompt is distinct.
|
||||
"""
|
||||
|
||||
def __init__(self, name="fish", timeout=TIMEOUT_SECS, env=os.environ.copy()):
|
||||
""" Construct from a name, timeout, and environment.
|
||||
|
||||
Args:
|
||||
name: the name of the executable to launch, as a key into the
|
||||
environment dictionary. By default this is 'fish' but may be
|
||||
other executables.
|
||||
timeout: A timeout to pass to pexpect. This indicates how long to wait
|
||||
before giving up on some expected output.
|
||||
env: a string->string dictionary, describing the environment variables.
|
||||
"""
|
||||
if name not in env:
|
||||
raise ValueError("'name' variable not found in environment" % name)
|
||||
exe_path = env.get(name)
|
||||
self.colorize = sys.stdout.isatty()
|
||||
self.messages = []
|
||||
self.start_time = None
|
||||
self.spawn = pexpect.spawn(exe_path, env=env, encoding="utf-8", timeout=timeout)
|
||||
self.spawn.delaybeforesend = None
|
||||
self.prompt_counter = 1
|
||||
|
||||
def time_since_first_message(self):
|
||||
""" Return a delta in seconds since the first message, or 0 if this is the first. """
|
||||
now = time.monotonic()
|
||||
if not self.start_time:
|
||||
self.start_time = now
|
||||
return now - self.start_time
|
||||
|
||||
def send(self, s):
|
||||
""" Cover over pexpect.spawn.send().
|
||||
Send the given string to the tty, returning the number of bytes written.
|
||||
"""
|
||||
res = self.spawn.send(s)
|
||||
when = self.time_since_first_message()
|
||||
self.messages.append(Message.sent_input(s, when))
|
||||
return res
|
||||
|
||||
def sendline(self, s):
|
||||
""" Cover over pexpect.spawn.sendline().
|
||||
Send the given string + linesep to the tty, returning the number of bytes written.
|
||||
"""
|
||||
return self.send(s + os.linesep)
|
||||
|
||||
def expect_re(self, pat, pat_desc=None, unmatched=None, **kwargs):
|
||||
""" Cover over pexpect.spawn.expect().
|
||||
Consume all "new" output of self.spawn until the given pattern is matched, or
|
||||
the timeout is reached.
|
||||
Note that output between the current position and the location of the match is
|
||||
consumed as well.
|
||||
The pattern is typically a regular expression in string form, but may also be
|
||||
any of the types accepted by pexpect.spawn.expect().
|
||||
If the 'unmatched' parameter is given, it is printed as part of the error message
|
||||
of any failure.
|
||||
On failure, this prints an error and exits.
|
||||
"""
|
||||
try:
|
||||
res = self.spawn.expect(pat, **kwargs)
|
||||
when = self.time_since_first_message()
|
||||
self.messages.append(
|
||||
Message.received_output(self.spawn.match.group(), when)
|
||||
)
|
||||
return res
|
||||
except pexpect.ExceptionPexpect as err:
|
||||
if not pat_desc:
|
||||
pat_desc = str(pat)
|
||||
self.report_exception_and_exit(pat_desc, unmatched, err)
|
||||
|
||||
def expect_str(self, s, **kwargs):
|
||||
""" Cover over expect_re() which accepts a literal string. """
|
||||
return self.expect_re(re.escape(s), **kwargs)
|
||||
|
||||
def expect_prompt(self, *args, **kwargs):
|
||||
""" Convenience function which matches some text and then a prompt.
|
||||
Match the given positional arguments as expect_re, and then look
|
||||
for a prompt, bumping the prompt counter.
|
||||
Returns None on success, and exits on failure.
|
||||
Example:
|
||||
sp.sendline("echo hello world")
|
||||
sp.expect_prompt("hello world")
|
||||
"""
|
||||
if args:
|
||||
self.expect_re(*args, **kwargs)
|
||||
self.expect_re(
|
||||
get_prompt_re(self.prompt_counter),
|
||||
pat_desc="prompt %d" % self.prompt_counter,
|
||||
)
|
||||
self.prompt_counter += 1
|
||||
|
||||
def report_exception_and_exit(self, pat, unmatched, err):
|
||||
""" Things have gone badly.
|
||||
We have an exception 'err', some pexpect.ExceptionPexpect.
|
||||
Report it to stdout, along with the offending call site.
|
||||
If 'unmatched' is set, print it to stdout.
|
||||
"""
|
||||
colors = self.colors()
|
||||
failtype = pexpect_error_type(err)
|
||||
fmtkeys = {"failtype": failtype, "pat": escape(pat)}
|
||||
fmtkeys.update(**colors)
|
||||
|
||||
filename, lineno, code_context = get_callsite()
|
||||
fmtkeys["filename"] = filename
|
||||
fmtkeys["lineno"] = lineno
|
||||
fmtkeys["code"] = "\n".join(code_context)
|
||||
|
||||
if unmatched:
|
||||
print(
|
||||
"{RED}Error: {NORMAL}{BOLD}{unmatched}{RESET}".format(
|
||||
unmatched=unmatched, **fmtkeys
|
||||
)
|
||||
)
|
||||
print(
|
||||
"{RED}Failed to match pattern:{NORMAL} {BOLD}{pat}{RESET}".format(**fmtkeys)
|
||||
)
|
||||
print(
|
||||
"{filename}:{lineno}: {BOLD}{failtype}{RESET} from {code}".format(**fmtkeys)
|
||||
)
|
||||
|
||||
print("")
|
||||
print("{CYAN}Escaped buffer:{RESET}".format(**colors))
|
||||
print(escape(self.spawn.before))
|
||||
print("")
|
||||
if sys.stdout.isatty():
|
||||
print(
|
||||
"{CYAN}When written to the tty, this looks like:{RESET}".format(
|
||||
**colors
|
||||
)
|
||||
)
|
||||
print("{CYAN}<-------{RESET}".format(**colors))
|
||||
sys.stdout.write(self.spawn.before)
|
||||
sys.stdout.flush()
|
||||
print("{RESET}\n{CYAN}------->{RESET}".format(**colors))
|
||||
|
||||
print("")
|
||||
|
||||
# Show the last 5 messages.
|
||||
print("Last 5 messages:")
|
||||
delta = None
|
||||
for m in self.messages[-5:]:
|
||||
etext = escape(m.text)
|
||||
timestamp = m.when * 1000.0
|
||||
# Use relative timestamps and add a sign.
|
||||
# This assumes a max length of 10^10 milliseconds (115 days) for the initial timestamp,
|
||||
# and 11.5 days for the delta.
|
||||
if delta:
|
||||
timestamp -= delta
|
||||
timestampstr = "{timestamp:+10.2f} ms".format(timestamp=timestamp)
|
||||
else:
|
||||
timestampstr = "{timestamp:10.2f} ms".format(timestamp=timestamp)
|
||||
delta = m.when * 1000.0
|
||||
dir = m.dir
|
||||
print(
|
||||
"{dir} {timestampstr} (Line {lineno}): {BOLD}{etext}{RESET}".format(
|
||||
dir=m.dir,
|
||||
timestampstr=timestampstr,
|
||||
filename=m.filename,
|
||||
lineno=m.lineno,
|
||||
etext=etext,
|
||||
**colors
|
||||
)
|
||||
)
|
||||
print("")
|
||||
sys.exit(1)
|
||||
|
||||
def sleep(self, secs):
|
||||
""" Cover over time.sleep(). """
|
||||
time.sleep(secs)
|
||||
|
||||
def colors(self):
|
||||
""" Return a dictionary mapping color names to ANSI escapes """
|
||||
|
||||
def ansic(n):
|
||||
""" Return either an ANSI escape sequence for a color, or empty string. """
|
||||
return "\033[%dm" % n if self.colorize else ""
|
||||
|
||||
return {
|
||||
"RESET": ansic(0),
|
||||
"BOLD": ansic(1),
|
||||
"NORMAL": ansic(39),
|
||||
"BLACK": ansic(30),
|
||||
"RED": ansic(31),
|
||||
"GREEN": ansic(32),
|
||||
"YELLOW": ansic(33),
|
||||
"BLUE": ansic(34),
|
||||
"MAGENTA": ansic(35),
|
||||
"CYAN": ansic(36),
|
||||
"LIGHTGRAY": ansic(37),
|
||||
"DARKGRAY": ansic(90),
|
||||
"LIGHTRED": ansic(91),
|
||||
"LIGHTGREEN": ansic(92),
|
||||
"LIGHTYELLOW": ansic(93),
|
||||
"LIGHTBLUE": ansic(94),
|
||||
"LIGHTMAGENTA": ansic(95),
|
||||
"LIGHTCYAN": ansic(96),
|
||||
"WHITE": ansic(97),
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
workspace_root=$(dirname "$0")/..
|
||||
|
||||
relnotes_tmp=$(mktemp -d)
|
||||
mkdir -p "$relnotes_tmp/fake-workspace" "$relnotes_tmp/out"
|
||||
(
|
||||
cd "$workspace_root"
|
||||
cp -r doc_src CONTRIBUTING.rst README.rst "$relnotes_tmp/fake-workspace"
|
||||
)
|
||||
version=$(sed 's,^fish \(\S*\) .*,\1,; 1q' "$workspace_root/CHANGELOG.rst")
|
||||
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"
|
||||
git for-each-ref --format='%(objecttype) %(refname:strip=2)' refs/tags |
|
||||
awk '/tag/ {print $2}' | sort --version-sort |
|
||||
grep -vxF "$(git describe)" | tail -1
|
||||
)
|
||||
minor_version=${version%.*}
|
||||
previous_minor_version=${previous_version%.*}
|
||||
if [ "$minor_version" != "$previous_minor_version" ]; then
|
||||
add_stats=true
|
||||
fi
|
||||
} fi
|
||||
{
|
||||
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() {
|
||||
comm "$@" "$relnotes_tmp/committers-then" "$relnotes_tmp/committers-now"
|
||||
}
|
||||
(
|
||||
cd "$workspace_root"
|
||||
ExtractCommitters "$previous_version" | sort -u >"$relnotes_tmp/committers-then"
|
||||
ExtractCommitters "$previous_version".. | sort -u >"$relnotes_tmp/committers-now"
|
||||
ListCommitters -13 >"$relnotes_tmp/committers-new"
|
||||
ListCommitters -12 >"$relnotes_tmp/committers-returning"
|
||||
num_commits=$(git log --no-merges --format=%H "$previous_version".. | wc -l)
|
||||
num_authors=$(wc -l <"$relnotes_tmp/committers-now")
|
||||
num_new_authors=$(wc -l <"$relnotes_tmp/committers-new")
|
||||
printf %s \
|
||||
"This release comprises $num_commits commits since $previous_version," \
|
||||
" contributed by $num_authors authors, $num_new_authors of which are new committers."
|
||||
echo
|
||||
echo
|
||||
)
|
||||
} fi
|
||||
|
||||
printf '%s\n' "$(awk <"$workspace_root/CHANGELOG.rst" '
|
||||
NR <= 2 || /^\.\. ignore / { next }
|
||||
/^===/ { exit }
|
||||
{ print }
|
||||
' | sed '$d')" |
|
||||
sed -e '$s/^----*$//' # Remove spurious transitions at the end of the document.
|
||||
|
||||
if $add_stats; then {
|
||||
JoinEscaped() {
|
||||
LC_CTYPE=C.UTF-8 sed 's/\S/\\&/g' |
|
||||
awk '
|
||||
NR != 1 { printf ",\n" }
|
||||
{ printf "%s", $0 }
|
||||
END { printf "\n" }
|
||||
'
|
||||
}
|
||||
echo ""
|
||||
echo "---"
|
||||
echo ""
|
||||
echo "Thanks to everyone who contributed through issue discussions, code reviews, or code changes."
|
||||
echo
|
||||
printf "Welcome our new committers: "
|
||||
JoinEscaped <"$relnotes_tmp/committers-new"
|
||||
echo
|
||||
printf "Welcome back our returning committers: "
|
||||
JoinEscaped <"$relnotes_tmp/committers-returning"
|
||||
} fi
|
||||
echo
|
||||
echo "---"
|
||||
echo
|
||||
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 '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
|
||||
|
||||
sphinx-build >&2 -j auto \
|
||||
-W -E -b markdown -c "$workspace_root/doc_src" \
|
||||
-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_uri_doc_suffix=".html" \
|
||||
-D markdown_flavor=github \
|
||||
"$@"
|
||||
|
||||
# Skip changelog header
|
||||
sed -n 1p "$relnotes_tmp/out/relnotes.md" | grep -Fxq "# Release notes"
|
||||
sed -n 2p "$relnotes_tmp/out/relnotes.md" | grep -Fxq ''
|
||||
sed 1,2d "$relnotes_tmp/out/relnotes.md"
|
||||
|
||||
rm -r "$relnotes_tmp"
|
||||
@@ -1,283 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
{
|
||||
|
||||
set -ex
|
||||
|
||||
version=$1
|
||||
repository_owner=fish-shell
|
||||
remote=origin
|
||||
if [ -n "$2" ]; then
|
||||
set -u
|
||||
repository_owner=$2
|
||||
remote=$3
|
||||
set +u
|
||||
[ $# -eq 3 ]
|
||||
fi
|
||||
|
||||
[ -n "$version" ]
|
||||
|
||||
for tool in \
|
||||
bundle \
|
||||
diff \
|
||||
gh \
|
||||
gpg \
|
||||
jq \
|
||||
ruby \
|
||||
tar \
|
||||
timeout \
|
||||
uv \
|
||||
; do
|
||||
if ! command -v "$tool" >/dev/null; then
|
||||
echo >&2 "$0: missing command: $1"
|
||||
exit 1
|
||||
fi
|
||||
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")/.."
|
||||
fish_site=$repo_root/../fish-site
|
||||
fish_site_repo=git@github.com:$repository_owner/fish-site
|
||||
|
||||
for path in . "$fish_site"
|
||||
do
|
||||
if ! git -C "$path" diff HEAD --quiet ||
|
||||
git ls-files --others --exclude-standard | grep .; then
|
||||
echo >&2 "$0: index and worktree must be clean"
|
||||
exit 1
|
||||
fi
|
||||
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
|
||||
echo >&2 "$0: tag $version already exists"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
integration_branch=$(
|
||||
git for-each-ref --points-at=HEAD 'refs/heads/Integration_*' \
|
||||
--format='%(refname:strip=2)'
|
||||
)
|
||||
[ -n "$integration_branch" ] ||
|
||||
git merge-base --is-ancestor $remote/master HEAD
|
||||
|
||||
sed -n 1p CHANGELOG.rst | grep -q '^fish .*(released .*)$'
|
||||
sed -n 2p CHANGELOG.rst | grep -q '^===*$'
|
||||
|
||||
changelog_title="fish $version (released $(date +'%B %d, %Y'))"
|
||||
sed -i \
|
||||
-e "1c$changelog_title" \
|
||||
-e "2c$(printf %s "$changelog_title" | sed s/./=/g)" \
|
||||
CHANGELOG.rst
|
||||
|
||||
CommitVersion() {
|
||||
sed -i "s/^version = \".*\"/version = \"$1\"/g" Cargo.toml
|
||||
cargo fetch --offline
|
||||
git add CHANGELOG.rst Cargo.toml Cargo.lock
|
||||
git commit -m "$2
|
||||
|
||||
Created by ./build_tools/release.sh $version"
|
||||
}
|
||||
|
||||
CommitVersion "$version" "Release $version"
|
||||
|
||||
git -c "user.signingKey=$committer" \
|
||||
tag --sign --message="Release $version" $version
|
||||
|
||||
git push $remote $version
|
||||
|
||||
TIMEOUT=
|
||||
gh() {
|
||||
command ${TIMEOUT:+timeout $TIMEOUT} \
|
||||
gh --repo "$repository_owner/fish-shell" "$@"
|
||||
}
|
||||
|
||||
gh workflow run release.yml --ref="$version" \
|
||||
--raw-field="version=$version"
|
||||
|
||||
run_id=
|
||||
while [ -z "$run_id" ] && sleep 5
|
||||
do
|
||||
run_id=$(gh run list \
|
||||
--json=databaseId --jq=.[].databaseId \
|
||||
--workflow=release.yml --limit=1 \
|
||||
--commit="$(git rev-parse "$version^{commit}")")
|
||||
done
|
||||
|
||||
# Update fishshell.com
|
||||
tag_oid=$(git rev-parse "$version")
|
||||
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
|
||||
# have write access to the fish-shell repository. Unless we are fine
|
||||
# publishing the release at this point, we should at least fail if
|
||||
# "gh" doesn't have write access.
|
||||
while ! \
|
||||
gh release download "$version" --dir="$tmpdir" \
|
||||
--pattern="$fish_tar_xz"
|
||||
do
|
||||
TIMEOUT=30 gh run watch "$run_id" ||:
|
||||
sleep 5
|
||||
done
|
||||
actual_tag_oid=$(git ls-remote "$remote" |
|
||||
awk '$2 == "refs/tags/'"$version"'" { print $1 }')
|
||||
[ "$tag_oid" = "$actual_tag_oid" ]
|
||||
|
||||
(
|
||||
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() {
|
||||
rm -rf "$fish_site/site/docs/$1"
|
||||
cp -r "$tmpdir/fish-$version/user_doc/html" "$fish_site/site/docs/$1"
|
||||
git -C $fish_site add "site/docs/$1"
|
||||
}
|
||||
minor_version=${version%.*}
|
||||
CopyDocs "$minor_version"
|
||||
latest_release=$(
|
||||
releases=$(git tag | grep '^[0-9]*\.[0-9]*\.[0-9]*.*' |
|
||||
sed $(: "De-prioritize release candidates (1.2.3-rc0)") \
|
||||
's/-/~/g' | LC_ALL=C sort --version-sort)
|
||||
printf %s\\n "$releases" | tail -1
|
||||
)
|
||||
if [ "$version" = "$latest_release" ]; then
|
||||
CopyDocs current
|
||||
fi
|
||||
rm -rf "$tmpdir"
|
||||
(
|
||||
cd "$fish_site"
|
||||
make
|
||||
git add -u
|
||||
git add docs
|
||||
if git ls-files --others --exclude-standard | grep .; then
|
||||
exit 1
|
||||
fi
|
||||
git commit --message="$(printf %s "\
|
||||
| Release $version (docs)
|
||||
|
|
||||
| Created by ../fish-shell/build_tools/release.sh
|
||||
" | sed 's,^\s*| \?,,')"
|
||||
)
|
||||
|
||||
gh_api_repo() {
|
||||
path=$1
|
||||
shift
|
||||
command gh api \
|
||||
-H "Accept: application/vnd.github+json" \
|
||||
-H "X-GitHub-Api-Version: 2022-11-28" \
|
||||
"/repos/$repository_owner/fish-shell/$path" \
|
||||
"$@"
|
||||
}
|
||||
|
||||
# Approve macos-codesign
|
||||
# TODO what if current user can't approve?
|
||||
gh_pending_deployments() {
|
||||
gh_api_repo "actions/runs/$run_id/pending_deployments" "$@"
|
||||
}
|
||||
while {
|
||||
environment_id=$(gh_pending_deployments | jq .[].environment.id)
|
||||
[ -z "$environment_id" ]
|
||||
}
|
||||
do
|
||||
sleep 5
|
||||
done
|
||||
echo '
|
||||
{
|
||||
"environment_ids": ['"$environment_id"'],
|
||||
"state": "approved",
|
||||
"comment": "Approved via ./build_tools/release.sh"
|
||||
}
|
||||
' |
|
||||
gh_pending_deployments --method POST --input=-
|
||||
|
||||
# Await completion.
|
||||
gh run watch "$run_id"
|
||||
|
||||
while {
|
||||
! draft=$(gh release view "$version" --json=isDraft --jq=.isDraft) \
|
||||
|| [ "$draft" = true ]
|
||||
}
|
||||
do
|
||||
sleep 20
|
||||
done
|
||||
|
||||
(
|
||||
cd "$fish_site"
|
||||
make new-release
|
||||
git add -u
|
||||
git add docs
|
||||
if git ls-files --others --exclude-standard | grep .; then
|
||||
exit 1
|
||||
fi
|
||||
git commit --message="$(printf %s "\
|
||||
| Release $version (release list update)
|
||||
|
|
||||
| Created by ../fish-shell/build_tools/release.sh
|
||||
" | sed 's,^\s*| \?,,')"
|
||||
# This takes care to support remote names that are different from
|
||||
# fish-shell remote name. Also, support detached HEAD state.
|
||||
git push "$fish_site_repo" HEAD:master
|
||||
)
|
||||
|
||||
if [ -n "$integration_branch" ]; then {
|
||||
git push $remote "$version^{commit}":refs/heads/$integration_branch
|
||||
} else {
|
||||
changelog=$(cat - CHANGELOG.rst <<EOF
|
||||
fish ?.?.? (released ???)
|
||||
=========================
|
||||
|
||||
EOF
|
||||
)
|
||||
printf %s\\n "$changelog" >CHANGELOG.rst
|
||||
CommitVersion ${version}-snapshot "start new cycle"
|
||||
git push $remote HEAD:master
|
||||
} fi
|
||||
|
||||
milestone_version="$(
|
||||
if echo "$version" | grep -q '\.0$'; then
|
||||
echo "$minor_version"
|
||||
else
|
||||
echo "$version"
|
||||
fi
|
||||
)"
|
||||
milestone_number=$(
|
||||
gh_api_repo milestones?state=open |
|
||||
jq --arg name "fish $1" '
|
||||
.[] | select(.title == $name) | .number
|
||||
'
|
||||
)
|
||||
gh_api_repo milestones/"$milestone_number" --method PATCH \
|
||||
--raw-field state=closed
|
||||
|
||||
next_minor_version=$(echo "$minor_version" |
|
||||
awk -F. '{ printf "%s.%s", $1, $2+1 }')
|
||||
if [ -z "$(milestone_number "$next_minor_version")" ]; then
|
||||
gh_api_repo milestones --method POST \
|
||||
--raw-field title="fish $next_minor_version"
|
||||
fi
|
||||
|
||||
exit
|
||||
|
||||
}
|
||||
@@ -1,123 +1,110 @@
|
||||
#!/usr/bin/env fish
|
||||
#
|
||||
# This runs Python files, fish scripts (*.fish), and Rust files
|
||||
# through their respective code formatting programs.
|
||||
# This runs C++ files and fish scripts (*.fish) through their respective code
|
||||
# formatting programs.
|
||||
#
|
||||
# `--all`: Format all eligible files instead of the ones specified as arguments.
|
||||
# `--check`: Instead of reformatting, fail if a file is not formatted correctly.
|
||||
# `--force`: Proceed without asking if uncommitted changes are detected.
|
||||
# Only relevant if `--all` is specified but `--check` is not specified.
|
||||
|
||||
set -l git_clang_format no
|
||||
set -l c_files
|
||||
set -l fish_files
|
||||
set -l python_files
|
||||
set -l rust_files
|
||||
set -l all no
|
||||
|
||||
argparse all check force -- $argv
|
||||
or exit $status
|
||||
|
||||
if set -l -q _flag_all
|
||||
if test "$argv[1]" = --all
|
||||
set all yes
|
||||
if set -q argv[1]
|
||||
echo "Unexpected arguments: '$argv'"
|
||||
exit 1
|
||||
end
|
||||
set -e argv[1]
|
||||
end
|
||||
|
||||
set -l workspace_root (status dirname)/..
|
||||
if set -q argv[1]
|
||||
echo "Unexpected arguments: '$argv'"
|
||||
exit 1
|
||||
end
|
||||
|
||||
if test $all = yes
|
||||
if not set -l -q _flag_force; and not set -l -q _flag_check
|
||||
# Potential for false positives: Not all fish files are formatted, see the `fish_files`
|
||||
# definition below.
|
||||
set -l relevant_uncommitted_changes (git status --porcelain --short --untracked-files=all | sed -e 's/^ *[^ ]* *//' | grep -E '.*\.(fish|py|rs)$')
|
||||
if set -q relevant_uncommitted_changes[1]
|
||||
for changed_file in $relevant_uncommitted_changes
|
||||
echo $changed_file
|
||||
end
|
||||
echo
|
||||
echo 'You have uncommitted changes (listed above). Are you sure you want to restyle?'
|
||||
read -P 'y/N? ' -n1 -l ans
|
||||
if not string match -qi y -- $ans
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
set -l files (git status --porcelain --short --untracked-files=all | sed -e 's/^ *[^ ]* *//')
|
||||
if set -q files[1]
|
||||
echo
|
||||
echo You have uncommitted changes. Cowardly refusing to restyle the entire code base.
|
||||
echo
|
||||
exit 1
|
||||
end
|
||||
set fish_files $workspace_root/{benchmarks,build_tools,etc,share}/**.fish
|
||||
set python_files $workspace_root
|
||||
set c_files src/*.h src/*.cpp src/*.c
|
||||
set fish_files (printf '%s\n' share/***.fish)
|
||||
set python_files **.py
|
||||
else
|
||||
# Format the files specified as arguments.
|
||||
set -l files $argv
|
||||
# We haven't been asked to reformat all the source. If there are uncommitted changes reformat
|
||||
# those using `git clang-format`. Else reformat the files in the most recent commit.
|
||||
# Select (cached files) (modified but not cached, and untracked files)
|
||||
set -l files (git diff-index --cached HEAD --name-only) (git ls-files --exclude-standard --others --modified)
|
||||
if set -q files[1]
|
||||
set git_clang_format yes
|
||||
else
|
||||
# No pending changes so lint the files in the most recent commit.
|
||||
set files (git diff-tree --no-commit-id --name-only -r HEAD)
|
||||
end
|
||||
|
||||
# Extract just the C/C++ files that exist.
|
||||
set c_files
|
||||
for file in (string match -r '^.*\.(?:c|cpp|h)$' -- $files)
|
||||
test -f $file; and set c_files $c_files $file
|
||||
end
|
||||
# Extract just the fish files.
|
||||
set fish_files (string match -r '^.*\.fish$' -- $files)
|
||||
set python_files (string match -r '^.*\.py$' -- $files)
|
||||
set rust_files (string match -r '^.*\.rs$' -- $files)
|
||||
end
|
||||
|
||||
set -l red (set_color red)
|
||||
set -l green (set_color green)
|
||||
set -l yellow (set_color yellow)
|
||||
set -l blue (set_color blue)
|
||||
set -l normal (set_color normal)
|
||||
|
||||
function die -V red -V normal
|
||||
echo $red$argv[1]$normal
|
||||
exit 1
|
||||
# Run the C++ reformatter if we have any C++ files.
|
||||
if set -q c_files[1]
|
||||
if test $git_clang_format = yes
|
||||
if type -q git-clang-format
|
||||
echo === Running "$red"git-clang-format"$normal"
|
||||
git add $c_files
|
||||
git-clang-format
|
||||
else
|
||||
echo
|
||||
echo 'WARNING: Cannot find git-clang-format command'
|
||||
echo
|
||||
end
|
||||
else if type -q clang-format
|
||||
echo === Running "$red"clang-format"$normal"
|
||||
for file in $c_files
|
||||
cp $file $file.new # preserves mode bits
|
||||
clang-format $file >$file.new
|
||||
if cmp --quiet $file $file.new
|
||||
rm $file.new
|
||||
else
|
||||
echo $file was NOT correctly formatted
|
||||
mv $file.new $file
|
||||
end
|
||||
end
|
||||
else
|
||||
echo
|
||||
echo 'WARNING: Cannot find clang-format command'
|
||||
echo
|
||||
end
|
||||
end
|
||||
|
||||
# Run the fish reformatter if we have any fish files.
|
||||
if set -q fish_files[1]
|
||||
if not type -q fish_indent
|
||||
echo
|
||||
echo $yellow'Could not find `fish_indent` in `$PATH`.'$normal
|
||||
exit 127
|
||||
make fish_indent
|
||||
set PATH . $PATH
|
||||
end
|
||||
echo === Running "$green"fish_indent"$normal"
|
||||
if set -l -q _flag_check
|
||||
fish_indent --check -- $fish_files
|
||||
or die "Fish files are not formatted correctly."
|
||||
else
|
||||
fish_indent -w -- $fish_files
|
||||
end
|
||||
fish_indent -w -- $fish_files
|
||||
end
|
||||
|
||||
if set -q python_files[1]
|
||||
if not type -q ruff
|
||||
if not type -q black
|
||||
echo
|
||||
echo Please install "`black`" to style python
|
||||
echo
|
||||
echo $yellow'Please install `ruff` to style python'$normal
|
||||
exit 127
|
||||
end
|
||||
echo === Running "$green"ruff format"$normal"
|
||||
if set -l -q _flag_check
|
||||
ruff format --check $python_files
|
||||
or die "Python files are not formatted correctly."
|
||||
else
|
||||
ruff format $python_files
|
||||
end
|
||||
end
|
||||
|
||||
if test $all = yes; or set -q rust_files[1]
|
||||
if not cargo fmt --version >/dev/null
|
||||
echo
|
||||
echo $yellow'Please install "rustfmt" to style Rust, e.g. via:'
|
||||
echo "rustup component add rustfmt"$normal
|
||||
exit 127
|
||||
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
|
||||
rustfmt --check --files-with-diff $rust_files
|
||||
end
|
||||
or die "Rust files are not formatted correctly."
|
||||
else
|
||||
if test $all = yes
|
||||
cargo fmt --all
|
||||
else
|
||||
rustfmt $rust_files
|
||||
end
|
||||
echo === Running "$blue"black"$normal"
|
||||
black $python_files
|
||||
end
|
||||
end
|
||||
|
||||
3
build_tools/ubsan.blacklist
Normal file
3
build_tools/ubsan.blacklist
Normal file
@@ -0,0 +1,3 @@
|
||||
# Ubuntu Xenial (used for Travis CI builds) ships libstdc++ 5.4.0 which contains undefined behaviour
|
||||
# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63345
|
||||
object-size:*bits/stl_tree.h
|
||||
@@ -1,33 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,154 +0,0 @@
|
||||
#!/usr/bin/env fish
|
||||
|
||||
# Updates the files used for gettext translations.
|
||||
# By default, the whole xgettext + msgmerge pipeline runs,
|
||||
# which extracts the messages from the source files into $template_file,
|
||||
# and updates the PO files for each language from that.
|
||||
#
|
||||
# Use cases:
|
||||
# For developers:
|
||||
# - Run with no args to update all PO files after making changes to Rust/fish sources.
|
||||
# For translators:
|
||||
# - Specify the language you want to work on as an argument, which must be a file in the po/
|
||||
# directory. You can specify a language which does not have translations yet by specifying the
|
||||
# name of a file which does not yet exist. Make sure to follow the naming convention.
|
||||
# For testing:
|
||||
# - Specify `--dry-run` to see if any updates to the PO files would by applied by this script.
|
||||
# If this flag is specified, the script will exit with an error if there are outstanding
|
||||
# changes, and will display the diff. Do not specify other flags if `--dry-run` is specified.
|
||||
#
|
||||
# Specify `--use-existing-template=FILE` to prevent running cargo for extracting an up-to-date
|
||||
# version of the localized strings. This flag is intended for testing setups which make it
|
||||
# inconvenient to run cargo here, but run it in an earlier step to ensure up-to-date values.
|
||||
# This argument is passed on to the `fish_xgettext.fish` script and has no other uses.
|
||||
# `FILE` must be the path to a gettext template file generated from our compilation process.
|
||||
# It can be obtained by running:
|
||||
# set -l FILE (mktemp)
|
||||
# FISH_GETTEXT_EXTRACTION_FILE=$FILE cargo check --features=gettext-extract
|
||||
|
||||
# The sort utility is locale-sensitive.
|
||||
# Ensure that sorting output is consistent by setting LC_ALL here.
|
||||
set -gx LC_ALL C.UTF-8
|
||||
|
||||
set -l build_tools (status dirname)
|
||||
set -l po_dir $build_tools/../po
|
||||
|
||||
set -l extract
|
||||
|
||||
argparse dry-run use-existing-template= -- $argv
|
||||
or exit $status
|
||||
|
||||
if test -z $argv[1]
|
||||
# Update everything if not specified otherwise.
|
||||
set -g po_files $po_dir/*.po
|
||||
else
|
||||
set -l po_dir_id (stat --format='%d:%i' -- $po_dir)
|
||||
for arg in $argv
|
||||
set -l arg_dir_id (stat --format='%d:%i' -- (dirname $arg) 2>/dev/null)
|
||||
if test $po_dir_id != "$arg_dir_id"
|
||||
echo "Argument $arg is not a file in the directory $(realpath $po_dir)."
|
||||
echo "Non-option arguments must specify paths to files in this directory."
|
||||
echo ""
|
||||
echo "If you want to add a new language to the translations not the following:"
|
||||
echo "The filename must identify a language, with a two letter ISO 639-1 language code of the target language (e.g. 'pt' for Portuguese), and use the file extension '.po'."
|
||||
echo "Optionally, you can specify a regional variant (e.g. 'pt_BR')."
|
||||
echo "So valid filenames are of the shape 'll.po' or 'll_CC.po'."
|
||||
exit 1
|
||||
end
|
||||
if not basename $arg | grep -qE '^[a-z]{2,3}(_[A-Z]{2})?\.po$'
|
||||
echo "Filename does not match the expected format ('ll.po' or 'll_CC.po')."
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
set -g po_files $argv
|
||||
end
|
||||
|
||||
set -g template_file (mktemp)
|
||||
# Protect from externally set $tmpdir leaking into this script.
|
||||
set -g tmpdir
|
||||
|
||||
function cleanup_exit
|
||||
set -l exit_status $status
|
||||
|
||||
rm $template_file
|
||||
|
||||
if set -g --query tmpdir[1]
|
||||
rm -r $tmpdir
|
||||
end
|
||||
|
||||
exit $exit_status
|
||||
end
|
||||
|
||||
if set -l --query extract
|
||||
set -l xgettext_args
|
||||
if set -l --query _flag_use_existing_template
|
||||
set xgettext_args --use-existing-template=$_flag_use_existing_template
|
||||
end
|
||||
$build_tools/fish_xgettext.fish $xgettext_args >$template_file
|
||||
or cleanup_exit
|
||||
end
|
||||
|
||||
if set -l --query _flag_dry_run
|
||||
# On a dry run, we do not modify po/ but write to a temporary directory instead and check if
|
||||
# there is a difference between po/ and the tmpdir after re-generating the PO files.
|
||||
set -g tmpdir (mktemp -d)
|
||||
|
||||
# Ensure tmpdir has the same initial state as the po dir.
|
||||
cp -r $po_dir/* $tmpdir
|
||||
end
|
||||
|
||||
# This is used to identify lines which should be set here via $header_lines.
|
||||
# Make sure that this prefix does not appear elsewhere in the file and only contains characters
|
||||
# without special meaning in a sed pattern.
|
||||
set -g header_prefix "# fish-note-sections: "
|
||||
|
||||
function print_header
|
||||
set -l header_lines \
|
||||
"Translations are divided into sections, each starting with a fish-section-* pseudo-message." \
|
||||
"The first few sections are more important." \
|
||||
"Ignore the tier3 sections unless you have a lot of time."
|
||||
for line in $header_lines
|
||||
printf '%s%s\n' $header_prefix $line
|
||||
end
|
||||
end
|
||||
|
||||
function merge_po_files --argument-names template_file po_file
|
||||
msgmerge --no-wrap --update --no-fuzzy-matching --backup=none --quiet \
|
||||
$po_file $template_file
|
||||
or cleanup_exit
|
||||
set -l new_po_file (mktemp) # TODO Remove on failure.
|
||||
# Remove obsolete messages instead of keeping them as #~ entries.
|
||||
and msgattrib --no-wrap --no-obsolete -o $new_po_file $po_file
|
||||
or cleanup_exit
|
||||
|
||||
begin
|
||||
print_header
|
||||
# Paste PO file without old header lines.
|
||||
sed '/^'$header_prefix'/d' $new_po_file
|
||||
end >$po_file
|
||||
rm $new_po_file
|
||||
end
|
||||
|
||||
for po_file in $po_files
|
||||
if set --query tmpdir[1]
|
||||
set po_file $tmpdir/(basename $po_file)
|
||||
end
|
||||
if test -e $po_file
|
||||
merge_po_files $template_file $po_file
|
||||
else
|
||||
begin
|
||||
print_header
|
||||
cat $template_file
|
||||
end >$po_file
|
||||
end
|
||||
end
|
||||
|
||||
if set -g --query tmpdir[1]
|
||||
diff -ur $po_dir $tmpdir
|
||||
or begin
|
||||
echo ERROR: translations in ./po/ are stale. Try running build_tools/update_translations.fish
|
||||
cleanup_exit
|
||||
end
|
||||
end
|
||||
|
||||
cleanup_exit
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/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
|
||||
@@ -1,7 +1,6 @@
|
||||
# Support for benchmarking fish.
|
||||
|
||||
add_custom_target(benchmark
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/benchmarks/driver.sh ${CMAKE_BINARY_DIR}/fish
|
||||
DEPENDS fish
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/benchmarks/driver.sh $<TARGET_FILE:fish>
|
||||
USES_TERMINAL
|
||||
)
|
||||
|
||||
123
cmake/CheckIncludeFiles.cmake
Normal file
123
cmake/CheckIncludeFiles.cmake
Normal file
@@ -0,0 +1,123 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See full license information in
|
||||
# doc_src/license.hdr or https://cmake.org/licensing for details.
|
||||
|
||||
#.rst:
|
||||
# CheckIncludeFiles
|
||||
# -----------------
|
||||
#
|
||||
# Provides a macro to check if a list of one or more header files can
|
||||
# be included together in ``C``.
|
||||
#
|
||||
# .. command:: CHECK_INCLUDE_FILES
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# CHECK_INCLUDE_FILES("<includes>" <variable> [LANGUAGE <language>])
|
||||
#
|
||||
# Check if the given ``<includes>`` list may be included together
|
||||
# in a ``C`` source file and store the result in an internal cache
|
||||
# entry named ``<variable>``. Specify the ``<includes>`` argument
|
||||
# as a :ref:`;-list <CMake Language Lists>` of header file names.
|
||||
#
|
||||
# If LANGUAGE is set, the specified compiler will be used to perform the
|
||||
# check. Acceptable values are C and CXX.
|
||||
#
|
||||
# The following variables may be set before calling this macro to modify
|
||||
# the way the check is run:
|
||||
#
|
||||
# ``CMAKE_REQUIRED_FLAGS``
|
||||
# string of compile command line flags
|
||||
# ``CMAKE_REQUIRED_DEFINITIONS``
|
||||
# list of macros to define (-DFOO=bar)
|
||||
# ``CMAKE_REQUIRED_INCLUDES``
|
||||
# list of include directories
|
||||
# ``CMAKE_REQUIRED_QUIET``
|
||||
# execute quietly without messages
|
||||
#
|
||||
# See modules :module:`CheckIncludeFile` and :module:`CheckIncludeFileCXX`
|
||||
# to check for a single header file in ``C`` or ``CXX`` languages.
|
||||
|
||||
macro(CHECK_INCLUDE_FILES INCLUDE VARIABLE)
|
||||
if(NOT DEFINED "${VARIABLE}")
|
||||
set(CMAKE_CONFIGURABLE_FILE_CONTENT "/* */\n")
|
||||
|
||||
if("x${ARGN}" STREQUAL "x")
|
||||
if(CMAKE_C_COMPILER_LOADED)
|
||||
set(_lang C)
|
||||
elseif(CMAKE_CXX_COMPILER_LOADED)
|
||||
set(_lang CXX)
|
||||
else()
|
||||
message(FATAL_ERROR "CHECK_INCLUDE_FILES needs either C or CXX language enabled")
|
||||
endif()
|
||||
elseif("x${ARGN}" MATCHES "^xLANGUAGE;([a-zA-Z]+)$")
|
||||
set(_lang "${CMAKE_MATCH_1}")
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown arguments:\n ${ARGN}\n")
|
||||
endif()
|
||||
|
||||
if(_lang STREQUAL "C")
|
||||
set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckIncludeFiles/${var}.c)
|
||||
elseif(_lang STREQUAL "CXX")
|
||||
set(src ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CheckIncludeFiles/${var}.cpp)
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown language:\n ${_lang}\nSupported languages: C, CXX.\n")
|
||||
endif()
|
||||
|
||||
if(CMAKE_REQUIRED_INCLUDES)
|
||||
set(CHECK_INCLUDE_FILES_INCLUDE_DIRS "-DINCLUDE_DIRECTORIES=${CMAKE_REQUIRED_INCLUDES}")
|
||||
else()
|
||||
set(CHECK_INCLUDE_FILES_INCLUDE_DIRS)
|
||||
endif()
|
||||
set(CHECK_INCLUDE_FILES_CONTENT "/* */\n")
|
||||
set(MACRO_CHECK_INCLUDE_FILES_FLAGS ${CMAKE_REQUIRED_FLAGS})
|
||||
foreach(FILE ${INCLUDE})
|
||||
string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT
|
||||
"#include <${FILE}>\n")
|
||||
endforeach()
|
||||
string(APPEND CMAKE_CONFIGURABLE_FILE_CONTENT
|
||||
"\n\nint main(void){return 0;}\n")
|
||||
configure_file("${CMAKE_ROOT}/Modules/CMakeConfigurableFile.in"
|
||||
"${src}" @ONLY)
|
||||
|
||||
set(_INCLUDE ${INCLUDE}) # remove empty elements
|
||||
if("${_INCLUDE}" MATCHES "^([^;]+);.+;([^;]+)$")
|
||||
list(LENGTH _INCLUDE _INCLUDE_LEN)
|
||||
set(_description "${_INCLUDE_LEN} include files ${CMAKE_MATCH_1}, ..., ${CMAKE_MATCH_2}")
|
||||
elseif("${_INCLUDE}" MATCHES "^([^;]+);([^;]+)$")
|
||||
set(_description "include files ${CMAKE_MATCH_1}, ${CMAKE_MATCH_2}")
|
||||
else()
|
||||
set(_description "include file ${_INCLUDE}")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_REQUIRED_QUIET)
|
||||
message(STATUS "Looking for ${_description}")
|
||||
endif()
|
||||
try_compile(${VARIABLE}
|
||||
${CMAKE_BINARY_DIR}
|
||||
${src}
|
||||
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
|
||||
CMAKE_FLAGS
|
||||
-DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_INCLUDE_FILES_FLAGS}
|
||||
"${CHECK_INCLUDE_FILES_INCLUDE_DIRS}"
|
||||
OUTPUT_VARIABLE OUTPUT)
|
||||
if(${VARIABLE})
|
||||
if(NOT CMAKE_REQUIRED_QUIET)
|
||||
message(STATUS "Looking for ${_description} - found")
|
||||
endif()
|
||||
set(${VARIABLE} 1 CACHE INTERNAL "Have include ${INCLUDE}")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
|
||||
"Determining if files ${INCLUDE} "
|
||||
"exist passed with the following output:\n"
|
||||
"${OUTPUT}\n\n")
|
||||
else()
|
||||
if(NOT CMAKE_REQUIRED_QUIET)
|
||||
message(STATUS "Looking for ${_description} - not found")
|
||||
endif()
|
||||
set(${VARIABLE} "" CACHE INTERNAL "Have includes ${INCLUDE}")
|
||||
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
|
||||
"Determining if files ${INCLUDE} "
|
||||
"exist failed with the following output:\n"
|
||||
"${OUTPUT}\nSource:\n${CMAKE_CONFIGURABLE_FILE_CONTENT}\n")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
209
cmake/ConfigureChecks.cmake
Normal file
209
cmake/ConfigureChecks.cmake
Normal file
@@ -0,0 +1,209 @@
|
||||
# The following defines affect the environment configuration tests are run in:
|
||||
# CMAKE_REQUIRED_DEFINITIONS, CMAKE_REQUIRED_FLAGS, CMAKE_REQUIRED_LIBRARIES,
|
||||
# and CMAKE_REQUIRED_INCLUDES
|
||||
# `wcstod_l` is a GNU-extension, sometimes hidden behind GNU-related defines.
|
||||
# This is the case for at least Cygwin and Newlib.
|
||||
list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE=1)
|
||||
|
||||
if(APPLE)
|
||||
include(CheckCXXCompilerFlag)
|
||||
check_cxx_compiler_flag("-Werror=unguarded-availability" REQUIRES_UNGUARDED_AVAILABILITY)
|
||||
if(REQUIRES_UNGUARDED_AVAILABILITY)
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "-Werror=unguarded-availability")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Try using CMake's own logic to locate curses/ncurses
|
||||
find_package(Curses)
|
||||
if(NOT ${CURSES_FOUND})
|
||||
# CMake has trouble finding platform-specific system libraries
|
||||
# installed to multiarch paths (e.g. /usr/lib/x86_64-linux-gnu)
|
||||
# if not symlinked or passed in as a manual define.
|
||||
message("Falling back to pkg-config for (n)curses detection")
|
||||
include(FindPkgConfig)
|
||||
pkg_search_module(CURSES REQUIRED ncurses curses)
|
||||
set(CURSES_CURSES_LIBRARY ${CURSES_LIBRARIES})
|
||||
set(CURSES_LIBRARY ${CURSES_LIBRARIES})
|
||||
endif()
|
||||
|
||||
# Get threads.
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
# FindThreads < 3.4.0 doesn't work for C++-only projects
|
||||
if(CMAKE_VERSION VERSION_LESS 3.4.0)
|
||||
enable_language(C)
|
||||
endif()
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
# Detect WSL. Does not match against native Windows/WIN32.
|
||||
if (CMAKE_HOST_SYSTEM_VERSION MATCHES ".*-Microsoft")
|
||||
set(WSL 1)
|
||||
endif()
|
||||
|
||||
# Set up the config.h file.
|
||||
set(PACKAGE_NAME "fish")
|
||||
set(PACKAGE_TARNAME "fish")
|
||||
include(CheckCXXSymbolExists)
|
||||
include(CheckIncludeFileCXX)
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckStructHasMember)
|
||||
include(CheckCXXSourceCompiles)
|
||||
include(CheckTypeSize)
|
||||
include(CMakePushCheckState)
|
||||
check_cxx_symbol_exists(backtrace_symbols execinfo.h HAVE_BACKTRACE_SYMBOLS)
|
||||
check_cxx_symbol_exists(clock_gettime time.h HAVE_CLOCK_GETTIME)
|
||||
check_cxx_symbol_exists(ctermid_r stdio.h HAVE_CTERMID_R)
|
||||
check_struct_has_member("struct dirent" d_type dirent.h HAVE_STRUCT_DIRENT_D_TYPE LANGUAGE CXX)
|
||||
check_cxx_symbol_exists(dirfd "sys/types.h;dirent.h" HAVE_DIRFD)
|
||||
check_include_file_cxx(execinfo.h HAVE_EXECINFO_H)
|
||||
check_cxx_symbol_exists(flock sys/file.h HAVE_FLOCK)
|
||||
# futimens is new in OS X 10.13 but is a weak symbol.
|
||||
# Don't assume it exists just because we can link - it may be null.
|
||||
check_cxx_symbol_exists(futimens sys/stat.h HAVE_FUTIMENS)
|
||||
check_cxx_symbol_exists(futimes sys/time.h HAVE_FUTIMES)
|
||||
check_cxx_symbol_exists(getifaddrs ifaddrs.h HAVE_GETIFADDRS)
|
||||
check_cxx_symbol_exists(getpwent pwd.h HAVE_GETPWENT)
|
||||
check_cxx_symbol_exists(getrusage sys/resource.h HAVE_GETRUSAGE)
|
||||
check_cxx_symbol_exists(gettext libintl.h HAVE_GETTEXT)
|
||||
check_cxx_symbol_exists(killpg "sys/types.h;signal.h" HAVE_KILLPG)
|
||||
check_cxx_symbol_exists(lrand48_r stdlib.h HAVE_LRAND48_R)
|
||||
# mkostemp is in stdlib in glibc and FreeBSD, but unistd on macOS
|
||||
check_cxx_symbol_exists(mkostemp "stdlib.h;unistd.h" HAVE_MKOSTEMP)
|
||||
set(HAVE_CURSES_H ${CURSES_HAVE_CURSES_H})
|
||||
set(HAVE_NCURSES_CURSES_H ${CURSES_HAVE_NCURSES_CURSES_H})
|
||||
set(HAVE_NCURSES_H ${CURSES_HAVE_NCURSES_H})
|
||||
if(HAVE_CURSES_H)
|
||||
check_include_files("curses.h;term.h" HAVE_TERM_H)
|
||||
endif()
|
||||
if(NOT HAVE_TERM_H)
|
||||
check_include_file_cxx("ncurses/term.h" HAVE_NCURSES_TERM_H)
|
||||
endif()
|
||||
check_include_file_cxx(siginfo.h HAVE_SIGINFO_H)
|
||||
check_include_file_cxx(spawn.h HAVE_SPAWN_H)
|
||||
check_struct_has_member("struct stat" st_ctime_nsec "sys/stat.h" HAVE_STRUCT_STAT_ST_CTIME_NSEC
|
||||
LANGUAGE CXX)
|
||||
check_struct_has_member("struct stat" st_mtimespec.tv_nsec "sys/stat.h"
|
||||
HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC LANGUAGE CXX)
|
||||
check_struct_has_member("struct stat" st_mtim.tv_nsec "sys/stat.h" HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
||||
LANGUAGE CXX)
|
||||
check_cxx_symbol_exists(sys_errlist stdio.h HAVE_SYS_ERRLIST)
|
||||
check_include_file_cxx(sys/ioctl.h HAVE_SYS_IOCTL_H)
|
||||
check_include_file_cxx(sys/select.h HAVE_SYS_SELECT_H)
|
||||
check_include_files("sys/types.h;sys/sysctl.h" HAVE_SYS_SYSCTL_H)
|
||||
check_include_file_cxx(termios.h HAVE_TERMIOS_H) # Needed for TIOCGWINSZ
|
||||
|
||||
check_cxx_symbol_exists(wcscasecmp wchar.h HAVE_WCSCASECMP)
|
||||
check_cxx_symbol_exists(wcsdup wchar.h HAVE_WCSDUP)
|
||||
check_cxx_symbol_exists(wcslcpy wchar.h HAVE_WCSLCPY)
|
||||
check_cxx_symbol_exists(wcsncasecmp wchar.h HAVE_WCSNCASECMP)
|
||||
check_cxx_symbol_exists(wcsndup wchar.h HAVE_WCSNDUP)
|
||||
|
||||
# These are for compatibility with Solaris 10, which places the following
|
||||
# in the std namespace.
|
||||
if(NOT HAVE_WCSNCASECMP)
|
||||
check_cxx_symbol_exists(std::wcscasecmp wchar.h HAVE_STD__WCSCASECMP)
|
||||
endif()
|
||||
if(NOT HAVE_WCSDUP)
|
||||
check_cxx_symbol_exists(std::wcsdup wchar.h HAVE_STD__WCSDUP)
|
||||
endif()
|
||||
if(NOT HAVE_WCSNCASECMP)
|
||||
check_cxx_symbol_exists(std::wcsncasecmp wchar.h HAVE_STD__WCSNCASECMP)
|
||||
endif()
|
||||
|
||||
# `xlocale.h` is required to find `wcstod_l` in `wchar.h` under FreeBSD,
|
||||
# but it's not present under Linux.
|
||||
check_include_files("xlocale.h" HAVE_XLOCALE_H)
|
||||
if(HAVE_XLOCALE_H)
|
||||
list(APPEND WCSTOD_L_INCLUDES "xlocale.h")
|
||||
endif()
|
||||
list(APPEND WCSTOD_L_INCLUDES "wchar.h")
|
||||
check_cxx_symbol_exists(wcstod_l "${WCSTOD_L_INCLUDES}" HAVE_WCSTOD_L)
|
||||
|
||||
check_cxx_symbol_exists(_sys_errs stdlib.h HAVE__SYS__ERRS)
|
||||
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_EXTRA_INCLUDE_FILES termios.h sys/ioctl.h)
|
||||
check_type_size("struct winsize" STRUCT_WINSIZE LANGUAGE CXX)
|
||||
check_cxx_symbol_exists("TIOCGWINSZ" "termios.h;sys/ioctl.h" HAVE_TIOCGWINSZ)
|
||||
if(STRUCT_WINSIZE GREATER -1 AND HAVE_TIOCGWINSZ EQUAL 1)
|
||||
set(HAVE_WINSIZE 1)
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
|
||||
check_type_size("wchar_t[8]" WCHAR_T_BITS LANGUAGE CXX)
|
||||
|
||||
set(TPARM_INCLUDES)
|
||||
if(HAVE_NCURSES_H)
|
||||
set(TPARM_INCLUDES "${TPARM_INCLUDES}#include <ncurses.h>\n")
|
||||
elseif(HAVE_NCURSES_CURSES_H)
|
||||
set(TPARM_INCLUDES "${TPARM_INCLUDES}#include <ncurses/curses.h>\n")
|
||||
else()
|
||||
set(TPARM_INCLUDES "${TPARM_INCLUDES}#include <curses.h>\n")
|
||||
endif()
|
||||
|
||||
if(HAVE_TERM_H)
|
||||
set(TPARM_INCLUDES "${TPARM_INCLUDES}#include <term.h>\n")
|
||||
elseif(HAVE_NCURSES_TERM_H)
|
||||
set(TPARM_INCLUDES "${TPARM_INCLUDES}#include <ncurses/term.h>\n")
|
||||
endif()
|
||||
|
||||
# Solaris and X/Open-conforming systems have a fixed-args tparm
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES ${CURSES_LIBRARY})
|
||||
check_cxx_source_compiles("
|
||||
#define TPARM_VARARGS
|
||||
${TPARM_INCLUDES}
|
||||
|
||||
int main () {
|
||||
tparm( \"\" );
|
||||
}
|
||||
"
|
||||
TPARM_TAKES_VARARGS
|
||||
)
|
||||
|
||||
if(TPARM_TAKES_VARARGS)
|
||||
set(TPARM_VARARGS 1)
|
||||
else()
|
||||
set(TPARM_SOLARIS_KLUDGE 1)
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
|
||||
# Work around the fact that cmake does not propagate the language standard flag into
|
||||
# the CHECK_CXX_SOURCE_COMPILES function. See CMake issue #16456.
|
||||
# Ensure we do this after the FIND_PACKAGE calls which use C, and will error on a C++
|
||||
# standards flag.
|
||||
# Also see https://github.com/fish-shell/fish-shell/issues/5865
|
||||
if(NOT POLICY CMP0067)
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS "${CMAKE_CXX${CMAKE_CXX_STANDARD}_EXTENSION_COMPILE_OPTION}")
|
||||
endif()
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <memory>
|
||||
|
||||
int main () {
|
||||
std::unique_ptr<int> foo = std::make_unique<int>();
|
||||
}
|
||||
"
|
||||
HAVE_STD__MAKE_UNIQUE
|
||||
)
|
||||
|
||||
# Detect support for thread_local.
|
||||
check_cxx_source_compiles("
|
||||
int main () {
|
||||
static thread_local int x = 3;
|
||||
(void)x;
|
||||
}
|
||||
"
|
||||
HAVE_CX11_THREAD_LOCAL
|
||||
)
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
std::atomic<uint64_t> x;
|
||||
int main() {
|
||||
return x;
|
||||
}"
|
||||
LIBATOMIC_NOT_NEEDED)
|
||||
IF (NOT LIBATOMIC_NOT_NEEDED)
|
||||
set(ATOMIC_LIBRARY "atomic")
|
||||
endif()
|
||||
@@ -9,6 +9,7 @@ include(FeatureSummary)
|
||||
set(SPHINX_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/doc_src")
|
||||
set(SPHINX_ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}/user_doc")
|
||||
set(SPHINX_BUILD_DIR "${SPHINX_ROOT_DIR}/build")
|
||||
set(SPHINX_CACHE_DIR "${SPHINX_ROOT_DIR}/doctrees")
|
||||
set(SPHINX_HTML_DIR "${SPHINX_ROOT_DIR}/html")
|
||||
set(SPHINX_MANPAGE_DIR "${SPHINX_ROOT_DIR}/man")
|
||||
|
||||
@@ -16,12 +17,13 @@ set(SPHINX_MANPAGE_DIR "${SPHINX_ROOT_DIR}/man")
|
||||
# Prepend the output dir of fish_indent to PATH.
|
||||
add_custom_target(sphinx-docs
|
||||
mkdir -p ${SPHINX_HTML_DIR}/_static/
|
||||
COMMAND env PATH="${CMAKE_BINARY_DIR}:$$PATH"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SPHINX_SRC_DIR}/_static/pygments.css ${SPHINX_HTML_DIR}/_static/
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SPHINX_SRC_DIR}/_static/custom.css ${SPHINX_HTML_DIR}/_static/
|
||||
COMMAND env PATH="$<TARGET_FILE_DIR:fish_indent>:$$PATH"
|
||||
${SPHINX_EXECUTABLE}
|
||||
-j auto
|
||||
-q -b html
|
||||
-c "${SPHINX_SRC_DIR}"
|
||||
-d "${SPHINX_ROOT_DIR}/.doctrees-html"
|
||||
-d "${SPHINX_CACHE_DIR}"
|
||||
"${SPHINX_SRC_DIR}"
|
||||
"${SPHINX_HTML_DIR}"
|
||||
DEPENDS ${SPHINX_SRC_DIR}/fish_indent_lexer.py fish_indent
|
||||
@@ -29,16 +31,15 @@ add_custom_target(sphinx-docs
|
||||
|
||||
# sphinx-manpages needs the fish_indent binary for the version number
|
||||
add_custom_target(sphinx-manpages
|
||||
env FISH_BUILD_VERSION_FILE=${CMAKE_CURRENT_BINARY_DIR}/${FBVF}
|
||||
env PATH="$<TARGET_FILE_DIR:fish_indent>:$$PATH"
|
||||
${SPHINX_EXECUTABLE}
|
||||
-j auto
|
||||
-q -b man
|
||||
-c "${SPHINX_SRC_DIR}"
|
||||
-d "${SPHINX_ROOT_DIR}/.doctrees-man"
|
||||
-d "${SPHINX_CACHE_DIR}"
|
||||
"${SPHINX_SRC_DIR}"
|
||||
# TODO: This only works if we only have section 1 manpages.
|
||||
"${SPHINX_MANPAGE_DIR}/man1"
|
||||
DEPENDS CHECK-FISH-BUILD-VERSION-FILE
|
||||
DEPENDS fish_indent
|
||||
COMMENT "Building man pages with Sphinx")
|
||||
|
||||
if(SPHINX_EXECUTABLE)
|
||||
@@ -66,7 +67,6 @@ endif()
|
||||
|
||||
add_feature_info(Documentation INSTALL_DOCS "user manual and documentation")
|
||||
|
||||
set(USE_PREBUILT_DOCS FALSE)
|
||||
if(BUILD_DOCS)
|
||||
configure_file("${SPHINX_SRC_DIR}/conf.py" "${SPHINX_BUILD_DIR}/conf.py" @ONLY)
|
||||
add_custom_target(doc ALL
|
||||
@@ -77,7 +77,6 @@ if(BUILD_DOCS)
|
||||
PROPERTY FOLDER cmake/DocTargets)
|
||||
|
||||
elseif(HAVE_PREBUILT_DOCS)
|
||||
set(USE_PREBUILT_DOCS TRUE)
|
||||
if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
|
||||
# Out of tree build - link the prebuilt documentation to the build tree
|
||||
add_custom_target(link_doc ALL)
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
#[=======================================================================[.rst:
|
||||
Imported from Corrosion https://github.com/corrosion-rs/corrosion/
|
||||
|
||||
Copyright (c) 2018 Andrew Gaspar
|
||||
|
||||
Licensed under the MIT license
|
||||
|
||||
However this is absolutely gutted and reduced to the bare minimum.
|
||||
#]=======================================================================]
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
|
||||
# List of user variables that will override any toolchain-provided setting
|
||||
set(_Rust_USER_VARS Rust_COMPILER Rust_CARGO Rust_CARGO_TARGET)
|
||||
foreach(_VAR ${_Rust_USER_VARS})
|
||||
if (DEFINED "${_VAR}")
|
||||
set(${_VAR}_CACHED "${${_VAR}}" CACHE INTERNAL "Internal cache of ${_VAR}")
|
||||
else()
|
||||
unset(${_VAR}_CACHED CACHE)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (NOT DEFINED Rust_CARGO_CACHED)
|
||||
find_program(Rust_CARGO_CACHED cargo PATHS "$ENV{HOME}/.cargo/bin")
|
||||
endif()
|
||||
|
||||
if (NOT EXISTS "${Rust_CARGO_CACHED}")
|
||||
message(FATAL_ERROR "The cargo executable ${Rust_CARGO_CACHED} was not found. "
|
||||
"Consider setting `Rust_CARGO_CACHED` to the absolute path of `cargo`."
|
||||
)
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED Rust_COMPILER_CACHED)
|
||||
find_program(Rust_COMPILER_CACHED rustc PATHS "$ENV{HOME}/.cargo/bin")
|
||||
endif()
|
||||
|
||||
|
||||
if (NOT EXISTS "${Rust_COMPILER_CACHED}")
|
||||
message(FATAL_ERROR "The rustc executable ${Rust_COMPILER} was not found. "
|
||||
"Consider setting `Rust_COMPILER` to the absolute path of `rustc`."
|
||||
)
|
||||
endif()
|
||||
|
||||
# Figure out the target by just using the host target.
|
||||
# If you want to cross-compile, you'll have to set Rust_CARGO_TARGET
|
||||
if(NOT Rust_CARGO_TARGET_CACHED)
|
||||
execute_process(
|
||||
COMMAND "${Rust_COMPILER_CACHED}" --version --verbose
|
||||
OUTPUT_VARIABLE _RUSTC_VERSION_RAW
|
||||
RESULT_VARIABLE _RUSTC_VERSION_RESULT
|
||||
)
|
||||
|
||||
if(NOT ( "${_RUSTC_VERSION_RESULT}" EQUAL "0" ))
|
||||
message(FATAL_ERROR "Failed to get rustc version.\n"
|
||||
"${Rust_COMPILER} --version failed with error: `${_RUSTC_VERSION_RESULT}`")
|
||||
endif()
|
||||
|
||||
if (_RUSTC_VERSION_RAW MATCHES "host: ([a-zA-Z0-9_\\-]*)\n")
|
||||
set(Rust_DEFAULT_HOST_TARGET "${CMAKE_MATCH_1}")
|
||||
else()
|
||||
message(FATAL_ERROR
|
||||
"Failed to parse rustc host target. `rustc --version --verbose` evaluated to:\n${_RUSTC_VERSION_RAW}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
message(FATAL_ERROR "CMake is in cross-compiling mode."
|
||||
"Manually set `Rust_CARGO_TARGET`."
|
||||
)
|
||||
endif()
|
||||
set(Rust_CARGO_TARGET_CACHED "${Rust_DEFAULT_HOST_TARGET}" CACHE STRING "Target triple")
|
||||
endif()
|
||||
|
||||
# Set the input variables as non-cache variables so that the variables are available after
|
||||
# `find_package`, even if the values were evaluated to defaults.
|
||||
foreach(_VAR ${_Rust_USER_VARS})
|
||||
set(${_VAR} "${${_VAR}_CACHED}")
|
||||
# Ensure cached variables have type INTERNAL
|
||||
set(${_VAR}_CACHED "${${_VAR}_CACHED}" CACHE INTERNAL "Internal cache of ${_VAR}")
|
||||
endforeach()
|
||||
|
||||
find_package_handle_standard_args(
|
||||
Rust
|
||||
REQUIRED_VARS Rust_COMPILER Rust_CARGO Rust_CARGO_TARGET
|
||||
)
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
# -DLOCALEDIR="${CMAKE_INSTALL_FULL_LOCALEDIR}"
|
||||
# -DPREFIX=L"${CMAKE_INSTALL_PREFIX}"
|
||||
# -DDATADIR=L"${CMAKE_INSTALL_FULL_DATADIR}"
|
||||
# -DSYSCONFDIR=L"${CMAKE_INSTALL_FULL_SYSCONFDIR}"
|
||||
# -DBINDIR=L"${CMAKE_INSTALL_FULL_BINDIR}"
|
||||
# -DDOCDIR=L"${CMAKE_INSTALL_FULL_DOCDIR}")
|
||||
|
||||
set(CMAKE_INSTALL_MESSAGE NEVER)
|
||||
|
||||
set(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/fish ${CMAKE_CURRENT_BINARY_DIR}/fish_indent ${CMAKE_CURRENT_BINARY_DIR}/fish_key_reader)
|
||||
set(PROGRAMS fish fish_indent fish_key_reader)
|
||||
|
||||
set(prefix ${CMAKE_INSTALL_PREFIX})
|
||||
set(bindir ${CMAKE_INSTALL_BINDIR})
|
||||
set(sysconfdir ${CMAKE_INSTALL_SYSCONFDIR})
|
||||
set(mandir ${CMAKE_INSTALL_MANDIR})
|
||||
|
||||
set(rel_datadir ${CMAKE_INSTALL_DATADIR})
|
||||
set(datadir ${CMAKE_INSTALL_FULL_DATADIR})
|
||||
file(RELATIVE_PATH rel_datadir ${CMAKE_INSTALL_PREFIX} ${datadir})
|
||||
|
||||
set(docdir ${CMAKE_INSTALL_DOCDIR})
|
||||
|
||||
# Comment at the top of some .in files
|
||||
set(configure_input
|
||||
"This file was generated from a corresponding .in file.\
|
||||
DO NOT MANUALLY EDIT THIS FILE!")
|
||||
|
||||
set(rel_completionsdir "fish/vendor_completions.d")
|
||||
set(rel_functionsdir "fish/vendor_functions.d")
|
||||
set(rel_confdir "fish/vendor_conf.d")
|
||||
@@ -28,21 +40,10 @@ set(extra_confdir
|
||||
"${datadir}/${rel_confdir}"
|
||||
CACHE STRING "Path for extra configuration")
|
||||
|
||||
|
||||
# These are the man pages that go in system manpath; all manpages go in the fish-specific manpath.
|
||||
set(MANUALS ${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish.1
|
||||
${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish_indent.1
|
||||
${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish_key_reader.1
|
||||
${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish-doc.1
|
||||
${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish-tutorial.1
|
||||
${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish-language.1
|
||||
${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish-interactive.1
|
||||
${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish-terminal-compatibility.1
|
||||
${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish-completions.1
|
||||
${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish-prompt-tutorial.1
|
||||
${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish-for-bash-users.1
|
||||
${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish-faq.1
|
||||
)
|
||||
${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/fish_key_reader.1)
|
||||
|
||||
# Determine which man page we don't want to install.
|
||||
# On OS X, don't install a man page for open, since we defeat fish's open
|
||||
@@ -75,7 +76,7 @@ function(FISH_TRY_CREATE_DIRS)
|
||||
endforeach()
|
||||
endfunction(FISH_TRY_CREATE_DIRS)
|
||||
|
||||
install(PROGRAMS ${PROGRAMS}
|
||||
install(TARGETS ${PROGRAMS}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ
|
||||
GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
|
||||
DESTINATION ${bindir})
|
||||
@@ -89,9 +90,8 @@ fish_create_dirs(${rel_datadir}/fish ${rel_datadir}/fish/completions
|
||||
${rel_datadir}/fish/man/man1 ${rel_datadir}/fish/tools
|
||||
${rel_datadir}/fish/tools/web_config
|
||||
${rel_datadir}/fish/tools/web_config/js
|
||||
${rel_datadir}/fish/tools/web_config/sample_prompts
|
||||
${rel_datadir}/fish/tools/web_config/themes
|
||||
)
|
||||
${rel_datadir}/fish/tools/web_config/partials
|
||||
${rel_datadir}/fish/tools/web_config/sample_prompts)
|
||||
|
||||
configure_file(share/__fish_build_paths.fish.in share/__fish_build_paths.fish)
|
||||
install(FILES share/config.fish
|
||||
@@ -108,9 +108,9 @@ configure_file(fish.pc.in fish.pc.noversion @ONLY)
|
||||
add_custom_command(OUTPUT fish.pc
|
||||
COMMAND sed '/Version/d' fish.pc.noversion > fish.pc
|
||||
COMMAND printf "Version: " >> fish.pc
|
||||
COMMAND cat ${FBVF} >> fish.pc
|
||||
COMMAND sed 's/FISH_BUILD_VERSION=//\;s/\"//g' ${FBVF} >> fish.pc
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS CHECK-FISH-BUILD-VERSION-FILE ${CMAKE_CURRENT_BINARY_DIR}/fish.pc.noversion)
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${FBVF} ${CMAKE_CURRENT_BINARY_DIR}/fish.pc.noversion)
|
||||
|
||||
add_custom_target(build_fish_pc ALL DEPENDS fish.pc)
|
||||
|
||||
@@ -136,7 +136,7 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/user_doc/man/man1/
|
||||
PATTERN "*.1"
|
||||
PATTERN ${CONDEMNED_PAGE} EXCLUDE)
|
||||
|
||||
install(PROGRAMS share/tools/create_manpage_completions.py
|
||||
install(PROGRAMS share/tools/create_manpage_completions.py share/tools/deroff.py
|
||||
DESTINATION ${rel_datadir}/fish/tools/)
|
||||
|
||||
install(DIRECTORY share/tools/web_config
|
||||
@@ -147,7 +147,6 @@ install(DIRECTORY share/tools/web_config
|
||||
PATTERN "*.html"
|
||||
PATTERN "*.py"
|
||||
PATTERN "*.js"
|
||||
PATTERN "*.theme"
|
||||
PATTERN "*.fish")
|
||||
|
||||
# Building the man pages is optional: if Sphinx isn't installed, they're not built
|
||||
@@ -156,8 +155,25 @@ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/user_doc/html/ # Trailing slash is
|
||||
DESTINATION ${docdir} OPTIONAL)
|
||||
install(FILES CHANGELOG.rst DESTINATION ${docdir})
|
||||
|
||||
install(FILES share/lynx.lss DESTINATION ${rel_datadir}/fish/)
|
||||
|
||||
# These files are built by cmake/gettext.cmake, but using GETTEXT_PROCESS_PO_FILES's
|
||||
# INSTALL_DESTINATION leads to them being installed as ${lang}.gmo, not fish.mo
|
||||
# The ${languages} array comes from cmake/gettext.cmake
|
||||
if(GETTEXT_FOUND)
|
||||
foreach(lang ${languages})
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${lang}.gmo DESTINATION
|
||||
${CMAKE_INSTALL_LOCALEDIR}/${lang}/LC_MESSAGES/ RENAME fish.mo)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
install(FILES fish.desktop DESTINATION ${rel_datadir}/applications)
|
||||
install(FILES fish.png DESTINATION ${rel_datadir}/pixmaps)
|
||||
|
||||
# Group install targets into a InstallTargets folder
|
||||
set_property(TARGET build_fish_pc CHECK-FISH-BUILD-VERSION-FILE
|
||||
test_fishscript
|
||||
test_prep tests_buildroot_target
|
||||
PROPERTY FOLDER cmake/InstallTargets)
|
||||
|
||||
# Make a target build_root that installs into the buildroot directory, for testing.
|
||||
|
||||
36
cmake/Mac.cmake
Normal file
36
cmake/Mac.cmake
Normal file
@@ -0,0 +1,36 @@
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version")
|
||||
|
||||
# Code signing ID on Mac. A default '-' is ad-hoc codesign.
|
||||
# If this is falsey, codesigning is disabled.
|
||||
set(MAC_CODESIGN_ID "-" CACHE STRING "Mac code-signing identity")
|
||||
|
||||
# Whether to inject the "get-task-allow" entitlement, which permits debugging
|
||||
# on the Mac.
|
||||
set(MAC_INJECT_GET_TASK_ALLOW ON CACHE BOOL "Inject get-task-allow on Mac")
|
||||
|
||||
function(CODESIGN_ON_MAC target)
|
||||
if((APPLE) AND (MAC_CODESIGN_ID))
|
||||
execute_process(COMMAND sw_vers "-productVersion" OUTPUT_VARIABLE OSX_VERSION)
|
||||
if(MAC_INJECT_GET_TASK_ALLOW)
|
||||
set(ENTITLEMENTS "--entitlements" "${CMAKE_SOURCE_DIR}/osx/fish_debug.entitlements")
|
||||
else()
|
||||
set(ENTITLEMENTS "")
|
||||
endif(MAC_INJECT_GET_TASK_ALLOW)
|
||||
if(OSX_VERSION VERSION_LESS "10.13.6")
|
||||
# `-options runtime` is only available in OS X from 10.13.6 and up
|
||||
add_custom_command(
|
||||
TARGET ${target}
|
||||
POST_BUILD
|
||||
COMMAND codesign --force --deep ${ENTITLEMENTS} --sign "${MAC_CODESIGN_ID}" $<TARGET_FILE:${target}>
|
||||
VERBATIM
|
||||
)
|
||||
else()
|
||||
add_custom_command(
|
||||
TARGET ${target}
|
||||
POST_BUILD
|
||||
COMMAND codesign --force --deep --options runtime ${ENTITLEMENTS} --sign "${MAC_CODESIGN_ID}" $<TARGET_FILE:${target}>
|
||||
VERBATIM
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endfunction(CODESIGN_ON_MAC target)
|
||||
@@ -6,9 +6,6 @@ endif (NOT APPLE)
|
||||
# The source tree containing certain macOS resources.
|
||||
set(OSX_DIR ${CMAKE_CURRENT_SOURCE_DIR}/osx)
|
||||
|
||||
# 10.9 is the minimum supported version.
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9")
|
||||
|
||||
set(RESOURCE_FILES
|
||||
${OSX_DIR}/launch_fish.scpt
|
||||
${OSX_DIR}/fish_term_icon.icns
|
||||
@@ -24,7 +21,7 @@ add_executable(fish_macapp EXCLUDE_FROM_ALL
|
||||
|
||||
# Compute the version. Note this is done at generation time, not build time,
|
||||
# so cmake must be re-run after version changes for the app to be updated. But
|
||||
# generally this will be run by make_macos_pkg.sh which always re-runs cmake.
|
||||
# generally this will be run by make_pkg.sh which always re-runs cmake.
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/build_tools/git_version_gen.sh --stdout
|
||||
COMMAND cut -d- -f1
|
||||
@@ -32,7 +29,7 @@ execute_process(
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
|
||||
# Note CMake appends .app, so the real output name will be fish.app.
|
||||
# Note CMake appends .app, so the real output name will be fish.app.
|
||||
# This target does not include the 'base' resource.
|
||||
set_target_properties(fish_macapp PROPERTIES OUTPUT_NAME "fish")
|
||||
|
||||
@@ -64,5 +61,15 @@ add_custom_command(TARGET fish_macapp POST_BUILD
|
||||
# The entitlements file.
|
||||
set(MACAPP_ENTITLEMENTS "${CMAKE_SOURCE_DIR}/osx/MacApp.entitlements")
|
||||
|
||||
# Group our targets in a folder.
|
||||
set_property(TARGET fish_macapp PROPERTY FOLDER macapp)
|
||||
# Target to sign the macapp.
|
||||
# Note that a POST_BUILD step happens before resources are copied,
|
||||
# and therefore would be too early.
|
||||
add_custom_target(signed_fish_macapp
|
||||
DEPENDS fish_macapp "${MACAPP_ENTITLEMENTS}"
|
||||
COMMAND codesign --force --deep
|
||||
--options runtime
|
||||
--entitlements "${MACAPP_ENTITLEMENTS}"
|
||||
--sign "${MAC_CODESIGN_ID}"
|
||||
$<TARGET_BUNDLE_DIR:fish_macapp>
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user