mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-11 02:51:15 -03:00
Compare commits
40 Commits
Integratio
...
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,27 +1,24 @@
|
||||
image: alpine/edge
|
||||
packages:
|
||||
- cargo
|
||||
- clang17-libclang
|
||||
- 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 test
|
||||
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 test
|
||||
env SHOW_INTERACTIVE_LOG=1 ninja test
|
||||
|
||||
@@ -1,30 +1,26 @@
|
||||
image: freebsd/latest
|
||||
packages:
|
||||
- cmake
|
||||
- ncurses
|
||||
- gcc
|
||||
- gettext
|
||||
- expect
|
||||
- cmake
|
||||
- gmake
|
||||
- llvm
|
||||
- terminfo-db
|
||||
- ninja
|
||||
- pcre2
|
||||
- py311-pexpect
|
||||
- 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 test
|
||||
cd fish/build
|
||||
gmake test SHOW_INTERACTIVE_LOG=1
|
||||
|
||||
@@ -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"
|
||||
77
.cirrus.yml
77
.cirrus.yml
@@ -1,77 +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: jammy
|
||||
container:
|
||||
<<: *step
|
||||
image: ghcr.io/krobelus/fish-ci/jammy:latest
|
||||
# - name: jammy-asan
|
||||
# container:
|
||||
# <<: *step
|
||||
# image: ghcr.io/krobelus/fish-ci/jammy-asan:latest
|
||||
# - name: focal-32bit
|
||||
# container:
|
||||
# <<: *step
|
||||
# image: ghcr.io/krobelus/fish-ci/focal-32bit:latest
|
||||
tests_script:
|
||||
# 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'
|
||||
|
||||
linux_arm_task:
|
||||
matrix:
|
||||
- name: focal-arm64
|
||||
arm_container:
|
||||
image: ghcr.io/fish-shell/fish-ci/focal-arm64
|
||||
- name: jammy-armv7-32bit
|
||||
arm_container:
|
||||
image: ghcr.io/fish-shell/fish-ci/jammy-armv7-32bit
|
||||
tests_script:
|
||||
# cirrus at times gives us 32 procs and 2 GB of RAM
|
||||
# Unrestriced parallelism results in OOM
|
||||
- lscpu || true
|
||||
- (cat /proc/meminfo | grep MemTotal) || true
|
||||
- mkdir build && cd build
|
||||
- FISH_TEST_MAX_CONCURRENCY=6 cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ..
|
||||
- ninja -j 6 fish
|
||||
- file ./fish
|
||||
- ninja fish_run_tests
|
||||
# CI task disabled during RIIR transition
|
||||
only_if: false && $CIRRUS_REPO_OWNER == 'fish-shell'
|
||||
|
||||
freebsd_task:
|
||||
matrix:
|
||||
- name: FreeBSD 14
|
||||
freebsd_instance:
|
||||
image: freebsd-14-3-release-amd64-ufs
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
name: Install sphinx-markdown-builder
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- shell: bash
|
||||
run: |
|
||||
set -x
|
||||
commit=b259de1dc97573a71470a1d71c3d83535934136b
|
||||
pip install git+https://github.com/krobelus/sphinx-markdown-builder@"$commit"
|
||||
python -c 'import sphinx_markdown_builder'
|
||||
@@ -1,20 +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: dtolnay/rust-toolchain@1.70
|
||||
with:
|
||||
targets: ${{ inputs.targets }}
|
||||
components: ${{ inputs.components}}
|
||||
20
.github/actions/rust-toolchain@stable/action.yml
vendored
20
.github/actions/rust-toolchain@stable/action.yml
vendored
@@ -1,20 +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: dtolnay/rust-toolchain@1.90
|
||||
with:
|
||||
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}"`);
|
||||
}
|
||||
19
.github/workflows/lockthreads.yml
vendored
19
.github/workflows/lockthreads.yml
vendored
@@ -2,24 +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:
|
||||
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'
|
||||
|
||||
166
.github/workflows/main.yml
vendored
166
.github/workflows/main.yml
vendored
@@ -1,13 +1,10 @@
|
||||
name: make fish_run_tests
|
||||
name: C/C++ CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
FISH_TEST_MAX_CONCURRENCY: "4"
|
||||
CMAKE_BUILD_PARALLEL_LEVEL: "4"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
ubuntu:
|
||||
@@ -15,162 +12,37 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/rust-toolchain@oldest-supported
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install deps
|
||||
run: |
|
||||
sudo apt install gettext libpcre2-dev python3-pexpect python3-sphinx tmux
|
||||
# Generate a locale that uses a comma as decimal separator.
|
||||
sudo locale-gen fr_FR.UTF-8
|
||||
- uses: ./.github/actions/install-sphinx-markdown-builder
|
||||
sudo apt install expect gettext libncurses5-dev libpcre2-dev
|
||||
- name: cmake
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
cmake ..
|
||||
- name: make
|
||||
run: |
|
||||
make -C build VERBOSE=1
|
||||
- name: make fish_run_tests
|
||||
make
|
||||
- name: make test
|
||||
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; }
|
||||
make test
|
||||
|
||||
ubuntu-32bit-static-pcre2:
|
||||
# macos:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
# runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: ./.github/actions/rust-toolchain@oldest-supported
|
||||
with:
|
||||
targets: "i586-unknown-linux-gnu" # rust-toolchain wants this comma-separated
|
||||
- name: Install deps
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install gettext python3-pexpect g++-multilib tmux
|
||||
- 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
|
||||
run: |
|
||||
sudo apt install gettext libpcre2-dev python3-pexpect tmux
|
||||
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
|
||||
|
||||
# Our clang++ tsan builds are not recognizing safe rust patterns (such as the fact that Drop
|
||||
# cannot be called while a thread is using the object in question). Rust has its own way of
|
||||
# running TSAN, but for the duration of the port from C++ to Rust, we'll keep this disabled.
|
||||
|
||||
# ubuntu-threadsan:
|
||||
#
|
||||
# runs-on: ubuntu-latest
|
||||
#
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4
|
||||
# - uses: ./.github/actions/rust-toolchain@oldest-supported
|
||||
# - uses: actions/checkout@v2
|
||||
# - name: Install deps
|
||||
# run: |
|
||||
# sudo apt install gettext libpcre2-dev python3-pexpect tmux
|
||||
# brew install pcre2
|
||||
# - name: cmake
|
||||
# env:
|
||||
# FISH_CI_SAN: 1
|
||||
# CC: clang
|
||||
# run: |
|
||||
# mkdir build && cd build
|
||||
# cmake ..
|
||||
# cmake ..
|
||||
# - name: make
|
||||
# run: |
|
||||
# make
|
||||
# - name: make fish_run_tests
|
||||
# - name: make test
|
||||
# run: |
|
||||
# make -C build 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 tmux
|
||||
- name: cmake
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
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
|
||||
# make test
|
||||
|
||||
189
.github/workflows/release.yml
vendored
189
.github/workflows/release.yml
vendored
@@ -1,189 +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 python3-sphinx
|
||||
- uses: ./.github/actions/install-sphinx-markdown-builder
|
||||
- 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
|
||||
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 (experimental)
|
||||
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 python3-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@oldest-supported
|
||||
with:
|
||||
targets: x86_64-apple-darwin
|
||||
- name: Install Rust Stable
|
||||
uses: ./.github/actions/rust-toolchain@stable
|
||||
with:
|
||||
targets: aarch64-apple-darwin
|
||||
- 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
|
||||
61
.github/workflows/rust_checks.yml
vendored
61
.github/workflows/rust_checks.yml
vendored
@@ -1,61 +0,0 @@
|
||||
name: Rust checks
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
rustfmt:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/rust-toolchain@stable
|
||||
with:
|
||||
components: rustfmt
|
||||
- name: cargo fmt
|
||||
run: cargo fmt --check
|
||||
|
||||
clippy-stable:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
features: ["", "--no-default-features"]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/rust-toolchain@stable
|
||||
with:
|
||||
components: clippy
|
||||
- name: Install deps
|
||||
run: |
|
||||
sudo apt install gettext
|
||||
- name: cargo clippy
|
||||
run: cargo clippy --workspace --all-targets ${{ matrix.features }} -- --deny=warnings
|
||||
|
||||
clippy-msrv:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/rust-toolchain@oldest-supported
|
||||
with:
|
||||
components: clippy
|
||||
- name: Install deps
|
||||
run: |
|
||||
sudo apt install gettext
|
||||
- name: cargo clippy
|
||||
run: cargo clippy --workspace --all-targets -- --deny=warnings
|
||||
|
||||
rustdoc:
|
||||
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
|
||||
18
.gitignore
vendored
18
.gitignore
vendored
@@ -38,6 +38,7 @@ Desktop.ini
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
messages.pot
|
||||
.directory
|
||||
.fuse_hidden*
|
||||
|
||||
@@ -76,7 +77,6 @@ __pycache__
|
||||
/share/__fish_build_paths.fish
|
||||
/share/pkgconfig
|
||||
/tests/*.tmp.*
|
||||
/tests/.last-check-all-files
|
||||
|
||||
# xcode
|
||||
## Build generated
|
||||
@@ -89,19 +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/
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
3567
CHANGELOG.rst
3567
CHANGELOG.rst
File diff suppressed because it is too large
Load Diff
216
CMakeLists.txt
216
CMakeLists.txt
@@ -1,29 +1,149 @@
|
||||
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)
|
||||
@@ -34,46 +154,51 @@ 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)
|
||||
|
||||
@@ -86,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.
|
||||
575
CONTRIBUTING.rst
575
CONTRIBUTING.rst
@@ -1,116 +1,136 @@
|
||||
####################
|
||||
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/.
|
||||
|
||||
Code Style
|
||||
==========
|
||||
|
||||
To ensure your changes conform to the style rules run
|
||||
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
|
||||
|
||||
::
|
||||
|
||||
build_tools/style.fish
|
||||
|
||||
before committing your change. That will run our autoformatters:
|
||||
|
||||
- ``rustfmt`` for Rust
|
||||
- ``fish_indent`` (shipped with fish) for fish script
|
||||
- ``black`` for python
|
||||
before committing your change. That will run ``git-clang-format`` to
|
||||
rewrite only the lines you’re modifying.
|
||||
|
||||
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
|
||||
@@ -128,24 +148,40 @@ If you want to check the style of the entire code base run
|
||||
That command will refuse to restyle any files if you have uncommitted
|
||||
changes.
|
||||
|
||||
Fish Script Style Guide
|
||||
-----------------------
|
||||
Configuring Your Editor for Fish C++ Code
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1. All fish scripts, such as those in the *share/functions* and *tests*
|
||||
directories, should be formatted using the ``fish_indent`` command.
|
||||
ViM
|
||||
^^^
|
||||
|
||||
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.
|
||||
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:
|
||||
|
||||
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.
|
||||
::
|
||||
|
||||
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``:
|
||||
|
||||
::
|
||||
@@ -178,61 +214,131 @@ made to run fish_indent via e.g.
|
||||
(add-hook 'fish-mode-hook (lambda ()
|
||||
(add-hook 'before-save-hook 'fish_indent-before-save)))
|
||||
|
||||
Rust Style Guide
|
||||
----------------
|
||||
Suppressing Reformatting of C++ Code
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Use ``cargo fmt`` and ``cargo clippy``. Clippy warnings can be turned off if there's a good reason to.
|
||||
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).
|
||||
|
||||
The tests can be found in three places:
|
||||
|
||||
- src/tests for unit tests.
|
||||
- tests/checks for script tests, run by `littlecheck <https://github.com/ridiculousfish/littlecheck>`__
|
||||
- tests/pexpects for interactive tests using `pexpect <https://pexpect.readthedocs.io/en/stable/>`__
|
||||
|
||||
When in doubt, the bulk of the tests should be added as a littlecheck test in tests/checks, as they are the easiest to modify and run, and much faster and more dependable than pexpect tests. The syntax is fairly self-explanatory. It's a fish script with the expected output in ``# CHECK:`` or ``# CHECKERR:`` (for stderr) comments.
|
||||
If your littlecheck test has a specific dependency, use ``# REQUIRE: ...`` with a posix sh script.
|
||||
|
||||
The pexpects are written in python and can simulate input and output to/from a terminal, so they are needed for anything that needs actual interactivity. The runner is in tests/pexpect_helper.py, in case you need to modify something there.
|
||||
|
||||
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), or see if it can already do it.
|
||||
|
||||
Local testing
|
||||
-------------
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The tests can be run on your local computer on all operating systems.
|
||||
|
||||
::
|
||||
|
||||
cmake path/to/fish-shell
|
||||
make fish_run_tests
|
||||
make test
|
||||
|
||||
Or you can run them on a fish, without involving cmake::
|
||||
Travis CI Build and Test
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
cargo build
|
||||
cargo test # for the unit tests
|
||||
tests/test_driver.py target/debug # for the script and interactive tests
|
||||
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.
|
||||
|
||||
Here, the first argument to test_driver.py refers to a directory with ``fish``, ``fish_indent`` and ``fish_key_reader`` in it.
|
||||
In this example we're in the root of the git repo and have run ``cargo build`` without ``--release``, so it's a debug build.
|
||||
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.
|
||||
@@ -250,165 +356,144 @@ One possibility is a pre-push hook script like this one:
|
||||
|
||||
# Git gives us lines like "refs/heads/frombranch SOMESHA1 refs/heads/tobranch SOMESHA1"
|
||||
# We're only interested in the branches
|
||||
isprotected=false
|
||||
while read from _ to _; do
|
||||
if [ "$to" = "refs/heads/$protected_branch" ]; then
|
||||
isprotected=true
|
||||
if [ "x$to" = "xrefs/heads/$protected_branch" ]; then
|
||||
isprotected=1
|
||||
fi
|
||||
done
|
||||
if "$isprotected"; then
|
||||
echo "Running checks before push to master"
|
||||
build_tools/check.sh
|
||||
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 ``build_tools/check.sh`` succeeds. In some circumstances
|
||||
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.
|
||||
|
||||
Contributing Translations
|
||||
=========================
|
||||
Coverity Scan
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
Installing the Required Tools
|
||||
-----------------------------
|
||||
|
||||
Adding translations for a new language
|
||||
--------------------------------------
|
||||
Installing the Linting Tools
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
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 "%ls: 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 "%ls: No suitable job\n"
|
||||
msgstr "%ls: Inget passande jobb\n"
|
||||
|
||||
Any ``%s`` / ``%ls`` or ``%d`` are placeholders that fish will use for formatting at runtime. It is important that they match - the translated string should have the same placeholders in the same order.
|
||||
|
||||
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:
|
||||
To install the lint checkers on Mac OS X using Homebrew:
|
||||
|
||||
::
|
||||
|
||||
streams.out.append(wgettext_fmt!("%ls: There are no jobs\n", argv[0]));
|
||||
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.
|
||||
|
||||
Versioning
|
||||
==========
|
||||
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).
|
||||
|
||||
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``).
|
||||
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`` ()
|
||||
|
||||
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``
|
||||
|
||||
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
|
||||
|
||||
768
Cargo.lock
generated
768
Cargo.lock
generated
@@ -1,768 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[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.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[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 = "cc"
|
||||
version = "1.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[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.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3"
|
||||
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 = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
|
||||
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 = "fish"
|
||||
version = "4.1.2"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
"errno",
|
||||
"fish-build-helper",
|
||||
"fish-build-man-pages",
|
||||
"fish-gettext-extraction",
|
||||
"fish-gettext-maps",
|
||||
"fish-gettext-mo-file-parser",
|
||||
"fish-printf",
|
||||
"libc",
|
||||
"lru",
|
||||
"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 = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
||||
dependencies = [
|
||||
"allocator-api2",
|
||||
"equivalent",
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.172"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "lru"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465"
|
||||
dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[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.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[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.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[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.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[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.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "025908b8682a26ba8d12f6f2d66b987584a4a87bc024abc5bbc12553a8cd178a"
|
||||
dependencies = [
|
||||
"rust-embed-impl",
|
||||
"rust-embed-utils",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-impl"
|
||||
version = "8.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6065f1a4392b71819ec1ea1df1120673418bf386f50de1d6f54204d836d4349c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rust-embed-utils",
|
||||
"syn",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-utils"
|
||||
version = "8.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6cc0c81648b20b70c491ff8cce00c1c3b223bb8ed2b5d41f0e54c6c4c0a3594"
|
||||
dependencies = [
|
||||
"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.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28e1c91382686d21b5ac7959341fcb9780fa7c03773646995a87c950fa7be640"
|
||||
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.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "478f121bb72bbf63c52c93011ea1791dca40140dfe13f8336c4c5ac952c33aa9"
|
||||
|
||||
[[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.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[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.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a"
|
||||
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 = "typenum"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||
|
||||
[[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.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd"
|
||||
|
||||
[[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 = "widestring"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
166
Cargo.toml
166
Cargo.toml
@@ -1,166 +0,0 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
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.70"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/fish-shell/fish-shell"
|
||||
|
||||
[workspace.dependencies]
|
||||
bitflags = "2.5.0"
|
||||
cc = "1.0.94"
|
||||
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"] }
|
||||
libc = "0.2.155"
|
||||
# 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"] }
|
||||
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.1.2"
|
||||
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
|
||||
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
|
||||
libc.workspace = true
|
||||
lru.workspace = true
|
||||
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"] }
|
||||
[target.'cfg(not(windows))'.dependencies]
|
||||
rust-embed = { workspace = true, optional = true, features = ["deterministic-timestamps"] }
|
||||
|
||||
[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"
|
||||
clippy.manual_range_contains = "allow"
|
||||
clippy.needless_return = "allow"
|
||||
clippy.needless_lifetimes = "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
|
||||
|
||||
173
README.rst
173
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,25 +88,56 @@ 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``,
|
||||
``file``, ``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
|
||||
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
|
||||
--------
|
||||
@@ -118,25 +149,17 @@ Dependencies
|
||||
|
||||
Compiling fish requires:
|
||||
|
||||
- Rust (version 1.70 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 Python 3.5+, tmux, and the pexpect package.
|
||||
|
||||
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:
|
||||
|
||||
@@ -144,54 +167,49 @@ To install into ``/usr/local``, run:
|
||||
|
||||
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 embedded data (experimental)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
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 the data files embedded.
|
||||
.. code:: bash
|
||||
|
||||
This will include all the datafiles like the included functions or web configuration tool in the main ``fish`` binary.
|
||||
xcodebuild
|
||||
xcodebuild -scheme install
|
||||
|
||||
Fish will then read these right from its own binary, and print them out when needed. Some files, like the webconfig tool and the manpage completion generator, will be extracted to a temporary directory on-demand. You can list the files with ``status list-files`` and print one with ``status get-file path/to/file`` (e.g. ``status get-file functions/fish_prompt.fish`` to get the default prompt).
|
||||
The install directory can be changed using the
|
||||
``-DCMAKE_INSTALL_PREFIX`` parameter for ``cmake``.
|
||||
|
||||
To install fish with embedded files, just use ``cargo``, like::
|
||||
Help, it didn’t build!
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
cargo install --path /path/to/fish # if you have a git clone
|
||||
cargo install --git https://github.com/fish-shell/fish-shell --tag "$(curl -s https://api.github.com/repos/fish-shell/fish-shell/releases/latest | jq -r .tag_name)" # to build the latest release
|
||||
cargo install --git https://github.com/fish-shell/fish-shell # to build the latest development snapshot
|
||||
If fish reports that it could not find curses, try installing a curses
|
||||
development package and build again.
|
||||
|
||||
This will place the standalone binaries in ``~/.cargo/bin/``, but you can place them wherever you want.
|
||||
On Debian or Ubuntu you want:
|
||||
|
||||
This build won't have the HTML docs (``help`` will open the online version).
|
||||
It will try to build the man pages with sphinx-build. If that is not available and you would like to include man pages, you need to install it and retrigger the build script, e.g. by setting FISH_BUILD_DOCS=1::
|
||||
::
|
||||
|
||||
FISH_BUILD_DOCS=1 cargo install --path .
|
||||
sudo apt-get install build-essential cmake ncurses-dev libncurses5-dev libpcre2-dev gettext
|
||||
|
||||
Setting it to "0" disables the inclusion of man pages.
|
||||
On RedHat, CentOS, or Amazon EC2:
|
||||
|
||||
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 yum install ncurses-devel
|
||||
|
||||
Contributing Changes to the Code
|
||||
--------------------------------
|
||||
@@ -203,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
|
||||
|
||||
|
||||
309
build.rs
309
build.rs
@@ -1,309 +0,0 @@
|
||||
#![allow(clippy::uninlined_format_args)]
|
||||
|
||||
use fish_build_helper::{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);
|
||||
|
||||
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");
|
||||
|
||||
rsconf::rebuild_if_path_changed("src/libc.c");
|
||||
cc::Build::new().file("src/libc.c").compile("flibc.a");
|
||||
|
||||
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),
|
||||
("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.
|
||||
std::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 = std::env::var("TARGET").unwrap();
|
||||
if !target.chars().all(|c| c.is_ascii_lowercase()) {
|
||||
target = target.to_ascii_lowercase();
|
||||
}
|
||||
#[allow(clippy::let_and_return)] // for old clippy
|
||||
let is_bsd = target.ends_with("bsd") || target.ends_with("dragonfly");
|
||||
#[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;
|
||||
|
||||
extern "C" {
|
||||
fn pthread_get_stacksize_np(thread: *const ffi::c_void) -> usize;
|
||||
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;
|
||||
match stack_size {
|
||||
0..=TWO_MIB => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_paths() {
|
||||
#[cfg(windows)]
|
||||
use unix_path::{Path, PathBuf};
|
||||
|
||||
fn get_path(name: &str, default: &str, onvar: &Path) -> PathBuf {
|
||||
let mut var = PathBuf::from(env::var(name).unwrap_or(default.to_string()));
|
||||
if var.is_relative() {
|
||||
var = onvar.join(var);
|
||||
}
|
||||
var
|
||||
}
|
||||
|
||||
let prefix = PathBuf::from(env::var("PREFIX").unwrap_or("/usr/local".to_string()));
|
||||
rsconf::rebuild_if_env_changed("PREFIX");
|
||||
rsconf::set_env_value("PREFIX", prefix.to_str().unwrap());
|
||||
|
||||
let datadir = get_path("DATADIR", "share/", &prefix);
|
||||
|
||||
let sysconfdir = get_path(
|
||||
"SYSCONFDIR",
|
||||
// Embedded builds use "/etc," not "./share/etc".
|
||||
if cfg!(feature = "embed-data") {
|
||||
"/etc/"
|
||||
} else {
|
||||
"etc/"
|
||||
},
|
||||
&datadir,
|
||||
);
|
||||
rsconf::set_env_value("SYSCONFDIR", sysconfdir.to_str().unwrap());
|
||||
rsconf::rebuild_if_env_changed("SYSCONFDIR");
|
||||
|
||||
#[cfg(not(feature = "embed-data"))]
|
||||
{
|
||||
rsconf::set_env_value("DATADIR", datadir.to_str().unwrap());
|
||||
rsconf::rebuild_if_env_changed("DATADIR");
|
||||
|
||||
let bindir = get_path("BINDIR", "bin/", &prefix);
|
||||
rsconf::set_env_value("BINDIR", bindir.to_str().unwrap());
|
||||
rsconf::rebuild_if_env_changed("BINDIR");
|
||||
|
||||
let localedir = get_path("LOCALEDIR", "locale/", &datadir);
|
||||
let localedir = localedir.to_str().unwrap();
|
||||
assert!(!localedir.is_empty(), "empty LOCALEDIR is not supported");
|
||||
rsconf::set_env_value("LOCALEDIR", localedir);
|
||||
rsconf::rebuild_if_env_changed("LOCALEDIR");
|
||||
|
||||
let docdir = get_path("DOCDIR", "doc/fish", &datadir);
|
||||
rsconf::set_env_value("DOCDIR", docdir.to_str().unwrap());
|
||||
rsconf::rebuild_if_env_changed("DOCDIR");
|
||||
}
|
||||
}
|
||||
|
||||
fn get_version(src_dir: &Path) -> String {
|
||||
use std::fs::read_to_string;
|
||||
use std::process::Command;
|
||||
|
||||
if let Ok(var) = std::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,62 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
{
|
||||
set -ex
|
||||
|
||||
lint=true
|
||||
if [ "$FISH_CHECK_LINT" = false ]; then
|
||||
lint=false
|
||||
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"
|
||||
|
||||
template_file=$(mktemp)
|
||||
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
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
#!/usr/bin/env fish
|
||||
# Build a list of all sections in the html sphinx docs, separately by page,
|
||||
# so it can be added to share/functions/help.fish
|
||||
# Use like
|
||||
# fish extract_help_sections.fish user_doc/html/{fish_for_bash_users.html,faq.html,interactive.html,language.html,tutorial.html}
|
||||
# TODO: Currently `help` uses variable names we can't generate, so it needs to be touched up manually.
|
||||
# Also this could easily be broken by changes in sphinx, ideally we'd have a way to let it print the section titles.
|
||||
#
|
||||
|
||||
for file in $argv
|
||||
set -l varname (string replace -r '.*/(.*).html' '$1' -- $file | string escape --style=var)pages
|
||||
# Technically we can use any id in the document as an anchor, but listing them all is probably too much.
|
||||
# Sphinx stores section titles (in a slug-ized form) in the id,
|
||||
# and stores explicit section links in a `span` tag like
|
||||
# `<span id="identifiers"></span>`
|
||||
# We extract both separately.
|
||||
set -l sections (string replace -rf '.*class="headerlink" href="#([^"]*)".*' '$1' <$file)
|
||||
# Sections titled "id5" and such are internal cruft and shouldn't be offered.
|
||||
set -a sections (string replace -rf '.*span id="([^"]*)".*' '$1' <$file | string match -rv 'id\d+')
|
||||
|
||||
set sections (printf '%s\n' $sections | sort -u)
|
||||
echo set -l $varname $sections
|
||||
end
|
||||
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,139 +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 --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) *\).*'
|
||||
|
||||
echo '# fish-section-tier1-from-rust'
|
||||
# Get rid of duplicates and sort.
|
||||
msguniq --no-wrap --strict --sort-output $rust_extraction_file
|
||||
or exit 1
|
||||
rm -r /tmp/fish
|
||||
|
||||
if not set -l --query _flag_use_existing_template
|
||||
rm $rust_extraction_file
|
||||
end
|
||||
mkdir -p /tmp/fish/implicit/share/completions /tmp/fish/implicit/share/functions
|
||||
mkdir -p /tmp/fish/explicit/share/completions /tmp/fish/explicit/share/functions
|
||||
|
||||
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.
|
||||
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
|
||||
|
||||
# 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
|
||||
# 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
|
||||
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) *\).*'
|
||||
echo "# fish-section-$tier-from-script-explicitly-added"
|
||||
extract_fish_script_messages_impl $explicit_regex $argv
|
||||
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
|
||||
|
||||
# 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).*'
|
||||
echo "# fish-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,177 +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.9'
|
||||
|
||||
# As of this writing, the most recent Rust release supports macOS back to 10.12.
|
||||
# The first supported version of macOS on arm64 is 10.15, so any Rust is fine for arm64.
|
||||
# We wish to support back to 10.9 on x86-64; the last version of Rust to support that is
|
||||
# version 1.73.0.
|
||||
RUST_VERSION_X86_64=1.70.0
|
||||
|
||||
while getopts "sf:i:p:e:nj:" opt; do
|
||||
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"
|
||||
|
||||
# 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" \
|
||||
&& cmake \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_EXE_LINKER_FLAGS="-Wl,-ld_classic" \
|
||||
-DRust_CARGO_TARGET=aarch64-apple-darwin \
|
||||
-DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' \
|
||||
-DFISH_USE_SYSTEM_PCRE2=OFF \
|
||||
"$SRC_DIR" \
|
||||
&& env $ARM64_DEPLOY_TARGET make VERBOSE=1 -j 12 \
|
||||
&& env 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.
|
||||
# Set RUST_VERSION_X86_64 to the last version of Rust that supports macOS 10.9.
|
||||
{ cd "$PKGDIR/build_x86_64" \
|
||||
&& cmake \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_EXE_LINKER_FLAGS="-Wl,-ld_classic" \
|
||||
-DRust_TOOLCHAIN="$RUST_VERSION_X86_64" \
|
||||
-DRust_CARGO_TARGET=x86_64-apple-darwin \
|
||||
-DRust_COMPILER="$(rustup +$RUST_VERSION_X86_64 which rustc)" \
|
||||
-DRust_CARGO="$(rustup +$RUST_VERSION_X86_64 which cargo)" \
|
||||
-DCMAKE_OSX_ARCHITECTURES='arm64;x86_64' \
|
||||
-DFISH_USE_SYSTEM_PCRE2=OFF "$SRC_DIR" \
|
||||
&& env $X86_64_DEPLOY_TARGET make VERBOSE=1 -j 12; }
|
||||
|
||||
# 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,38 +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)
|
||||
# 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"
|
||||
@@ -59,11 +51,11 @@ 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"
|
||||
$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
|
||||
$TAR_APPEND version
|
||||
@@ -74,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,104 +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")
|
||||
previous_version=$(
|
||||
cd "$workspace_root"
|
||||
awk <CHANGELOG.rst '
|
||||
( /^fish \S*\.\S*\.\S* \(released .*\)$/ &&
|
||||
NR > 1 &&
|
||||
# Skip tags that have not been created yet..
|
||||
system("git rev-parse --verify >/dev/null --quiet refs/tags/"$2) == 0 \
|
||||
) {
|
||||
print $2; ok = 1; exit
|
||||
}
|
||||
END { exit !ok }
|
||||
'
|
||||
)
|
||||
minor_version=${version%.*}
|
||||
previous_minor_version=${previous_version%.*}
|
||||
{
|
||||
sed -n 1,2p <"$workspace_root/CHANGELOG.rst"
|
||||
|
||||
ListCommitters() {
|
||||
comm "$@" "$relnotes_tmp/committers-then" "$relnotes_tmp/committers-now"
|
||||
}
|
||||
(
|
||||
cd "$workspace_root"
|
||||
git log "$previous_version" --format="%aN" | sort -u >"$relnotes_tmp/committers-then"
|
||||
git log "$previous_version".. --format="%aN" | sort -u >"$relnotes_tmp/committers-now"
|
||||
ListCommitters -13 >"$relnotes_tmp/committers-new"
|
||||
ListCommitters -12 >"$relnotes_tmp/committers-returning"
|
||||
)
|
||||
if [ "$minor_version" != "$previous_minor_version" ]; then
|
||||
(
|
||||
cd "$workspace_root"
|
||||
num_commits=$(git log --no-merges --format=%H "$previous_version".. | wc -l)
|
||||
num_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 [ "$minor_version" != "$previous_minor_version" ]; then {
|
||||
JoinEscaped() {
|
||||
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: To download the source code for fish, we suggest the file named \"fish-$version.tar.xz\". The file downloaded from \"Source code (tar.gz)\" will not build correctly.*"
|
||||
echo
|
||||
echo "*The files called fish-$version-linux-\*.tar.xz are experimental packages containing a single standalone ``fish`` binary for any Linux with the given CPU architecture.*"
|
||||
} >"$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_github_flavored=1 \
|
||||
"$@"
|
||||
|
||||
# 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,253 +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 \
|
||||
gh \
|
||||
jq \
|
||||
ruby \
|
||||
timeout \
|
||||
; do
|
||||
if ! command -v "$tool" >/dev/null; then
|
||||
echo >&2 "$0: missing command: $1"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
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"
|
||||
|
||||
# N.B. this is not GPG-signed.
|
||||
git tag --annotate --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)
|
||||
# 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-$version.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-$version.tar.xz )
|
||||
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_number=$(
|
||||
gh_api_repo milestones?state=open |
|
||||
jq '.[] | select(.title == "fish '"$version"'") | .number'
|
||||
)
|
||||
gh_api_repo --method PATCH milestones/$milestone_number \
|
||||
--raw-field state=closed
|
||||
|
||||
next_patch_version=$(
|
||||
echo "$version" | awk -F. '
|
||||
NF == 3 && $3 ~ /[0-9]+/ {
|
||||
printf "%s.%s.%s", $1, $2, $3+1
|
||||
}
|
||||
'
|
||||
)
|
||||
if [ -n "$next_patch_version" ]; then
|
||||
gh_api_repo --method POST milestones \
|
||||
--raw-field title="fish $next_patch_version"
|
||||
fi
|
||||
|
||||
exit
|
||||
|
||||
}
|
||||
@@ -1,124 +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 {doc_src,share,tests}/**.py
|
||||
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)
|
||||
|
||||
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
|
||||
end
|
||||
echo === Running "$green"fish_indent"$normal"
|
||||
if set -l -q _flag_check
|
||||
if not fish_indent --check -- $fish_files
|
||||
echo $red"Fish files are not formatted correctly."$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
|
||||
fish_indent -w -- $fish_files
|
||||
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
|
||||
make fish_indent
|
||||
set PATH . $PATH
|
||||
end
|
||||
echo === Running "$green"fish_indent"$normal"
|
||||
fish_indent -w -- $fish_files
|
||||
end
|
||||
|
||||
if set -q python_files[1]
|
||||
if not type -q black
|
||||
echo
|
||||
echo $yellow'Please install `black` to style python'$normal
|
||||
exit 127
|
||||
end
|
||||
echo === Running "$green"black"$normal"
|
||||
if set -l -q _flag_check
|
||||
if not black --check $python_files
|
||||
echo $red"Python files are not formatted correctly."$normal
|
||||
exit 1
|
||||
end
|
||||
echo Please install "`black`" to style python
|
||||
echo
|
||||
else
|
||||
echo === Running "$blue"black"$normal"
|
||||
black $python_files
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
echo === Running "$green"rustfmt"$normal"
|
||||
if set -l -q _flag_check
|
||||
if set -l -q _flag_all
|
||||
if not cargo fmt --check
|
||||
echo $red"Rust files are not formatted correctly."$normal
|
||||
exit 1
|
||||
end
|
||||
else
|
||||
if set -q rust_files[1]
|
||||
if not rustfmt --check --files-with-diff $rust_files
|
||||
echo $red"Rust files are not formatted correctly."
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if set -l -q _flag_all
|
||||
cargo fmt
|
||||
else
|
||||
if set -q rust_files[1]
|
||||
rustfmt $rust_files
|
||||
end
|
||||
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,165 +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 -g tmpdir
|
||||
set -l po_dir $build_tools/../po
|
||||
|
||||
set -l extract
|
||||
set -l po
|
||||
|
||||
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))
|
||||
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
|
||||
|
||||
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.
|
||||
and msgattrib --no-wrap --no-obsolete -o $new_po_file $po_file
|
||||
or cleanup_exit
|
||||
|
||||
begin
|
||||
echo "# fish-note-sections: Translations are divided into sections, each starting with a fish-section-* comment."
|
||||
echo "# fish-note-sections: The first few sections are more important."
|
||||
echo "# fish-note-sections: Ignore the tier3 sections unless you have a lot of time."
|
||||
sed -i '
|
||||
/^# fish-note-sections:/d;
|
||||
/^# fish-section-/d;
|
||||
' $new_po_file
|
||||
|
||||
set -l next_line 1
|
||||
set -l section
|
||||
awk <$template_file '
|
||||
/^# fish-section-\S*$/ {
|
||||
section = $0
|
||||
}
|
||||
section != "" && /^msgid ".+"$/ {
|
||||
print section
|
||||
print $0
|
||||
section = ""
|
||||
}
|
||||
' |
|
||||
while read -l section
|
||||
read -l msgid_line
|
||||
set -l line_number (grep -m1 -Fxn $msgid_line $new_po_file | string split :)[1]
|
||||
sed -n "$next_line,$(math $line_number - 1)"p $new_po_file
|
||||
echo $section
|
||||
set next_line $line_number
|
||||
# set section
|
||||
end
|
||||
sed -n "$next_line,\$"p $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 set -l --query po
|
||||
if test -e $po_file
|
||||
merge_po_files $template_file $po_file
|
||||
else
|
||||
cp $template_file $po_file
|
||||
end
|
||||
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,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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -1,9 +1,43 @@
|
||||
set(FISH_USE_SYSTEM_PCRE2 ON CACHE BOOL
|
||||
"Try to use PCRE2 from the system, instead of the pcre2-sys version")
|
||||
# PCRE2 needs some settings.
|
||||
set(PCRE2_WIDTH ${WCHAR_T_BITS})
|
||||
set(PCRE2_BUILD_PCRE2_8 OFF CACHE BOOL "Build 8bit PCRE2 library")
|
||||
set(PCRE2_BUILD_PCRE2_${PCRE2_WIDTH} ON CACHE BOOL "Build ${PCRE2_WIDTH}bit PCRE2 library")
|
||||
set(PCRE2_SHOW_REPORT OFF CACHE BOOL "Show the final configuration report")
|
||||
set(PCRE2_BUILD_TESTS OFF CACHE BOOL "Build tests")
|
||||
set(PCRE2_BUILD_PCRE2GREP OFF CACHE BOOL "Build pcre2grep")
|
||||
|
||||
set(PCRE2_MIN_VERSION 10.21)
|
||||
|
||||
# Look for a system-installed PCRE2.
|
||||
find_library(SYS_PCRE2_LIB pcre2-${PCRE2_WIDTH})
|
||||
find_path(SYS_PCRE2_INCLUDE_DIR pcre2.h)
|
||||
|
||||
# We can either use the system-installed PCRE or our bundled version.
|
||||
# This is controlled by the cache variable FISH_USE_SYSTEM_PCRE2.
|
||||
# Here we compute the default value for that variable.
|
||||
if ((APPLE) AND (MAC_CODESIGN_ID))
|
||||
# On Mac, a codesigned fish will refuse to load a non-codesigned PCRE2
|
||||
# (e.g. from Homebrew) so default to bundled PCRE2.
|
||||
set(USE_SYS_PCRE2_DEFAULT OFF)
|
||||
elseif((NOT SYS_PCRE2_LIB) OR (NOT SYS_PCRE2_INCLUDE_DIR))
|
||||
# We did not find system PCRE2, so default to bundled.
|
||||
set(USE_SYS_PCRE2_DEFAULT OFF)
|
||||
else()
|
||||
# Default to using the system PCRE2, which was found.
|
||||
set(USE_SYS_PCRE2_DEFAULT ON)
|
||||
endif()
|
||||
|
||||
set(FISH_USE_SYSTEM_PCRE2 ${USE_SYS_PCRE2_DEFAULT} CACHE BOOL
|
||||
"Use PCRE2 from the system, instead of bundled with fish")
|
||||
|
||||
if(FISH_USE_SYSTEM_PCRE2)
|
||||
message(STATUS "Trying to use PCRE2 from the system")
|
||||
set(PCRE2_LIB "${SYS_PCRE2_LIB}")
|
||||
set(PCRE2_INCLUDE_DIR "${SYS_PCRE2_INCLUDE_DIR}")
|
||||
message(STATUS "Using system PCRE2 library ${PCRE2_INCLUDE_DIR}")
|
||||
else()
|
||||
message(STATUS "Forcing static build of PCRE2")
|
||||
set(FISH_PCRE2_BUILDFLAG "PCRE2_SYS_STATIC=1")
|
||||
message(STATUS "Using bundled PCRE2 library")
|
||||
add_subdirectory(pcre2 EXCLUDE_FROM_ALL)
|
||||
set(PCRE2_INCLUDE_DIR ${CMAKE_BINARY_DIR}/pcre2)
|
||||
set(PCRE2_LIB pcre2-${PCRE2_WIDTH})
|
||||
endif(FISH_USE_SYSTEM_PCRE2)
|
||||
include_directories(${PCRE2_INCLUDE_DIR})
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
include(FindRust)
|
||||
find_package(Rust REQUIRED)
|
||||
|
||||
set(FISH_RUST_BUILD_DIR "${CMAKE_BINARY_DIR}/cargo/build")
|
||||
|
||||
if(DEFINED ASAN)
|
||||
list(APPEND CARGO_FLAGS "-Z" "build-std")
|
||||
list(APPEND FISH_CARGO_FEATURES_LIST "asan")
|
||||
endif()
|
||||
if(DEFINED TSAN)
|
||||
list(APPEND CARGO_FLAGS "-Z" "build-std")
|
||||
list(APPEND FISH_CARGO_FEATURES_LIST "tsan")
|
||||
endif()
|
||||
|
||||
if (Rust_CARGO_TARGET)
|
||||
set(rust_target_dir "${FISH_RUST_BUILD_DIR}/${Rust_CARGO_TARGET}")
|
||||
else()
|
||||
set(rust_target_dir "${FISH_RUST_BUILD_DIR}/${Rust_CARGO_HOST_TARGET}")
|
||||
endif()
|
||||
|
||||
set(rust_profile $<IF:$<CONFIG:Debug>,debug,$<IF:$<CONFIG:RelWithDebInfo>,release-with-debug,release>>)
|
||||
set(rust_debugflags "$<$<CONFIG:Debug>:-g>$<$<CONFIG:RelWithDebInfo>:-g>")
|
||||
|
||||
option(WITH_GETTEXT "Build with gettext localization support. Requires `msgfmt` to work." ON)
|
||||
# Enable gettext feature unless explicitly disabled.
|
||||
if(NOT DEFINED WITH_GETTEXT OR "${WITH_GETTEXT}")
|
||||
list(APPEND FISH_CARGO_FEATURES_LIST "localize-messages")
|
||||
endif()
|
||||
|
||||
list(JOIN FISH_CARGO_FEATURES_LIST , FISH_CARGO_FEATURES)
|
||||
|
||||
# Tell Cargo where our build directory is so it can find Cargo.toml.
|
||||
set(VARS_FOR_CARGO
|
||||
"FISH_BUILD_DIR=${CMAKE_BINARY_DIR}"
|
||||
"PREFIX=${CMAKE_INSTALL_PREFIX}"
|
||||
# Cheesy so we can tell cmake was used to build
|
||||
"CMAKE=1"
|
||||
"DOCDIR=${CMAKE_INSTALL_FULL_DOCDIR}"
|
||||
"DATADIR=${CMAKE_INSTALL_FULL_DATADIR}"
|
||||
"SYSCONFDIR=${CMAKE_INSTALL_FULL_SYSCONFDIR}"
|
||||
"BINDIR=${CMAKE_INSTALL_FULL_BINDIR}"
|
||||
"CARGO_TARGET_DIR=${FISH_RUST_BUILD_DIR}"
|
||||
"CARGO_BUILD_RUSTC=${Rust_COMPILER}"
|
||||
"${FISH_PCRE2_BUILDFLAG}"
|
||||
"RUSTFLAGS=$ENV{RUSTFLAGS} ${rust_debugflags}"
|
||||
)
|
||||
@@ -1,64 +1,125 @@
|
||||
add_executable(fish_test_helper tests/fish_test_helper.c)
|
||||
# Define fish_tests.
|
||||
add_executable(fish_tests EXCLUDE_FROM_ALL
|
||||
src/fish_tests.cpp)
|
||||
fish_link_deps_and_sign(fish_tests)
|
||||
|
||||
FILE(GLOB FISH_CHECKS CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/tests/checks/*.fish)
|
||||
foreach(CHECK ${FISH_CHECKS})
|
||||
get_filename_component(CHECK_NAME ${CHECK} NAME)
|
||||
add_custom_target(
|
||||
test_${CHECK_NAME}
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tests/test_driver.py ${CMAKE_CURRENT_BINARY_DIR}
|
||||
checks/${CHECK_NAME}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests
|
||||
DEPENDS fish fish_indent fish_key_reader fish_test_helper
|
||||
USES_TERMINAL
|
||||
)
|
||||
endforeach(CHECK)
|
||||
# The "test" directory.
|
||||
set(TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/test)
|
||||
|
||||
FILE(GLOB PEXPECTS CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/tests/pexpects/*.py)
|
||||
foreach(PEXPECT ${PEXPECTS})
|
||||
get_filename_component(PEXPECT ${PEXPECT} NAME)
|
||||
add_custom_target(
|
||||
test_${PEXPECT}
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tests/test_driver.py ${CMAKE_CURRENT_BINARY_DIR}
|
||||
pexpects/${PEXPECT}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests
|
||||
DEPENDS fish fish_indent fish_key_reader fish_test_helper
|
||||
USES_TERMINAL
|
||||
)
|
||||
endforeach(PEXPECT)
|
||||
# The directory into which fish is installed.
|
||||
set(TEST_INSTALL_DIR ${TEST_DIR}/buildroot)
|
||||
|
||||
# Rust stuff.
|
||||
set(cargo_test_flags)
|
||||
if(DEFINED ASAN)
|
||||
# Rust w/ -Zsanitizer=address requires explicitly specifying the --target triple or else linker
|
||||
# errors pertaining to asan symbols will ensue.
|
||||
if(NOT DEFINED Rust_CARGO_TARGET)
|
||||
message(FATAL_ERROR "ASAN requires defining the CMake variable Rust_CARGO_TARGET to the
|
||||
intended target triple")
|
||||
endif()
|
||||
endif()
|
||||
if(DEFINED TSAN)
|
||||
if(NOT DEFINED Rust_CARGO_TARGET)
|
||||
message(FATAL_ERROR "TSAN requires defining the CMake variable Rust_CARGO_TARGET to the
|
||||
intended target triple")
|
||||
endif()
|
||||
# The directory where the tests expect to find the fish root (./bin, etc)
|
||||
set(TEST_ROOT_DIR ${TEST_DIR}/root)
|
||||
|
||||
# Copy tests files.
|
||||
file(GLOB TESTS_FILES tests/*)
|
||||
add_custom_target(tests_dir DEPENDS tests)
|
||||
|
||||
if(NOT FISH_IN_TREE_BUILD)
|
||||
add_custom_command(TARGET tests_dir
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_SOURCE_DIR}/tests/ ${CMAKE_BINARY_DIR}/tests/
|
||||
COMMENT "Copying test files to binary dir"
|
||||
VERBATIM)
|
||||
|
||||
add_dependencies(fish_tests tests_dir)
|
||||
endif()
|
||||
|
||||
if(DEFINED Rust_CARGO_TARGET)
|
||||
list(APPEND cargo_test_flags "--target" ${Rust_CARGO_TARGET})
|
||||
list(APPEND cargo_test_flags "--lib")
|
||||
# Copy littlecheck.py
|
||||
configure_file(build_tools/littlecheck.py littlecheck.py COPYONLY)
|
||||
|
||||
# Copy pexpect_helper.py
|
||||
configure_file(build_tools/pexpect_helper.py pexpect_helper.py COPYONLY)
|
||||
|
||||
# Make the directory in which to run tests.
|
||||
# Also symlink fish to where the tests expect it to be.
|
||||
# Lastly put fish_test_helper there too.
|
||||
add_custom_target(tests_buildroot_target
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${TEST_INSTALL_DIR}
|
||||
COMMAND DESTDIR=${TEST_INSTALL_DIR} ${CMAKE_COMMAND}
|
||||
--build ${CMAKE_CURRENT_BINARY_DIR} --target install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/fish_test_helper
|
||||
${TEST_INSTALL_DIR}/${CMAKE_INSTALL_PREFIX}/bin
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink
|
||||
${TEST_INSTALL_DIR}/${CMAKE_INSTALL_PREFIX}
|
||||
${TEST_ROOT_DIR}
|
||||
DEPENDS fish fish_test_helper)
|
||||
|
||||
if(NOT FISH_IN_TREE_BUILD)
|
||||
# We need to symlink share/functions for the tests.
|
||||
# This should be simplified.
|
||||
add_custom_target(symlink_functions
|
||||
COMMAND ${CMAKE_COMMAND} -E create_symlink
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/share/functions
|
||||
${CMAKE_CURRENT_BINARY_DIR}/share/functions)
|
||||
add_dependencies(tests_buildroot_target symlink_functions)
|
||||
else()
|
||||
add_custom_target(symlink_functions)
|
||||
endif()
|
||||
|
||||
set(max_concurrency_flag)
|
||||
if(DEFINED ENV{FISH_TEST_MAX_CONCURRENCY})
|
||||
list(APPEND max_concurrency_flag "--max-concurrency" $ENV{FISH_TEST_MAX_CONCURRENCY})
|
||||
endif()
|
||||
# Prep the environment for running the unit tests.
|
||||
add_custom_target(test_prep
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${TEST_DIR}/data
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${TEST_DIR}/home
|
||||
COMMAND ${CMAKE_COMMAND} -E remove_directory ${TEST_DIR}/temp
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory
|
||||
${TEST_DIR}/data ${TEST_DIR}/home ${TEST_DIR}/temp
|
||||
DEPENDS tests_buildroot_target tests_dir
|
||||
USES_TERMINAL)
|
||||
|
||||
# The top-level test target is "fish_run_tests".
|
||||
add_custom_target(fish_run_tests
|
||||
# TODO: This should be replaced with a unified solution, possibly build_tools/check.sh.
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tests/test_driver.py ${max_concurrency_flag} ${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMAND env ${VARS_FOR_CARGO} cargo test --no-default-features ${CARGO_FLAGS} --workspace --target-dir ${rust_target_dir} ${cargo_test_flags}
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
DEPENDS fish fish_indent fish_key_reader fish_test_helper
|
||||
USES_TERMINAL
|
||||
)
|
||||
# Define our individual tests.
|
||||
# Each test is conceptually independent.
|
||||
# However when running all tests, we want to run them serially for sanity's sake.
|
||||
# So define both a normal target, and a serial variant which enforces ordering.
|
||||
foreach(TESTTYPE test serial_test)
|
||||
add_custom_target(${TESTTYPE}_low_level
|
||||
COMMAND env XDG_DATA_HOME=test/data XDG_CONFIG_HOME=test/home ./fish_tests
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS fish_tests
|
||||
USES_TERMINAL)
|
||||
|
||||
add_custom_target(${TESTTYPE}_fishscript
|
||||
COMMAND cd tests && ${TEST_ROOT_DIR}/bin/fish test.fish
|
||||
DEPENDS test_prep
|
||||
USES_TERMINAL)
|
||||
|
||||
add_custom_target(${TESTTYPE}_interactive
|
||||
COMMAND cd tests && ${TEST_ROOT_DIR}/bin/fish interactive.fish
|
||||
DEPENDS test_prep
|
||||
USES_TERMINAL)
|
||||
endforeach(TESTTYPE)
|
||||
|
||||
# Now add a dependency chain between the serial versions.
|
||||
# This ensures they run in order.
|
||||
add_dependencies(serial_test_fishscript serial_test_low_level)
|
||||
add_dependencies(serial_test_interactive serial_test_fishscript)
|
||||
|
||||
|
||||
add_custom_target(serial_test_high_level
|
||||
DEPENDS serial_test_interactive serial_test_fishscript)
|
||||
|
||||
# Create the 'test' target.
|
||||
# Set a policy so CMake stops complaining about the name 'test'.
|
||||
cmake_policy(PUSH)
|
||||
|
||||
if(${CMAKE_VERSION} VERSION_LESS 3.11.0 AND POLICY CMP0037)
|
||||
cmake_policy(SET CMP0037 OLD)
|
||||
endif()
|
||||
add_custom_target(test)
|
||||
cmake_policy(POP)
|
||||
add_dependencies(test serial_test_high_level)
|
||||
|
||||
# Group test targets into a TestTargets folder
|
||||
set_property(TARGET test tests_dir
|
||||
test_low_level
|
||||
test_fishscript
|
||||
test_interactive
|
||||
test_fishscript test_prep
|
||||
tests_buildroot_target
|
||||
serial_test_high_level
|
||||
serial_test_low_level
|
||||
serial_test_fishscript
|
||||
serial_test_interactive
|
||||
symlink_functions
|
||||
PROPERTY FOLDER cmake/TestTargets)
|
||||
|
||||
43
cmake/gettext.cmake
Normal file
43
cmake/gettext.cmake
Normal file
@@ -0,0 +1,43 @@
|
||||
set(languages de en fr nb nn pl pt_BR sv zh_CN)
|
||||
|
||||
include(FeatureSummary)
|
||||
|
||||
option(WITH_GETTEXT "translate messages if gettext is available" ON)
|
||||
if(WITH_GETTEXT)
|
||||
find_package(Intl QUIET)
|
||||
find_package(Gettext)
|
||||
if(GETTEXT_FOUND)
|
||||
set(HAVE_GETTEXT 1)
|
||||
include_directories(${Intl_INCLUDE_DIR})
|
||||
endif()
|
||||
endif()
|
||||
add_feature_info(gettext GETTEXT_FOUND "translate messages with gettext")
|
||||
|
||||
# Define translations
|
||||
if(GETTEXT_FOUND)
|
||||
foreach(lang ${languages})
|
||||
# Our translations aren't set up entirely as CMake expects, so installation is done in
|
||||
# cmake/Install.cmake instead of using INSTALL_DESTINATION
|
||||
gettext_process_po_files(${lang} ALL
|
||||
PO_FILES po/${lang}.po)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
cmake_push_check_state()
|
||||
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${Intl_INCLUDE_DIR})
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${Intl_LIBRARIES})
|
||||
# libintl.h can be compiled into the stdlib on some GLibC systems
|
||||
if(Intl_FOUND AND Intl_LIBRARIES)
|
||||
set(LIBINTL_INCLUDE "#include <libintl.h>")
|
||||
endif()
|
||||
check_cxx_source_compiles("
|
||||
${LIBINTL_INCLUDE}
|
||||
#include <stdlib.h>
|
||||
int main () {
|
||||
extern int _nl_msg_cat_cntr;
|
||||
int tmp = _nl_msg_cat_cntr;
|
||||
exit(tmp);
|
||||
}
|
||||
"
|
||||
HAVE__NL_MSG_CAT_CNTR)
|
||||
cmake_pop_check_state()
|
||||
179
config_cmake.h.in
Normal file
179
config_cmake.h.in
Normal file
@@ -0,0 +1,179 @@
|
||||
/* Define to 1 if you have the `backtrace_symbols' function. */
|
||||
#cmakedefine HAVE_BACKTRACE_SYMBOLS 1
|
||||
|
||||
/* Define to 1 if compiled on WSL */
|
||||
#cmakedefine WSL 1
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#cmakedefine HAVE_CLOCK_GETTIME 1
|
||||
|
||||
/* Define to 1 if you have the `ctermid_r' function. */
|
||||
#cmakedefine HAVE_CTERMID_R 1
|
||||
|
||||
/* Define to 1 if C++11 thread_local is supported. */
|
||||
#cmakedefine HAVE_CX11_THREAD_LOCAL 1
|
||||
|
||||
/* Define to 1 if you have the `dirfd' function. */
|
||||
#cmakedefine HAVE_DIRFD 1
|
||||
|
||||
/* Define to 1 if you have the <execinfo.h> header file. */
|
||||
#cmakedefine HAVE_EXECINFO_H 1
|
||||
|
||||
/* Define to 1 if you have the `flock' function. */
|
||||
#cmakedefine HAVE_FLOCK 1
|
||||
|
||||
/* Define to 1 if you have the `futimens' function. */
|
||||
#cmakedefine HAVE_FUTIMENS 1
|
||||
|
||||
/* Define to 1 if you have the `futimes' function. */
|
||||
#cmakedefine HAVE_FUTIMES 1
|
||||
|
||||
/* Define to 1 if you have the `getifaddrs' function. */
|
||||
#cmakedefine HAVE_GETIFADDRS 1
|
||||
|
||||
/* Define to 1 if you have the `getpwent' function. */
|
||||
#cmakedefine HAVE_GETPWENT 1
|
||||
|
||||
/* Define to 1 if you have the 'getrusage' function. */
|
||||
#cmakedefine HAVE_GETRUSAGE 1
|
||||
|
||||
/* Define to 1 if you have the `gettext' function. */
|
||||
#cmakedefine HAVE_GETTEXT 1
|
||||
|
||||
/* Define to 1 if you have the `killpg' function. */
|
||||
#cmakedefine HAVE_KILLPG 1
|
||||
|
||||
/* Define to 1 if you have the `lrand48_r' function. */
|
||||
#cmakedefine HAVE_LRAND48_R 1
|
||||
|
||||
/* Define to 1 if you have the `mkostemp' function. */
|
||||
#cmakedefine HAVE_MKOSTEMP 1
|
||||
|
||||
/* Define to 1 if you have the <curses.h> header file. */
|
||||
#cmakedefine HAVE_CURSES_H 1
|
||||
|
||||
/* Define to 1 if you have the <ncurses/curses.h> header file. */
|
||||
#cmakedefine HAVE_NCURSES_CURSES_H 1
|
||||
|
||||
/* Define to 1 if you have the <ncurses.h> header file. */
|
||||
#cmakedefine HAVE_NCURSES_H 1
|
||||
|
||||
/* Define to 1 if you have the <ncurses/term.h> header file. */
|
||||
#cmakedefine HAVE_NCURSES_TERM_H 1
|
||||
|
||||
/* Define to 1 if you have the <siginfo.h> header file. */
|
||||
#cmakedefine HAVE_SIGINFO_H 1
|
||||
|
||||
/* Define to 1 if you have the <spawn.h> header file. */
|
||||
#cmakedefine HAVE_SPAWN_H 1
|
||||
|
||||
/* Define to 1 if you have the `std::wcscasecmp' function. */
|
||||
#cmakedefine HAVE_STD__WCSCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `std::wcsdup' function. */
|
||||
#cmakedefine HAVE_STD__WCSDUP 1
|
||||
|
||||
/* Define to 1 if you have the `std::wcsncasecmp' function. */
|
||||
#cmakedefine HAVE_STD__WCSNCASECMP 1
|
||||
|
||||
/* Define to 1 if `d_type' is a member of `struct dirent'. */
|
||||
#cmakedefine HAVE_STRUCT_DIRENT_D_TYPE 1
|
||||
|
||||
/* Define to 1 if `st_ctime_nsec' is a member of `struct stat'. */
|
||||
#cmakedefine HAVE_STRUCT_STAT_ST_CTIME_NSEC 1
|
||||
|
||||
/* Define to 1 if `st_mtimespec.tv_nsec' is a member of `struct stat'. */
|
||||
#cmakedefine HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC 1
|
||||
|
||||
/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
|
||||
#cmakedefine HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1
|
||||
|
||||
/* Define to 1 if the sys_errlist array is available. */
|
||||
#cmakedefine HAVE_SYS_ERRLIST 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#cmakedefine HAVE_SYS_IOCTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#cmakedefine HAVE_SYS_SELECT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/sysctl.h> header file. */
|
||||
#cmakedefine HAVE_SYS_SYSCTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#cmakedefine HAVE_TERMIOS_H 1
|
||||
|
||||
/* Define to 1 if you have the <term.h> header file. */
|
||||
#cmakedefine HAVE_TERM_H 1
|
||||
|
||||
/* Define to 1 if you have the `wcscasecmp' function. */
|
||||
#cmakedefine HAVE_WCSCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `wcsdup' function. */
|
||||
#cmakedefine HAVE_WCSDUP 1
|
||||
|
||||
/* Define to 1 if you have the `wcslcpy' function. */
|
||||
#cmakedefine HAVE_WCSLCPY 1
|
||||
|
||||
/* Define to 1 if you have the `wcsncasecmp' function. */
|
||||
#cmakedefine HAVE_WCSNCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `wcsndup' function. */
|
||||
#cmakedefine HAVE_WCSNDUP 1
|
||||
|
||||
/* Define to 1 if you have the `wcstod_l' function. */
|
||||
#cmakedefine HAVE_WCSTOD_L 1
|
||||
|
||||
/* Define to 1 if the winsize struct and TIOCGWINSZ macro exist */
|
||||
#cmakedefine HAVE_WINSIZE 1
|
||||
|
||||
/* Define to 1 if the _nl_msg_cat_cntr symbol is exported. */
|
||||
#cmakedefine HAVE__NL_MSG_CAT_CNTR 1
|
||||
|
||||
/* Define to 1 if std::make_unique is available. */
|
||||
#cmakedefine HAVE_STD__MAKE_UNIQUE 1
|
||||
|
||||
/* Define to 1 if the _sys_errs array is available. */
|
||||
#cmakedefine HAVE__SYS__ERRS 1
|
||||
|
||||
/* Define to 1 to disable ncurses macros that conflict with the STL */
|
||||
#define NCURSES_NOMACROS 1
|
||||
|
||||
/* Define to 1 to disable curses macros that conflict with the STL */
|
||||
#define NOMACROS 1
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "https://github.com/fish-shell/fish-shell/issues"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "fish"
|
||||
|
||||
/* Use a variadic tparm on NetBSD curses. */
|
||||
#cmakedefine TPARM_VARARGS 1
|
||||
|
||||
/* Define to 1 if tparm accepts a fixed amount of parameters. */
|
||||
#cmakedefine TPARM_SOLARIS_KLUDGE 1
|
||||
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
/* The size of wchar_t in bits. */
|
||||
#define WCHAR_T_BITS ${WCHAR_T_BITS}
|
||||
|
||||
/* Define if xlocale.h is required for locale_t or wide character support */
|
||||
#cmakedefine HAVE_XLOCALE_H 1
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
#ifndef __warn_unused
|
||||
#define __warn_unused __attribute__ ((warn_unused_result))
|
||||
#endif
|
||||
#else
|
||||
#define __warn_unused
|
||||
#endif
|
||||
@@ -1,12 +0,0 @@
|
||||
[package]
|
||||
name = "fish-build-helper"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
version = "0.0.0"
|
||||
repository.workspace = true
|
||||
|
||||
[dependencies]
|
||||
rsconf.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -1,31 +0,0 @@
|
||||
use std::{borrow::Cow, env, path::Path};
|
||||
|
||||
pub fn workspace_root() -> &'static Path {
|
||||
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
|
||||
manifest_dir.ancestors().nth(2).unwrap()
|
||||
}
|
||||
|
||||
fn cargo_target_dir() -> Cow<'static, Path> {
|
||||
option_env!("CARGO_TARGET_DIR")
|
||||
.map(|d| Cow::Borrowed(Path::new(d)))
|
||||
.unwrap_or(Cow::Owned(workspace_root().join("target")))
|
||||
}
|
||||
|
||||
pub fn fish_build_dir() -> Cow<'static, Path> {
|
||||
// This is set if using CMake.
|
||||
option_env!("FISH_BUILD_DIR")
|
||||
.map(|d| Cow::Borrowed(Path::new(d)))
|
||||
.unwrap_or(cargo_target_dir())
|
||||
}
|
||||
|
||||
// TODO Move this to rsconf
|
||||
pub fn rebuild_if_path_changed<P: AsRef<Path>>(path: P) {
|
||||
rsconf::rebuild_if_path_changed(path.as_ref().to_str().unwrap());
|
||||
}
|
||||
|
||||
// TODO Move this to rsconf
|
||||
pub fn rebuild_if_paths_changed<P: AsRef<Path>, I: IntoIterator<Item = P>>(paths: I) {
|
||||
for path in paths {
|
||||
rsconf::rebuild_if_path_changed(path.as_ref().to_str().unwrap());
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
[package]
|
||||
name = "fish-build-man-pages"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
version = "0.0.0"
|
||||
repository.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
fish-build-helper.workspace = true
|
||||
rsconf.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user