mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-11 11:11:13 -03:00
Compare commits
40 Commits
update-def
...
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"
|
||||
91
.cirrus.yml
91
.cirrus.yml
@@ -1,91 +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
|
||||
- cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCTEST_PARALLEL_LEVEL=6 ..
|
||||
- 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
|
||||
- cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCTEST_PARALLEL_LEVEL=6 ..
|
||||
- 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_family: freebsd-14-0-snap
|
||||
- name: FreeBSD 13
|
||||
freebsd_instance:
|
||||
image: freebsd-13-2-release-amd64
|
||||
# - name: FreeBSD 12.3
|
||||
# freebsd_instance:
|
||||
# image: freebsd-12-3-release-amd64
|
||||
tests_script:
|
||||
- pkg install -y cmake-core devel/pcre2 devel/ninja misc/py-pexpect git-lite terminfo-db
|
||||
# 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
|
||||
# FreeBSD's pkg currently has rust 1.66.0 while we need rust 1.70.0+. Use rustup to install
|
||||
# the latest, but note that it only installs rust per-user.
|
||||
- sudo -u fish-user -s fetch -qo - https://sh.rustup.rs > rustup.sh
|
||||
- sudo -u fish-user -s sh ./rustup.sh -y --profile=minimal
|
||||
# `sudo -s ...` does not invoke a login shell so we need a workaround to make sure the
|
||||
# rustup environment is configured for subsequent `sudo -s ...` commands.
|
||||
# For some reason, this doesn't do the job:
|
||||
# - sudo -u fish-user sh -c 'echo source \$HOME/.cargo/env >> $HOME/.cshrc'
|
||||
- sudo -u fish-user -s cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCTEST_PARALLEL_LEVEL=1 ..
|
||||
- sudo -u fish-user sh -c '. $HOME/.cargo/env; ninja -j 6 fish'
|
||||
- sudo -u fish-user sh -c '. $HOME/.cargo/env; 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
|
||||
@@ -20,9 +20,3 @@ indent_size = 2
|
||||
|
||||
[Dockerfile]
|
||||
indent_size = 2
|
||||
|
||||
[share/{completions,functions}/**.fish]
|
||||
max_line_length = unset
|
||||
|
||||
[{COMMIT_EDITMSG,git-revise-todo}]
|
||||
max_line_length = 80
|
||||
|
||||
17
.gitattributes
vendored
17
.gitattributes
vendored
@@ -5,10 +5,9 @@
|
||||
|
||||
# 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
|
||||
|
||||
@@ -22,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
|
||||
|
||||
66
.github/workflows/autolabel_prs.yml
vendored
66
.github/workflows/autolabel_prs.yml
vendored
@@ -1,66 +0,0 @@
|
||||
name: Auto-Label PRs
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize]
|
||||
|
||||
jobs:
|
||||
label-and-milestone:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# - name: Checkout repository
|
||||
# uses: actions/checkout@v2
|
||||
|
||||
- name: Set label and milestone
|
||||
id: set-label-milestone
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const completionsLabel = 'completions';
|
||||
const completionsMilestone = 'fish next-3.x';
|
||||
|
||||
// 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}"`);
|
||||
|
||||
// Get the list of milestones
|
||||
const { data: milestones } = await github.rest.issues.listMilestones({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
});
|
||||
|
||||
// Find the milestone id
|
||||
const milestone = milestones.find(milestone => milestone.title === completionsMilestone);
|
||||
|
||||
if (milestone) {
|
||||
// Set the milestone for the PR
|
||||
await github.rest.issues.update({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: prNumber,
|
||||
milestone: milestone.number
|
||||
});
|
||||
console.log(`PR ${prNumber} assigned milestone "${completionsMilestone}"`);
|
||||
} else {
|
||||
console.error(`Milestone "${completionsMilestone}" not found`);
|
||||
}
|
||||
}
|
||||
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'
|
||||
|
||||
42
.github/workflows/mac_codesign.yml
vendored
42
.github/workflows/mac_codesign.yml
vendored
@@ -1,42 +0,0 @@
|
||||
name: macOS build and codesign
|
||||
|
||||
on:
|
||||
workflow_dispatch: # Enables manual trigger from GitHub UI
|
||||
|
||||
jobs:
|
||||
build-and-code-sign:
|
||||
runs-on: macos-latest
|
||||
environment: macos-codesign
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Rust 1.73.0
|
||||
uses: dtolnay/rust-toolchain@1.73.0
|
||||
with:
|
||||
targets: x86_64-apple-darwin
|
||||
- name: Install Rust Stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: aarch64-apple-darwin
|
||||
- name: build-and-codesign
|
||||
run: |
|
||||
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_pkg.sh -s -f /tmp/app.p12 -i /tmp/installer.p12 -p "$MAC_CODESIGN_PASSWORD" -n -j /tmp/notarize.json
|
||||
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 }}
|
||||
# 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
|
||||
FISH_ARTEFACT_PATH: /tmp/fish-built
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: macOS Artefacts
|
||||
path: /tmp/fish-built/*
|
||||
if-no-files-found: error
|
||||
156
.github/workflows/main.yml
vendored
156
.github/workflows/main.yml
vendored
@@ -1,13 +1,10 @@
|
||||
name: make fish_run_tests
|
||||
name: C/C++ CI
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
env:
|
||||
CTEST_PARALLEL_LEVEL: "4"
|
||||
CMAKE_BUILD_PARALLEL_LEVEL: "4"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
ubuntu:
|
||||
@@ -15,152 +12,37 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@1.70
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install deps
|
||||
run: |
|
||||
sudo apt install gettext libpcre2-dev python3-pexpect tmux
|
||||
# Generate a locale that uses a comma as decimal separator.
|
||||
sudo locale-gen fr_FR.UTF-8
|
||||
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
|
||||
make test
|
||||
|
||||
ubuntu-32bit-static-pcre2:
|
||||
# macos:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
# runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@1.70
|
||||
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
|
||||
- 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 (shared with corrosion).
|
||||
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: |
|
||||
llvm_version=$(clang --version | awk 'NR==1 { split($NF, version, "."); print version[1] }')
|
||||
export ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-$llvm_version
|
||||
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: dtolnay/rust-toolchain@1.70
|
||||
# - 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: dtolnay/rust-toolchain@1.70
|
||||
- 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 -DWITH_GETTEXT=NO -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
|
||||
|
||||
41
.github/workflows/rust_checks.yml
vendored
41
.github/workflows/rust_checks.yml
vendored
@@ -1,41 +0,0 @@
|
||||
name: Rust checks
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
rustfmt:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- name: cargo fmt
|
||||
run: cargo fmt --check --all
|
||||
|
||||
clippy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
- name: Install deps
|
||||
run: |
|
||||
sudo apt install gettext libpcre2-dev
|
||||
- name: cmake
|
||||
run: |
|
||||
cmake -B build
|
||||
- name: cargo clippy
|
||||
# This used to have --deny=warnings, but that turns rust release day
|
||||
# into automatic CI failure day, so we don't do that.
|
||||
run: cargo clippy --workspace --all-targets
|
||||
|
||||
# Disabling for now because it also checks "advisories",
|
||||
# making CI fail for reasons unrelated to the patch
|
||||
# cargo-deny:
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - uses: actions/checkout@v3
|
||||
# - uses: EmbarkStudios/cargo-deny-action@v1
|
||||
80
.github/workflows/staticbuild.yml
vendored
80
.github/workflows/staticbuild.yml
vendored
@@ -1,80 +0,0 @@
|
||||
name: staticbuilds
|
||||
|
||||
on:
|
||||
# release:
|
||||
# types: [published]
|
||||
# schedule:
|
||||
# - cron: "14 13 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
CTEST_PARALLEL_LEVEL: "1"
|
||||
CMAKE_BUILD_PARALLEL_LEVEL: "4"
|
||||
|
||||
jobs:
|
||||
staticbuilds-linux:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- uses: dtolnay/rust-toolchain@1.70
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Prepare
|
||||
run: |
|
||||
sudo apt install python3-sphinx
|
||||
rustup target add x86_64-unknown-linux-musl
|
||||
rustup target add aarch64-unknown-linux-musl
|
||||
sudo apt install musl-tools crossbuild-essential-arm64 python3-pexpect tmux -y
|
||||
- name: Build
|
||||
run: |
|
||||
CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2" CMAKE_WITH_GETTEXT=0 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
|
||||
cargo build --release --target x86_64-unknown-linux-musl
|
||||
- name: Test
|
||||
run: |
|
||||
test -e tests/test_driver.py && tests/test_driver.py -f /tmp target/x86_64-unknown-linux-musl/release/
|
||||
- name: Compress
|
||||
run: |
|
||||
tar -cazf fish-static-x86_64-$(git describe).tar.xz -C target/x86_64-unknown-linux-musl/release/ fish
|
||||
tar -cazf fish-static-aarch64-$(git describe).tar.xz -C target/aarch64-unknown-linux-musl/release/ fish
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fish-static-linux
|
||||
path: |
|
||||
fish-*.tar.xz
|
||||
retention-days: 14
|
||||
staticbuilds-macos:
|
||||
|
||||
runs-on: macos-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- uses: dtolnay/rust-toolchain@1.70
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Prepare
|
||||
run: |
|
||||
sudo pip3 install --break-system-packages sphinx
|
||||
rustup target add x86_64-apple-darwin
|
||||
rustup target add aarch64-apple-darwin
|
||||
- name: Build
|
||||
run: |
|
||||
PCRE2_SYS_STATIC=1 cargo build --release --target aarch64-apple-darwin --bin fish
|
||||
PCRE2_SYS_STATIC=1 cargo build --release --target x86_64-apple-darwin --bin fish
|
||||
- name: Compress
|
||||
run: |
|
||||
tar -cazf fish-macos-aarch64.tar.xz -C target/aarch64-apple-darwin/release/ fish
|
||||
tar -cazf fish-macos-x86_64.tar.xz -C target/x86_64-apple-darwin/release/ fish
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fish-static-macos
|
||||
path: |
|
||||
fish-macos-*.tar.xz
|
||||
retention-days: 14
|
||||
16
.gitignore
vendored
16
.gitignore
vendored
@@ -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
|
||||
|
||||
3393
CHANGELOG.rst
3393
CHANGELOG.rst
File diff suppressed because it is too large
Load Diff
216
CMakeLists.txt
216
CMakeLists.txt
@@ -1,31 +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 \
|
||||
")
|
||||
|
||||
include(cmake/gettext.cmake)
|
||||
# Disable exception handling.
|
||||
add_compile_options(-fno-exceptions)
|
||||
|
||||
# Set up PCRE2
|
||||
# This sets an environment variable that needs to be available before the Rust stanzas
|
||||
include(cmake/PCRE2.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()
|
||||
|
||||
include(cmake/Rust.cmake)
|
||||
# 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)
|
||||
@@ -36,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
|
||||
${CARGO_FLAGS}
|
||||
${FEATURES_ARG}
|
||||
&&
|
||||
"${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)
|
||||
|
||||
@@ -88,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.
|
||||
490
CONTRIBUTING.rst
490
CONTRIBUTING.rst
@@ -1,109 +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.
|
||||
|
||||
Getting Set Up
|
||||
==============
|
||||
Versioning
|
||||
----------
|
||||
|
||||
Fish is developed on Github, at https://github.com/fish-shell/fish-shell.
|
||||
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``).
|
||||
|
||||
First, you'll need an account there, and you'll need a git clone of fish.
|
||||
Fork it on Github and then run::
|
||||
Include What You Use
|
||||
--------------------
|
||||
|
||||
git clone https://github.com/<USERNAME>/fish-shell.git
|
||||
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.
|
||||
|
||||
This will create a copy of the fish repository in the directory fish-shell in your current working directory.
|
||||
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>`__.
|
||||
|
||||
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:
|
||||
To install the tool on OS X you’ll need to add a
|
||||
`formula <https://github.com/jasonmp85/homebrew-iwyu>`__ then install
|
||||
it:
|
||||
|
||||
- Rust - when in doubt, try rustup
|
||||
- CMake
|
||||
- PCRE2 (headers and libraries) - optional, this will be downloaded if missing
|
||||
- gettext (headers and libraries) - 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!
|
||||
brew tap jasonmp85/iwyu
|
||||
brew install iwyu
|
||||
|
||||
Once you have your changes, open a pull request on https://github.com/fish-shell/fish-shell/pulls.
|
||||
On Ubuntu you can install it via ``apt-get``:
|
||||
|
||||
Guidelines
|
||||
==========
|
||||
::
|
||||
|
||||
In short:
|
||||
sudo apt-get install iwyu
|
||||
|
||||
- Be conservative in what you need (keep to the agreed minimum supported Rust version, limit new dependencies)
|
||||
- Use automated tools to help you (including ``make fish_run_tests`` and ``build_tools/style.fish``)
|
||||
Lint Free Code
|
||||
--------------
|
||||
|
||||
Contributing completions
|
||||
========================
|
||||
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.
|
||||
|
||||
Completion scripts are the most common contribution to fish, and they are very welcome.
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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 should
|
||||
Fish also depends on ``diff`` and ``expect`` for its tests.
|
||||
|
||||
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.
|
||||
Dealing With Lint Warnings
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Put your completion script into share/completions/name-of-command.fish. If you have multiple commands, you need multiple files.
|
||||
You are strongly encouraged to address a lint warning by refactoring the
|
||||
code, changing variable names, or whatever action is implied by the
|
||||
warning.
|
||||
|
||||
If you want to add tests, you probably want to add a littlecheck test. See below for details.
|
||||
Suppressing Lint Warnings
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Contributing documentation
|
||||
==========================
|
||||
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:
|
||||
|
||||
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::
|
||||
// cppcheck-suppress memleak // addr not really leaked
|
||||
|
||||
sphinx-build -j 8 -b html -n doc_src/ /tmp/fish-doc/
|
||||
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:
|
||||
|
||||
which will build the docs as html in /tmp/fish-doc. You can open it in a browser and see that it looks okay.
|
||||
::
|
||||
|
||||
The builtins and various functions shipped with fish are documented in doc_src/cmds/.
|
||||
[src/complete.cpp:1727]: warning (nullPointerRedundantCheck): Either the condition 'cmd_node' is redundant or there is possible null pointer dereference: cmd_node.
|
||||
|
||||
Code Style
|
||||
==========
|
||||
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.
|
||||
|
||||
To ensure your changes conform to the style rules run
|
||||
Ensuring Your Changes Conform to the Style Guides
|
||||
-------------------------------------------------
|
||||
|
||||
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
|
||||
@@ -121,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``:
|
||||
|
||||
::
|
||||
@@ -171,63 +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 --cachedir=/tmp 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.
|
||||
The ``--cachedir /tmp`` argument means it will keep the fish_test_helper binary in /tmp instead of recompiling it for every test.
|
||||
This saves some time, but isn't strictly necessary.
|
||||
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.
|
||||
@@ -252,7 +363,7 @@ One possibility is a pre-push hook script like this one:
|
||||
done
|
||||
if [ "x$isprotected" = x1 ]; then
|
||||
echo "Running tests before push to master"
|
||||
make fish_run_tests
|
||||
make test
|
||||
RESULT=$?
|
||||
if [ $RESULT -ne 0 ]; then
|
||||
echo "Tests failed for a push to master, we can't let you do that" >&2
|
||||
@@ -262,7 +373,7 @@ One possibility is a pre-push hook script like this one:
|
||||
exit 0
|
||||
|
||||
This will check if the push is to the master branch and, if it is, only
|
||||
allow the push if running ``make fish_run_tests`` 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.
|
||||
|
||||
@@ -270,7 +381,7 @@ To install the hook, place the code in a new file
|
||||
``.git/hooks/pre-push`` and make it executable.
|
||||
|
||||
Coverity Scan
|
||||
-------------
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
We use Coverity’s static analysis tool which offers free access to open
|
||||
source projects. While access to the tool itself is restricted,
|
||||
@@ -280,75 +391,67 @@ 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.
|
||||
|
||||
Contributing Translations
|
||||
=========================
|
||||
Installing the Required Tools
|
||||
-----------------------------
|
||||
|
||||
Installing the Linting Tools
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To install the lint checkers on Mac OS X using Homebrew:
|
||||
|
||||
::
|
||||
|
||||
brew tap oclint/formulae
|
||||
brew install oclint
|
||||
brew install cppcheck
|
||||
|
||||
To install the lint checkers on Debian-based Linux distributions:
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install clang
|
||||
sudo apt-get install oclint
|
||||
sudo apt-get install cppcheck
|
||||
|
||||
Installing the Reformatting Tools
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Mac OS X:
|
||||
|
||||
::
|
||||
|
||||
brew install clang-format
|
||||
|
||||
Debian-based:
|
||||
|
||||
::
|
||||
|
||||
apt-cache search clang-format
|
||||
|
||||
Above will list all the versions available. Pick the newest one
|
||||
available (3.9 for Ubuntu 16.10 as I write this) and install it:
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install clang-format-3.9
|
||||
sudo ln -s /usr/bin/clang-format-3.9 /usr/bin/clang-format
|
||||
|
||||
Message Translations
|
||||
--------------------
|
||||
|
||||
Fish uses the GNU gettext library to translate messages from English to
|
||||
other languages.
|
||||
|
||||
Creating and updating translations requires the Gettext tools, including
|
||||
``xgettext``, ``msgfmt`` and ``msgmerge``. Translation sources are
|
||||
stored in the ``po`` directory, named ``LANG.po``, where ``LANG`` is the
|
||||
two letter ISO 639-1 language code of the target language (eg ``de`` for
|
||||
German).
|
||||
|
||||
To create a new translation:
|
||||
|
||||
* 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``
|
||||
|
||||
The ``--no-fuzzy-matching`` is important as we have had terrible experiences with gettext's "fuzzy" translations in the past.
|
||||
|
||||
Many tools are available for editing translation files, including
|
||||
command-line and graphical user interface programs. For simple use, you can just 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. 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.
|
||||
|
||||
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:
|
||||
translation. In C++, this requires the use of the ``_`` (underscore)
|
||||
macro:
|
||||
|
||||
::
|
||||
|
||||
streams.out.append(wgettext_fmt!("%ls: There are no jobs\n", argv[0]));
|
||||
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:
|
||||
|
||||
::
|
||||
@@ -363,15 +466,34 @@ Above should be written like this instead:
|
||||
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
|
||||
|
||||
666
Cargo.lock
generated
666
Cargo.lock
generated
@@ -1,666 +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.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fish"
|
||||
version = "4.1.0-alpha0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cc",
|
||||
"errno",
|
||||
"fish-printf",
|
||||
"libc",
|
||||
"lru",
|
||||
"nix",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"pcre2",
|
||||
"portable-atomic",
|
||||
"rand",
|
||||
"rsconf",
|
||||
"rust-embed",
|
||||
"serial_test",
|
||||
"terminfo",
|
||||
"unix_path",
|
||||
"widestring",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fish-printf"
|
||||
version = "0.2.1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"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.169"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
|
||||
[[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.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
|
||||
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",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_codegen"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_generator"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
|
||||
dependencies = [
|
||||
"phf_shared",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
|
||||
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.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
||||
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.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa66af4a4fdd5e7ebc276f115e895611a34739a9c1c01028383d612d550953c0"
|
||||
dependencies = [
|
||||
"rust-embed-impl",
|
||||
"rust-embed-utils",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-impl"
|
||||
version = "8.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6125dbc8867951125eec87294137f4e9c2c96566e61bf72c45095a7c77761478"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rust-embed-utils",
|
||||
"syn",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-utils"
|
||||
version = "8.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e5347777e9aacb56039b0e1f28785929a8a3b709e87482e7442c72e7c12529d"
|
||||
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",
|
||||
"phf_codegen",
|
||||
]
|
||||
|
||||
[[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 = "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"
|
||||
115
Cargo.toml
115
Cargo.toml
@@ -1,115 +0,0 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["printf"]
|
||||
|
||||
[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"
|
||||
|
||||
[profile.release]
|
||||
overflow-checks = true
|
||||
lto = true
|
||||
|
||||
[profile.release-with-debug]
|
||||
inherits = "release"
|
||||
debug = true
|
||||
|
||||
[package]
|
||||
name = "fish"
|
||||
version = "4.1.0-alpha0"
|
||||
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"
|
||||
repository = "https://github.com/fish-shell/fish-shell"
|
||||
homepage = "https://fishshell.com"
|
||||
readme = "README.rst"
|
||||
|
||||
[dependencies]
|
||||
pcre2 = { git = "https://github.com/fish-shell/rust-pcre2", tag = "0.2.9-utf32", default-features = false, features = [
|
||||
"utf32",
|
||||
] }
|
||||
|
||||
bitflags = "2.5.0"
|
||||
errno = "0.3.0"
|
||||
libc = "0.2"
|
||||
# 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.29.0", default-features = false, features = [
|
||||
"event",
|
||||
"inotify",
|
||||
"resource",
|
||||
"fs",
|
||||
] }
|
||||
num-traits = "0.2.19"
|
||||
once_cell = "1.19.0"
|
||||
fish-printf = { path = "./printf", features = ["widestring"] }
|
||||
|
||||
# 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"] }
|
||||
widestring = "1.2.0"
|
||||
# We need 0.9.0 specifically for some crash fixes.
|
||||
terminfo = "0.9.0"
|
||||
rust-embed = { version = "8.2.0", optional = true }
|
||||
|
||||
[target.'cfg(not(target_has_atomic = "64"))'.dependencies]
|
||||
portable-atomic = { version = "1", default-features = false, features = [
|
||||
"fallback",
|
||||
] }
|
||||
|
||||
[dev-dependencies]
|
||||
serial_test = { version = "3", default-features = false }
|
||||
|
||||
[build-dependencies]
|
||||
cc = "1.0.94"
|
||||
rsconf = "0.2.2"
|
||||
|
||||
[target.'cfg(windows)'.build-dependencies]
|
||||
unix_path = "1.0.1"
|
||||
|
||||
[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"]
|
||||
benchmark = []
|
||||
embed-data = ["dep:rust-embed"]
|
||||
|
||||
# The following features are auto-detected by the build-script and should not be enabled manually.
|
||||
asan = []
|
||||
tsan = []
|
||||
|
||||
[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"
|
||||
@@ -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
|
||||
|
||||
170
README.rst
170
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,11 +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 (4.0 on and onwards) cannot be installed in Cygwin, due to a lack of Rust support.
|
||||
- Fish can also be installed on all versions of Windows using
|
||||
`Cygwin <https://cygwin.com/>`__ (from the **Shells** category).
|
||||
|
||||
Building from source
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -75,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
|
||||
------------
|
||||
@@ -87,28 +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``, ``sort``, ``tee``, ``tr``,
|
||||
``uname`` and ``sed`` at least, but the full coreutils plus ``find`` and
|
||||
``awk`` is preferred)
|
||||
- The gettext library, if compiled with
|
||||
``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 ``nroff`` or ``mandoc`` for
|
||||
messages require ``ul`` and either ``nroff`` or ``mandoc`` 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
|
||||
- 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
|
||||
--------
|
||||
@@ -120,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
|
||||
- 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
|
||||
- an Internet connection, as other dependencies will be downloaded automatically
|
||||
|
||||
Sphinx is also optionally required to build the documentation from a
|
||||
cloned git repository.
|
||||
|
||||
Additionally, running the full test suite requires Python 3, 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:
|
||||
|
||||
@@ -146,53 +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 build with gettext support for 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 4.0.0 # to build from git with a specific version
|
||||
cargo install --git https://github.com/fish-shell/fish-shell # to build the current development snapshot without cloning
|
||||
If fish reports that it could not find curses, try installing a curses
|
||||
development package and build again.
|
||||
|
||||
This will place the 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) or translations.
|
||||
::
|
||||
|
||||
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::
|
||||
sudo apt-get install build-essential cmake ncurses-dev libncurses5-dev libpcre2-dev gettext
|
||||
|
||||
FISH_BUILD_DOCS=1 cargo install --path .
|
||||
On RedHat, CentOS, or Amazon EC2:
|
||||
|
||||
Setting it to "0" disables the inclusion of man pages.
|
||||
::
|
||||
|
||||
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
|
||||
--------------------------------
|
||||
@@ -204,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/
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
462
build.rs
462
build.rs
@@ -1,462 +0,0 @@
|
||||
#![allow(clippy::uninlined_format_args)]
|
||||
|
||||
use rsconf::{LinkType, Target};
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
setup_paths();
|
||||
|
||||
// Add our default to enable tools that don't go through CMake, like "cargo test" and the
|
||||
// language server.
|
||||
|
||||
// FISH_BUILD_DIR is set by CMake, if we are using it.
|
||||
// OUT_DIR is set by Cargo when the build script is running (not compiling)
|
||||
let default_build_dir = env::var("OUT_DIR").unwrap();
|
||||
let build_dir = option_env!("FISH_BUILD_DIR").unwrap_or(&default_build_dir);
|
||||
let build_dir = std::fs::canonicalize(build_dir).unwrap();
|
||||
let build_dir = build_dir.to_str().unwrap();
|
||||
rsconf::set_env_value("FISH_BUILD_DIR", build_dir);
|
||||
// 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",
|
||||
std::fs::canonicalize(env!("CARGO_MANIFEST_DIR"))
|
||||
.unwrap()
|
||||
.as_path()
|
||||
.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);
|
||||
|
||||
let cman = std::fs::canonicalize(env!("CARGO_MANIFEST_DIR")).unwrap();
|
||||
let targetman = cman.as_path().join("target").join("man");
|
||||
|
||||
#[cfg(feature = "embed-data")]
|
||||
#[cfg(not(clippy))]
|
||||
{
|
||||
build_man(&targetman);
|
||||
}
|
||||
#[cfg(any(not(feature = "embed-data"), clippy))]
|
||||
{
|
||||
let sec1dir = targetman.join("man1");
|
||||
let _ = std::fs::create_dir_all(sec1dir.to_str().unwrap());
|
||||
}
|
||||
|
||||
rsconf::rebuild_if_paths_changed(&["src", "printf", "Cargo.toml", "Cargo.lock", "build.rs"]);
|
||||
|
||||
// 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(not(debug_assertions))]
|
||||
rsconf::rebuild_if_paths_changed(&["doc_src", "share"]);
|
||||
|
||||
cc::Build::new()
|
||||
.file("src/libc.c")
|
||||
.include(build_dir)
|
||||
.compile("flibc.a");
|
||||
|
||||
let mut build = cc::Build::new();
|
||||
// Add to the default library search path
|
||||
build.flag_if_supported("-L/usr/local/lib/");
|
||||
rsconf::add_library_search_path("/usr/local/lib");
|
||||
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| Ok(false)) as &dyn Fn(&Target) -> Result<bool, Box<dyn Error>>,
|
||||
),
|
||||
("apple", &detect_apple),
|
||||
("bsd", &detect_bsd),
|
||||
("cygwin", &detect_cygwin),
|
||||
("gettext", &have_gettext),
|
||||
("small_main_stack", &has_small_stack),
|
||||
// See if libc supports the thread-safe localeconv_l(3) alternative to localeconv(3).
|
||||
("localeconv_l", &|target| {
|
||||
Ok(target.has_symbol("localeconv_l"))
|
||||
}),
|
||||
("FISH_USE_POSIX_SPAWN", &|target| {
|
||||
Ok(target.has_header("spawn.h"))
|
||||
}),
|
||||
("HAVE_PIPE2", &|target| {
|
||||
Ok(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") {
|
||||
Ok(false)
|
||||
} else {
|
||||
Ok(target.has_header("sys/eventfd.h"))
|
||||
}
|
||||
}),
|
||||
("HAVE_WAITSTATUS_SIGNAL_RET", &|target| {
|
||||
Ok(target.r#if("WEXITSTATUS(0x007f) == 0x7f", &["sys/wait.h"]))
|
||||
}),
|
||||
] {
|
||||
match handler(target) {
|
||||
Err(e) => {
|
||||
rsconf::warn!("{}: {}", name, e);
|
||||
rsconf::declare_cfg(name, false);
|
||||
},
|
||||
Ok(enabled) => rsconf::declare_cfg(name, enabled),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn detect_apple(_: &Target) -> Result<bool, Box<dyn Error>> {
|
||||
Ok(cfg!(any(target_os = "ios", target_os = "macos")))
|
||||
}
|
||||
|
||||
#[allow(unexpected_cfgs)]
|
||||
fn detect_cygwin(_: &Target) -> Result<bool, Box<dyn Error>> {
|
||||
Ok(cfg!(target_os = "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) -> Result<bool, Box<dyn Error>> {
|
||||
// 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();
|
||||
}
|
||||
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!");
|
||||
Ok(is_bsd)
|
||||
}
|
||||
|
||||
/// Detect libintl/gettext and its needed symbols to enable internationalization/localization
|
||||
/// support.
|
||||
fn have_gettext(target: &Target) -> Result<bool, Box<dyn Error>> {
|
||||
// The following script correctly detects and links against gettext, but so long as we are using
|
||||
// C++ and generate a static library linked into the C++ binary via CMake, we need to account
|
||||
// for the CMake option WITH_GETTEXT being explicitly disabled.
|
||||
rsconf::rebuild_if_env_changed("CMAKE_WITH_GETTEXT");
|
||||
if let Some(with_gettext) = std::env::var_os("CMAKE_WITH_GETTEXT") {
|
||||
if with_gettext.eq_ignore_ascii_case("0") {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
|
||||
// In order for fish to correctly operate, we need some way of notifying libintl to invalidate
|
||||
// its localizations when the locale environment variables are modified. Without the libintl
|
||||
// symbol _nl_msg_cat_cntr, we cannot use gettext even if we find it.
|
||||
let mut libraries = Vec::new();
|
||||
let mut found = 0;
|
||||
let symbols = ["gettext", "_nl_msg_cat_cntr"];
|
||||
for symbol in &symbols {
|
||||
// Historically, libintl was required in order to use gettext() and co, but that
|
||||
// functionality was subsumed by some versions of libc.
|
||||
if target.has_symbol(symbol) {
|
||||
// No need to link anything special for this symbol
|
||||
found += 1;
|
||||
continue;
|
||||
}
|
||||
for library in ["intl", "gettextlib"] {
|
||||
if target.has_symbol_in(symbol, &[library]) {
|
||||
libraries.push(library);
|
||||
found += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
match found {
|
||||
0 => Ok(false),
|
||||
1 => Err(format!("gettext found but cannot be used without {}", symbols[1]).into()),
|
||||
_ => {
|
||||
rsconf::link_libraries(&libraries, LinkType::Default);
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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) -> Result<bool, Box<dyn Error>> {
|
||||
#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "netbsd")))]
|
||||
return Ok(false);
|
||||
|
||||
// NetBSD 10 also needs this but can't find pthread_get_stacksize_np.
|
||||
#[cfg(target_os = "netbsd")]
|
||||
return Ok(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 => Ok(true),
|
||||
_ => Ok(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_paths() {
|
||||
#[cfg(unix)]
|
||||
use std::path::PathBuf;
|
||||
#[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_from_home, prefix) = if let Ok(pre) = env::var("PREFIX") {
|
||||
(false, PathBuf::from(pre))
|
||||
} else {
|
||||
(true, PathBuf::from(".local/"))
|
||||
};
|
||||
|
||||
// If someone gives us a $PREFIX, we need it to be absolute.
|
||||
// Otherwise we would try to get it from $HOME and that won't really work.
|
||||
if !prefix_from_home && prefix.is_relative() {
|
||||
panic!("Can't have relative prefix");
|
||||
}
|
||||
|
||||
rsconf::rebuild_if_env_changed("PREFIX");
|
||||
rsconf::set_env_value("PREFIX", prefix.to_str().unwrap());
|
||||
|
||||
let datadir = get_path("DATADIR", "share/", &prefix);
|
||||
rsconf::set_env_value("DATADIR", datadir.to_str().unwrap());
|
||||
rsconf::rebuild_if_env_changed("DATADIR");
|
||||
|
||||
let datadir_subdir = if prefix_from_home {
|
||||
"fish/install"
|
||||
} else {
|
||||
"fish"
|
||||
};
|
||||
rsconf::set_env_value("DATADIR_SUBDIR", datadir_subdir);
|
||||
|
||||
let bindir = get_path("BINDIR", "bin/", &prefix);
|
||||
rsconf::set_env_value("BINDIR", bindir.to_str().unwrap());
|
||||
rsconf::rebuild_if_env_changed("BINDIR");
|
||||
|
||||
let sysconfdir = get_path(
|
||||
"SYSCONFDIR",
|
||||
// If we get our prefix from $HOME, we should use the system's /etc/
|
||||
// ~/.local/share/etc/ makes no sense
|
||||
if prefix_from_home { "/etc/" } else { "etc/" },
|
||||
&datadir,
|
||||
);
|
||||
rsconf::set_env_value("SYSCONFDIR", sysconfdir.to_str().unwrap());
|
||||
rsconf::rebuild_if_env_changed("SYSCONFDIR");
|
||||
|
||||
let localedir = get_path("LOCALEDIR", "locale/", &datadir);
|
||||
rsconf::set_env_value("LOCALEDIR", localedir.to_str().unwrap());
|
||||
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.to_string();
|
||||
}
|
||||
|
||||
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 gitdir = Path::new(env!("CARGO_MANIFEST_DIR")).join(".git");
|
||||
let jjdir = Path::new(env!("CARGO_MANIFEST_DIR")).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.")
|
||||
}
|
||||
|
||||
#[cfg(feature = "embed-data")]
|
||||
// disable clippy because otherwise it would panic without sphinx
|
||||
#[cfg(not(clippy))]
|
||||
fn build_man(build_dir: &Path) {
|
||||
use std::process::Command;
|
||||
let mandir = build_dir;
|
||||
let sec1dir = mandir.join("man1");
|
||||
let docsrc_path = std::fs::canonicalize(env!("CARGO_MANIFEST_DIR"))
|
||||
.unwrap()
|
||||
.as_path()
|
||||
.join("doc_src");
|
||||
let docsrc = docsrc_path.to_str().unwrap();
|
||||
let args = &[
|
||||
"-j",
|
||||
"auto",
|
||||
"-q",
|
||||
"-b",
|
||||
"man",
|
||||
"-c",
|
||||
docsrc,
|
||||
// doctree path - put this *above* the man1 dir to exclude it.
|
||||
// this is ~6M
|
||||
"-d",
|
||||
mandir.to_str().unwrap(),
|
||||
docsrc,
|
||||
sec1dir.to_str().unwrap(),
|
||||
];
|
||||
let _ = std::fs::create_dir_all(sec1dir.to_str().unwrap());
|
||||
|
||||
rsconf::rebuild_if_env_changed("FISH_BUILD_DOCS");
|
||||
if env::var("FISH_BUILD_DOCS") == Ok("0".to_string()) {
|
||||
println!("cargo:warning=Skipping man pages because $FISH_BUILD_DOCS is set to 0");
|
||||
return;
|
||||
}
|
||||
|
||||
// We run sphinx to build the man pages.
|
||||
// Every error here is fatal so cargo doesn't cache the result
|
||||
// - if we skipped the docs with sphinx not installed, installing it would not then build the docs.
|
||||
// That means you need to explicitly set $FISH_BUILD_DOCS=0 (`FISH_BUILD_DOCS=0 cargo install --path .`),
|
||||
// which is unfortunate - but the docs are pretty important because they're also used for --help.
|
||||
match Command::new("sphinx-build").args(args).spawn() {
|
||||
Err(x) if x.kind() == std::io::ErrorKind::NotFound => {
|
||||
if env::var("FISH_BUILD_DOCS") == Ok("1".to_string()) {
|
||||
panic!("Could not find sphinx-build to build man pages.\nInstall sphinx or disable building the docs by setting $FISH_BUILD_DOCS=0.");
|
||||
}
|
||||
println!("cargo:warning=Cannot find sphinx-build to build man pages.");
|
||||
println!("cargo:warning=If you install it now you need to run `cargo clean` and rebuild, or set $FISH_BUILD_DOCS=1 explicitly.");
|
||||
}
|
||||
Err(x) => {
|
||||
// Another error - permissions wrong etc
|
||||
panic!("Error starting sphinx-build to build man pages: {:?}", x);
|
||||
}
|
||||
Ok(mut x) => match x.wait() {
|
||||
Err(err) => {
|
||||
panic!(
|
||||
"Error waiting for sphinx-build to build man pages: {:?}",
|
||||
err
|
||||
);
|
||||
}
|
||||
Ok(out) => {
|
||||
if out.success() {
|
||||
// Success!
|
||||
return;
|
||||
} else {
|
||||
panic!("sphinx-build failed to build the man pages.");
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
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/
|
||||
@@ -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,40 +1,18 @@
|
||||
#!/usr/bin/env fish
|
||||
#
|
||||
# Tool to generate messages.pot
|
||||
# Extended to replace the old Makefile rule which did not port easily to CMak
|
||||
|
||||
# Create temporary directory for these operations. OS X `mktemp` is somewhat restricted, so this block
|
||||
# works around that - based on share/functions/funced.fish.
|
||||
set -q TMPDIR
|
||||
or set -l TMPDIR /tmp
|
||||
set -l tmpdir (mktemp -d $TMPDIR/fish.XXXXXX)
|
||||
or exit 1
|
||||
# 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.
|
||||
|
||||
# This is a gigantic crime.
|
||||
# xgettext still does not support rust *at all*, so we use cargo-expand to get all our wgettext invocations.
|
||||
set -l expanded (cargo expand --lib; for f in fish{,_indent,_key_reader}; cargo expand --bin $f; end)
|
||||
|
||||
# Extract any gettext call
|
||||
set -l strs (printf '%s\n' $expanded | grep -A1 wgettext_static_str |
|
||||
grep 'widestring::internals::core::primitive::str =' |
|
||||
string match -rg '"(.*)"' | string match -rv '^%ls$|^$' |
|
||||
# escaping difference between gettext and cargo-expand: single-quotes
|
||||
string replace -a "\'" "'" | sort -u)
|
||||
|
||||
# Extract any constants
|
||||
set -a strs (string match -rv 'BUILD_VERSION:|PACKAGE_NAME' -- $expanded |
|
||||
string match -rg 'const [A-Z_]*: &str = "(.*)"' | string replace -a "\'" "'")
|
||||
|
||||
# We construct messages.pot ourselves instead of forcing this into msgmerge or whatever.
|
||||
# The escaping so far works out okay.
|
||||
for str in $strs
|
||||
# grep -P needed for string escape to be compatible (PCRE-style),
|
||||
# -H gives the filename, -n the line number.
|
||||
# If you want to run this on non-GNU grep: Don't.
|
||||
echo "#:" (grep -PHn -r -- (string escape --style=regex -- $str) src/ |
|
||||
head -n1 | string replace -r ':\s.*' '')
|
||||
echo "msgid \"$str\""
|
||||
echo 'msgstr ""'
|
||||
end >messages.pot
|
||||
# Start with the C++ source
|
||||
xgettext -k -k_ -kN_ -LC++ --no-wrap -o messages.pot src/*.cpp src/*.h
|
||||
|
||||
# This regex handles descriptions for `complete` and `function` statements. These messages are not
|
||||
# particularly important to translate. Hence the "implicit" label.
|
||||
@@ -44,25 +22,34 @@ set -l implicit_regex '(?:^| +)(?:complete|function).*? (?:-d|--description) (([
|
||||
# than messages which should be implicitly translated.
|
||||
set -l explicit_regex '.*\( *_ (([\'"]).+?(?<!\\\\)\\2) *\).*'
|
||||
|
||||
mkdir -p $tmpdir/implicit/share/completions $tmpdir/implicit/share/functions
|
||||
mkdir -p $tmpdir/explicit/share/completions $tmpdir/explicit/share/functions
|
||||
rm -r /tmp/fish
|
||||
|
||||
mkdir -p /tmp/fish/implicit/share/completions /tmp/fish/implicit/share/functions
|
||||
mkdir -p /tmp/fish/explicit/share/completions /tmp/fish/explicit/share/functions
|
||||
|
||||
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 '$1' <$f | string unescape \
|
||||
| string replace --all '"' '\\"' | string replace -r '(.*)' 'N_ "$1"' >$tmpdir/explicit/$f
|
||||
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
|
||||
|
||||
# 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 '$1' <$f | string unescape \
|
||||
| string replace --all '"' '\\"' | string replace -r '(.*)' 'N_ "$1"' >$tmpdir/implicit/$f
|
||||
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
|
||||
|
||||
xgettext -j -k -kN_ -LShell --from-code=UTF-8 -cDescription --no-wrap -o messages.pot $tmpdir/{ex,im}plicit/share/*/*.fish
|
||||
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
|
||||
|
||||
# Remove the tmpdir from the location to avoid churn
|
||||
sed -i 's_^#: /.*/share/_#: share/_' messages.pot
|
||||
|
||||
rm -r $tmpdir
|
||||
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
|
||||
|
||||
@@ -2,57 +2,6 @@
|
||||
|
||||
# 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.73.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=$(git describe --always --dirty 2>/dev/null)
|
||||
if test -z "$VERSION" ; then
|
||||
echo "Could not get version from git"
|
||||
@@ -63,121 +12,28 @@ 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)
|
||||
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" \
|
||||
-DWITH_GETTEXT=OFF \
|
||||
-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" \
|
||||
-DWITH_GETTEXT=OFF \
|
||||
-DRust_TOOLCHAIN="$RUST_VERSION_X86_64" \
|
||||
-DRust_CARGO_TARGET=x86_64-apple-darwin \
|
||||
-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
|
||||
|
||||
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"
|
||||
|
||||
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
|
||||
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_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)
|
||||
{ cd "$PKGDIR/build" && make signed_fish_macapp && zip -r "$OUTPUT_PATH/fish-$VERSION.app.zip" fish.app; }
|
||||
|
||||
# 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"
|
||||
rm -r "$PKGDIR"
|
||||
|
||||
@@ -14,14 +14,6 @@ set -e
|
||||
# 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 paralellises
|
||||
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
|
||||
@@ -59,8 +51,8 @@ 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\//"
|
||||
@@ -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=$(git describe --dirty 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),
|
||||
}
|
||||
@@ -3,9 +3,10 @@
|
||||
# This runs C++ files and fish scripts (*.fish) through their respective code
|
||||
# formatting programs.
|
||||
#
|
||||
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
|
||||
|
||||
if test "$argv[1]" = --all
|
||||
@@ -22,20 +23,33 @@ if test $all = yes
|
||||
set -l files (git status --porcelain --short --untracked-files=all | sed -e 's/^ *[^ ]* *//')
|
||||
if set -q files[1]
|
||||
echo
|
||||
echo 'You have uncommitted changes. Are you sure you want to restyle?'
|
||||
read -P 'y/N? ' -n1 -l ans
|
||||
if not string match -qi y -- $ans
|
||||
exit 1
|
||||
end
|
||||
echo You have uncommitted changes. Cowardly refusing to restyle the entire code base.
|
||||
echo
|
||||
exit 1
|
||||
end
|
||||
set fish_files share/**.fish
|
||||
set python_files {doc_src,share,tests}/**.py
|
||||
set rust_files fish-rust/src/**.rs
|
||||
set c_files src/*.h src/*.cpp src/*.c
|
||||
set fish_files (printf '%s\n' share/***.fish)
|
||||
set python_files **.py
|
||||
else
|
||||
# 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)
|
||||
@@ -43,6 +57,37 @@ set -l green (set_color green)
|
||||
set -l blue (set_color blue)
|
||||
set -l normal (set_color normal)
|
||||
|
||||
# Run the C++ reformatter if we have any C++ files.
|
||||
if set -q c_files[1]
|
||||
if test $git_clang_format = yes
|
||||
if type -q git-clang-format
|
||||
echo === Running "$red"git-clang-format"$normal"
|
||||
git add $c_files
|
||||
git-clang-format
|
||||
else
|
||||
echo
|
||||
echo 'WARNING: Cannot find git-clang-format command'
|
||||
echo
|
||||
end
|
||||
else if type -q clang-format
|
||||
echo === Running "$red"clang-format"$normal"
|
||||
for file in $c_files
|
||||
cp $file $file.new # preserves mode bits
|
||||
clang-format $file >$file.new
|
||||
if cmp --quiet $file $file.new
|
||||
rm $file.new
|
||||
else
|
||||
echo $file was NOT correctly formatted
|
||||
mv $file.new $file
|
||||
end
|
||||
end
|
||||
else
|
||||
echo
|
||||
echo 'WARNING: Cannot find clang-format command'
|
||||
echo
|
||||
end
|
||||
end
|
||||
|
||||
# Run the fish reformatter if we have any fish files.
|
||||
if set -q fish_files[1]
|
||||
if not type -q fish_indent
|
||||
@@ -63,14 +108,3 @@ if set -q python_files[1]
|
||||
black $python_files
|
||||
end
|
||||
end
|
||||
|
||||
if set -q rust_files[1]
|
||||
if not type -q rustfmt
|
||||
echo
|
||||
echo Please install "`rustfmt`" to style rust
|
||||
echo
|
||||
else
|
||||
echo === Running "$blue"rustfmt"$normal"
|
||||
rustfmt $rust_files
|
||||
end
|
||||
end
|
||||
|
||||
3
build_tools/ubsan.blacklist
Normal file
3
build_tools/ubsan.blacklist
Normal file
@@ -0,0 +1,3 @@
|
||||
# Ubuntu Xenial (used for Travis CI builds) ships libstdc++ 5.4.0 which contains undefined behaviour
|
||||
# See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63345
|
||||
object-size:*bits/stl_tree.h
|
||||
@@ -1,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,19 +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-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
|
||||
@@ -73,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})
|
||||
@@ -87,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
|
||||
@@ -106,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)
|
||||
|
||||
@@ -145,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
|
||||
@@ -154,6 +155,8 @@ 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
|
||||
@@ -164,8 +167,13 @@ if(GETTEXT_FOUND)
|
||||
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
|
||||
@@ -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,54 +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_CRATE_FEATURES "asan")
|
||||
endif()
|
||||
if(DEFINED TSAN)
|
||||
list(APPEND CARGO_FLAGS "-Z" "build-std")
|
||||
list(APPEND FISH_CRATE_FEATURES "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>")
|
||||
|
||||
|
||||
# Temporary hack to propagate CMake flags/options to build.rs. We need to get CMake to evaluate the
|
||||
# truthiness of the strings if they are set.
|
||||
set(CMAKE_WITH_GETTEXT "1")
|
||||
if(DEFINED WITH_GETTEXT AND NOT "${WITH_GETTEXT}")
|
||||
set(CMAKE_WITH_GETTEXT "0")
|
||||
endif()
|
||||
|
||||
if(FISH_CRATE_FEATURES)
|
||||
set(FEATURES_ARG ${FISH_CRATE_FEATURES})
|
||||
list(PREPEND FEATURES_ARG "--features")
|
||||
endif()
|
||||
|
||||
# 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}"
|
||||
# Temporary hack to propagate CMake flags/options to build.rs.
|
||||
"CMAKE_WITH_GETTEXT=${CMAKE_WITH_GETTEXT}"
|
||||
# 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}"
|
||||
"LOCALEDIR=${CMAKE_INSTALL_FULL_LOCALEDIR}"
|
||||
"CARGO_TARGET_DIR=${FISH_RUST_BUILD_DIR}"
|
||||
"CARGO_BUILD_RUSTC=${Rust_COMPILER}"
|
||||
"${FISH_PCRE2_BUILDFLAG}"
|
||||
"RUSTFLAGS=$ENV{RUSTFLAGS} ${rust_debugflags}"
|
||||
)
|
||||
@@ -1,116 +1,125 @@
|
||||
# This adds ctest support to the project
|
||||
enable_testing()
|
||||
# Define fish_tests.
|
||||
add_executable(fish_tests EXCLUDE_FROM_ALL
|
||||
src/fish_tests.cpp)
|
||||
fish_link_deps_and_sign(fish_tests)
|
||||
|
||||
# By default, ctest runs tests serially
|
||||
# Support CTEST_PARALLEL_LEVEL as an environment variable in addition to a CMake variable
|
||||
if(NOT CTEST_PARALLEL_LEVEL)
|
||||
set(CTEST_PARALLEL_LEVEL $ENV{CTEST_PARALLEL_LEVEL})
|
||||
if(NOT CTEST_PARALLEL_LEVEL)
|
||||
include(ProcessorCount)
|
||||
ProcessorCount(CORES)
|
||||
math(EXPR halfcores "${CORES} / 2")
|
||||
set(CTEST_PARALLEL_LEVEL ${halfcores})
|
||||
endif()
|
||||
# The "test" directory.
|
||||
set(TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/test)
|
||||
|
||||
# The directory into which fish is installed.
|
||||
set(TEST_INSTALL_DIR ${TEST_DIR}/buildroot)
|
||||
|
||||
# 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()
|
||||
|
||||
# Copy littlecheck.py
|
||||
configure_file(build_tools/littlecheck.py littlecheck.py COPYONLY)
|
||||
|
||||
# Put in a tests folder to reduce the top level targets in IDEs.
|
||||
set(CMAKE_FOLDER tests)
|
||||
# Copy pexpect_helper.py
|
||||
configure_file(build_tools/pexpect_helper.py pexpect_helper.py COPYONLY)
|
||||
|
||||
# We will use 125 as a reserved exit code to indicate that a test has been skipped, i.e. it did not
|
||||
# pass but it should not be considered a failed test run, either.
|
||||
set(SKIP_RETURN_CODE 125)
|
||||
# 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)
|
||||
|
||||
# Even though we are using CMake's ctest for testing, we still define our own `make fish_run_tests` target
|
||||
# rather than use its default for many reasons:
|
||||
# * CMake doesn't run tests in-proc or even add each tests as an individual node in the ninja
|
||||
# dependency tree, instead it just bundles all tests into a target called `test` that always just
|
||||
# shells out to `ctest`, so there are no build-related benefits to not doing that ourselves.
|
||||
# * CMake devs insist that it is appropriate for `make fish_run_tests` to never depend on `make all`, i.e.
|
||||
# running `make fish_run_tests` does not require any of the binaries to be built before testing.
|
||||
# * It is not possible to set top-level CTest options/settings such as CTEST_PARALLEL_LEVEL from
|
||||
# within the CMake configuration file.
|
||||
# * The only way to have a test depend on a binary is to add a fake test with a name like
|
||||
# "build_fish" that executes CMake recursively to build the `fish` target.
|
||||
# * Circling back to the point about individual tests not being actual Makefile targets, CMake does
|
||||
# not offer any way to execute a named test via the `make`/`ninja`/whatever interface; the only
|
||||
# way to manually invoke test `foo` is to to manually run `ctest` and specify a regex matching
|
||||
# `foo` as an argument, e.g. `ctest -R ^foo$`... which is really crazy.
|
||||
|
||||
# The top-level test target is "fish_run_tests".
|
||||
add_custom_target(fish_run_tests
|
||||
COMMAND env CTEST_PARALLEL_LEVEL=${CTEST_PARALLEL_LEVEL} FISH_FORCE_COLOR=1
|
||||
${CMAKE_CTEST_COMMAND} --force-new-ctest-process # --verbose
|
||||
--output-on-failure --progress
|
||||
DEPENDS fish fish_indent fish_key_reader fish_test_helper
|
||||
USES_TERMINAL
|
||||
)
|
||||
|
||||
# CMake being CMake, you can't just add a DEPENDS argument to add_test to make it depend on any of
|
||||
# your binaries actually being built before `make fish_run_tests` is executed (requiring `make all` first),
|
||||
# and the only dependency a test can have is on another test. So we make building fish
|
||||
# prerequisites to our entire top-level `test` target.
|
||||
function(add_test_target NAME)
|
||||
string(REPLACE "/" "-" NAME ${NAME})
|
||||
add_custom_target("test_${NAME}" COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -R "^${NAME}$$"
|
||||
DEPENDS fish fish_indent fish_key_reader fish_test_helper USES_TERMINAL)
|
||||
endfunction()
|
||||
|
||||
add_executable(fish_test_helper tests/fish_test_helper.c)
|
||||
|
||||
FILE(GLOB FISH_CHECKS CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/tests/checks/*.fish)
|
||||
foreach(CHECK ${FISH_CHECKS})
|
||||
get_filename_component(CHECK_NAME ${CHECK} NAME)
|
||||
get_filename_component(CHECK ${CHECK} NAME_WE)
|
||||
add_test(NAME ${CHECK_NAME}
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tests/test_driver.py --cachedir=${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}
|
||||
checks/${CHECK}.fish
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests
|
||||
)
|
||||
set_tests_properties(${CHECK_NAME} PROPERTIES SKIP_RETURN_CODE ${SKIP_RETURN_CODE})
|
||||
set_tests_properties(${CHECK_NAME} PROPERTIES ENVIRONMENT FISH_FORCE_COLOR=1)
|
||||
add_test_target("${CHECK_NAME}")
|
||||
endforeach(CHECK)
|
||||
|
||||
FILE(GLOB PEXPECTS CONFIGURE_DEPENDS ${CMAKE_SOURCE_DIR}/tests/pexpects/*.py)
|
||||
foreach(PEXPECT ${PEXPECTS})
|
||||
get_filename_component(PEXPECT ${PEXPECT} NAME)
|
||||
add_test(NAME ${PEXPECT}
|
||||
COMMAND ${CMAKE_SOURCE_DIR}/tests/test_driver.py --cachedir=${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}
|
||||
pexpects/${PEXPECT}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests
|
||||
)
|
||||
set_tests_properties(${PEXPECT} PROPERTIES SKIP_RETURN_CODE ${SKIP_RETURN_CODE})
|
||||
set_tests_properties(${PEXPECT} PROPERTIES ENVIRONMENT FISH_FORCE_COLOR=1)
|
||||
add_test_target("${PEXPECT}")
|
||||
endforeach(PEXPECT)
|
||||
|
||||
set(cargo_test_flags)
|
||||
# Rust stuff.
|
||||
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()
|
||||
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()
|
||||
|
||||
if(DEFINED Rust_CARGO_TARGET)
|
||||
list(APPEND cargo_test_flags "--target" ${Rust_CARGO_TARGET})
|
||||
list(APPEND cargo_test_flags "--lib")
|
||||
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)
|
||||
|
||||
add_test(
|
||||
NAME "cargo-test"
|
||||
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}"
|
||||
)
|
||||
set_tests_properties("cargo-test" PROPERTIES SKIP_RETURN_CODE ${SKIP_RETURN_CODE})
|
||||
add_test_target("cargo-test")
|
||||
# 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)
|
||||
|
||||
@@ -1,22 +1,43 @@
|
||||
set(languages de en fr pl pt_BR sv zh_CN)
|
||||
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)
|
||||
# Group pofile targets into their own folder, as there's a lot of them.
|
||||
set(CMAKE_FOLDER pofiles)
|
||||
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()
|
||||
set(CMAKE_FOLDER)
|
||||
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
|
||||
2
debian/compat
vendored
2
debian/compat
vendored
@@ -1 +1 @@
|
||||
12
|
||||
9
|
||||
|
||||
55
debian/control
vendored
55
debian/control
vendored
@@ -3,16 +3,10 @@ Section: shells
|
||||
Priority: optional
|
||||
Maintainer: ridiculous_fish <corydoras@ridiculousfish.com>
|
||||
Uploaders: David Adam <zanchey@ucc.gu.uwa.edu.au>
|
||||
Build-Depends: debhelper (>= 12),
|
||||
cargo (>= 0.66) | cargo-mozilla (>= 0.66),
|
||||
cmake (>= 3.15.0) | cmake-mozilla (>= 3.15.0),
|
||||
gettext,
|
||||
libpcre2-dev,
|
||||
rustc (>= 1.70),
|
||||
Build-Depends: debhelper (>= 9.20151004), libncurses5-dev, cmake (>= 3.2.0), gettext,
|
||||
# Test dependencies
|
||||
locales-all,
|
||||
ncurses-base,
|
||||
python3
|
||||
locales-all, python3
|
||||
# When libpcre2-dev is available on all supported Debian versions, add a dependency on that.
|
||||
Standards-Version: 4.1.5
|
||||
Homepage: https://fishshell.com/
|
||||
Vcs-Git: https://github.com/fish-shell/fish-shell.git
|
||||
@@ -20,25 +14,34 @@ Vcs-Browser: https://github.com/fish-shell/fish-shell
|
||||
|
||||
Package: fish
|
||||
Architecture: any
|
||||
# for col and lock - bsdmainutils is required in Ubuntu focal
|
||||
Depends: bsdextrautils | bsdmainutils,
|
||||
file,
|
||||
# for the gettext command
|
||||
gettext-base,
|
||||
# for nroff and preconv
|
||||
groff-base,
|
||||
man-db,
|
||||
# for terminal definitions
|
||||
ncurses-base,
|
||||
# for kill
|
||||
procps,
|
||||
python3 (>=3.5),
|
||||
${misc:Depends},
|
||||
${shlibs:Depends}
|
||||
Conflicts: fish-common
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, fish-common (= ${source:Version}), passwd (>= 4.0.3-10), gettext-base, man-db
|
||||
Recommends: xsel (>=1.2.0)
|
||||
Suggests: xdg-utils
|
||||
Description: friendly interactive shell
|
||||
Fish is a command-line shell for modern systems, focusing on user-friendliness,
|
||||
sensibility and discoverability in interactive use. The syntax is simple, but
|
||||
not POSIX compliant.
|
||||
|
||||
Package: fish-common
|
||||
Architecture: all
|
||||
Multi-Arch: foreign
|
||||
Depends: ${misc:Depends}
|
||||
Recommends: fish, python3 (>= 3.5), python3-distutils
|
||||
Suggests: xdg-utils
|
||||
Replaces: fish (<= 2.1.1.dfsg-2)
|
||||
Description: friendly interactive shell (architecture-independent files)
|
||||
Fish is a command-line shell for modern systems, focusing on user-friendliness,
|
||||
sensibility and discoverability in interactive use. The syntax is simple, but
|
||||
not POSIX compliant.
|
||||
.
|
||||
This package contains the common fish files shared by all architectures.
|
||||
|
||||
Package: fish-dbg
|
||||
Architecture: any
|
||||
Section: debug
|
||||
Depends: fish (= ${binary:Version}), ${misc:Depends}
|
||||
Description: debugging symbols for friendly interactive shell
|
||||
Fish is a command-line shell for modern systems, focusing on user-friendliness,
|
||||
sensibility and discoverability in interactive use. The syntax is simple, but
|
||||
not POSIX compliant.
|
||||
.
|
||||
This package contains the debugging symbols for fish.
|
||||
|
||||
236
debian/copyright
vendored
236
debian/copyright
vendored
@@ -1,165 +1,101 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: fish
|
||||
Upstream-Contact: corydoras@ridiculousfish.com
|
||||
Source: https://fishshell.com/
|
||||
This work was packaged for Debian by David Adam <zanchey@ucc.gu.uwa.edu.au>
|
||||
on Thu, 14 Jun 2012 20:33:34 +0800, based on work by James Vega
|
||||
<jamessan@jamessan.com>. Modifications from the downstream Debian maintainer,
|
||||
Tristan Seligmann <mithrandi@debian.org>, have also been included.
|
||||
|
||||
Files: *
|
||||
Copyright: 2005-2009 Axel Liljencrantz <axel@liljencrantz.se>
|
||||
2009- fish-shell contributors
|
||||
License: GPL-2
|
||||
It was downloaded from:
|
||||
|
||||
Files: doc_src/python_docs_theme/*
|
||||
Copyright: 2001-2017 Python Software Foundation
|
||||
2020- fish-shell contributors
|
||||
License: Python
|
||||
https://github.com/fish-shell/fish-shell
|
||||
|
||||
Files: share/tools/web_config/js/alpine.js
|
||||
Copyright: 2019-2021 Caleb Porzio and contributors
|
||||
License: MIT
|
||||
Upstream Authors:
|
||||
|
||||
Files: share/tools/web_config/themes/Dracula.theme
|
||||
Copyright: 2018 Dracula Team
|
||||
License: MIT
|
||||
Axel Liljencrantz
|
||||
ridiculous_fish
|
||||
|
||||
Files: share/tools/web_config/themes/Nord.theme
|
||||
Copyright: 2016-2024 Sven Greb
|
||||
License: MIT
|
||||
Copyright:
|
||||
|
||||
Files: cmake/FindRust.cmake
|
||||
Copyright: 2018 Andrew Gaspar
|
||||
License: MIT
|
||||
Copyright (C) 2005-2008 Axel Liljencrantz
|
||||
Copyright (C) 2011-2012 ridiculous_fish
|
||||
|
||||
Files: src/builtins/printf.rs
|
||||
Copyright: 1990-2007 Free Software Foundation, Inc.
|
||||
2022 fish-shell contributors
|
||||
License: GPL-2+
|
||||
License:
|
||||
|
||||
Files: src/wgetopt.rs
|
||||
Copyright: 1989-1994 Free Software Foundation, Inc.
|
||||
License: LGPL-2+
|
||||
Copyright (C) 2005-2008 Axel Liljencrantz
|
||||
|
||||
Files: printf/*
|
||||
Copyright: 2024 fish-shell contributors
|
||||
2005-2020 Rich Felker
|
||||
License: MIT
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation.
|
||||
|
||||
Files: debian/*
|
||||
Copyright: 2005-2009 James Vega <jamessan@jamessan.com>
|
||||
2012 David Adam <zanchey@ucc.gu.uwa.edu.au>
|
||||
2015 Tristan Seligmann <mithrandi@debian.org>
|
||||
2019-2022 Mo Zhou <lumin@debian.org>
|
||||
License: GPL-2
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
License: GPL-2
|
||||
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.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General Public License can be
|
||||
found in `/usr/share/common-licenses/GPL-2'.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
||||
MA 02110-1301, USA.
|
||||
|
||||
License: GPL-2+
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation; either version 2, or (at your option) any later version.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General Public License can be
|
||||
found in `/usr/share/common-licenses/GPL-2'.
|
||||
On Debian systems, the complete text of the GNU General
|
||||
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
|
||||
|
||||
License: LGPL-2+
|
||||
This package is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
.
|
||||
This package is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this package; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
.
|
||||
On Debian systems, the complete text of the GNU Library General
|
||||
Public License can be found in `/usr/share/common-licenses/LGPL-2'.
|
||||
Fish contains code from the PCRE2 library to support regular expressions. This
|
||||
code, created by Philip Hazel, is distributed under the terms of the BSD
|
||||
license. Copyright © 1997-2015 University of Cambridge.
|
||||
|
||||
License: MIT
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
License: Python
|
||||
1. This LICENSE AGREEMENT is between the Python Software Foundation
|
||||
("PSF"), and the Individual or Organization ("Licensee") accessing and
|
||||
otherwise using this software ("Python") in source or binary form and
|
||||
its associated documentation.
|
||||
.
|
||||
2. Subject to the terms and conditions of this License Agreement, PSF
|
||||
hereby grants Licensee a nonexclusive, royalty-free, world-wide
|
||||
license to reproduce, analyze, test, perform and/or display publicly,
|
||||
prepare derivative works, distribute, and otherwise use Python alone
|
||||
or in any derivative version, provided, however, that PSF's License
|
||||
Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
|
||||
2013, 2014 Python Software Foundation; All Rights Reserved" are
|
||||
retained in Python alone or in any derivative version prepared by
|
||||
Licensee.
|
||||
.
|
||||
3. In the event Licensee prepares a derivative work that is based on
|
||||
or incorporates Python or any part thereof, and wants to make
|
||||
the derivative work available to others as provided herein, then
|
||||
Licensee hereby agrees to include in any such work a brief summary of
|
||||
the changes made to Python.
|
||||
.
|
||||
4. PSF is making Python available to Licensee on an "AS IS"
|
||||
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
|
||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
|
||||
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||
.
|
||||
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
||||
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
|
||||
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||
.
|
||||
6. This License Agreement will automatically terminate upon a material
|
||||
breach of its terms and conditions.
|
||||
.
|
||||
7. Nothing in this License Agreement shall be deemed to create any
|
||||
relationship of agency, partnership, or joint venture between PSF and
|
||||
Licensee. This License Agreement does not grant permission to use PSF
|
||||
trademarks or trade name in a trademark sense to endorse or promote
|
||||
products or services of Licensee, or any third party.
|
||||
.
|
||||
8. By copying, installing or otherwise using Python, Licensee
|
||||
agrees to be bound by the terms and conditions of this License
|
||||
Agreement.
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the University of Cambridge nor the names of any
|
||||
contributors may be used to endorse or promote products derived from this
|
||||
software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Fish also contains small amounts of code under the OpenBSD license, namely a
|
||||
version of the function strlcpy, modified for use with wide character strings.
|
||||
This code is copyrighted by Todd C. Miller (1998). It also contains code from
|
||||
tmux, copyrighted by Nicholas Marriott <nicm@users.sourceforge.net> (2007), and
|
||||
made available under an identical license.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
Fish contains code from the glibc library, namely the wcstok function
|
||||
in fallback.c. This code is licensed under the LGPL.
|
||||
|
||||
On Debian systems, the complete text of the GNU Lesser General
|
||||
Public License can be found in `/usr/share/common-licenses/LGPL'.
|
||||
|
||||
The Debian packaging is:
|
||||
|
||||
Copyright (C) 2005 James Vega <jamessan@jamessan.com>
|
||||
Copyright (C) 2012 David Adam <zanchey@ucc.gu.uwa.edu.au>
|
||||
Copyright (C) 2015 Tristan Seligmann <mithrandi@debian.org>
|
||||
|
||||
and is licensed under the GPL version 2, see above.
|
||||
|
||||
0
debian/docs → debian/fish-common.docs
vendored
0
debian/docs → debian/fish-common.docs
vendored
2
debian/fish-common.install
vendored
Normal file
2
debian/fish-common.install
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
debian/tmp/etc
|
||||
debian/tmp/usr/share
|
||||
4
debian/fish-common.lintian-overrides
vendored
Normal file
4
debian/fish-common.lintian-overrides
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# These directories are intentionally empty.
|
||||
fish-common: package-contains-empty-directory usr/share/fish/vendor_completions.d/
|
||||
fish-common: package-contains-empty-directory usr/share/fish/vendor_conf.d/
|
||||
fish-common: package-contains-empty-directory usr/share/fish/vendor_functions.d/
|
||||
1
debian/fish.install
vendored
Normal file
1
debian/fish.install
vendored
Normal file
@@ -0,0 +1 @@
|
||||
debian/tmp/usr/bin
|
||||
0
debian/postinst → debian/fish.postinst
vendored
0
debian/postinst → debian/fish.postinst
vendored
37
debian/fish.postrm
vendored
Normal file
37
debian/fish.postrm
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/bin/sh
|
||||
# postrm script for fish
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <postrm> `remove'
|
||||
# * <postrm> `purge'
|
||||
# * <old-postrm> `upgrade' <new-version>
|
||||
# * <new-postrm> `failed-upgrade' <old-version>
|
||||
# * <new-postrm> `abort-install'
|
||||
# * <new-postrm> `abort-install' <old-version>
|
||||
# * <new-postrm> `abort-upgrade' <old-version>
|
||||
# * <disappearer's-postrm> `disappear' <overwriter>
|
||||
# <overwriter-version>
|
||||
# for details, see http://www.debian.org/doc/debian-policy/ or
|
||||
# the debian-policy package
|
||||
|
||||
|
||||
case "$1" in
|
||||
purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postrm called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# dh_installdeb will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
0
debian/prerm → debian/fish.prerm
vendored
0
debian/prerm → debian/fish.prerm
vendored
4
debian/lintian-overrides
vendored
4
debian/lintian-overrides
vendored
@@ -1,4 +0,0 @@
|
||||
# These directories are intentionally empty.
|
||||
fish: package-contains-empty-directory usr/share/fish/vendor_completions.d/
|
||||
fish: package-contains-empty-directory usr/share/fish/vendor_conf.d/
|
||||
fish: package-contains-empty-directory usr/share/fish/vendor_functions.d/
|
||||
19
debian/rules
vendored
19
debian/rules
vendored
@@ -3,23 +3,18 @@
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
export DH_VERBOSE=1
|
||||
# The LTO profile sets CFLAGS/CXXFLAGS which confuse the compilation process; disable it
|
||||
# LTO is still performed by rustc based on Cargo.toml
|
||||
export DEB_BUILD_MAINT_OPTIONS=optimize=-lto
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
# Setting the build system is still required, because otherwise the GNUmakefile gets picked up
|
||||
override_dh_auto_configure:
|
||||
ln -s cargo-vendor/vendor vendor
|
||||
ln -s cargo-vendor/.cargo .cargo
|
||||
dh_auto_configure --buildsystem=cmake -- -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
dh_auto_configure --buildsystem=cmake --parallel
|
||||
|
||||
override_dh_clean:
|
||||
dh_clean
|
||||
-unlink .cargo
|
||||
-unlink vendor
|
||||
override_dh_installdocs:
|
||||
dh_installdocs --link-doc=fish
|
||||
|
||||
override_dh_auto_test:
|
||||
make fish_run_tests
|
||||
# Still needed until all platforms have debhelper 9.20151219
|
||||
# Consider transitioning https://wiki.debian.org/DebugPackage
|
||||
override_dh_strip:
|
||||
dh_strip --dbg-package=fish-dbg
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user