mirror of
https://github.com/sharkdp/hexyl.git
synced 2026-10-29 08:05:57 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e10136d203 | ||
|
|
5f0373184f | ||
|
|
57d18482ba | ||
|
|
816779e968 | ||
|
|
9be018fbb9 | ||
|
|
cba717b783 | ||
|
|
580f865c4a | ||
|
|
20450310c9 | ||
|
|
b251575d94 | ||
|
|
58b038af27 | ||
|
|
d703cdfd78 | ||
|
|
43f8b92502 | ||
|
|
a966896d3f | ||
|
|
08b903270f | ||
|
|
dd601e4792 | ||
|
|
564cf64b1b | ||
|
|
c24280620a | ||
|
|
bfa2726e05 | ||
|
|
d6af232691 | ||
|
|
cc6987e270 |
No files matched your search
+112
-120
@@ -1,8 +1,8 @@
|
||||
name: CICD
|
||||
|
||||
env:
|
||||
MIN_SUPPORTED_RUST_VERSION: "1.60.0"
|
||||
CICD_INTERMEDIATES_DIR: "_cicd-intermediates"
|
||||
MSRV_FEATURES: ""
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -14,84 +14,102 @@ on:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
crate_metadata:
|
||||
name: Extract crate metadata
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Extract crate information
|
||||
id: crate_metadata
|
||||
run: |
|
||||
cargo metadata --no-deps --format-version 1 | jq -r '"name=" + .packages[0].name' | tee -a $GITHUB_OUTPUT
|
||||
cargo metadata --no-deps --format-version 1 | jq -r '"version=" + .packages[0].version' | tee -a $GITHUB_OUTPUT
|
||||
cargo metadata --no-deps --format-version 1 | jq -r '"maintainer=" + .packages[0].authors[0]' | tee -a $GITHUB_OUTPUT
|
||||
cargo metadata --no-deps --format-version 1 | jq -r '"homepage=" + .packages[0].homepage' | tee -a $GITHUB_OUTPUT
|
||||
cargo metadata --no-deps --format-version 1 | jq -r '"msrv=" + .packages[0].rust_version' | tee -a $GITHUB_OUTPUT
|
||||
outputs:
|
||||
name: ${{ steps.crate_metadata.outputs.name }}
|
||||
version: ${{ steps.crate_metadata.outputs.version }}
|
||||
maintainer: ${{ steps.crate_metadata.outputs.maintainer }}
|
||||
homepage: ${{ steps.crate_metadata.outputs.homepage }}
|
||||
msrv: ${{ steps.crate_metadata.outputs.msrv }}
|
||||
|
||||
ensure_cargo_fmt:
|
||||
name: Ensure 'cargo fmt' has been run
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
components: rustfmt
|
||||
- uses: actions/checkout@v3
|
||||
- run: cargo fmt -- --check
|
||||
|
||||
min_version:
|
||||
name: Minimum supported rust version
|
||||
runs-on: ubuntu-18.04
|
||||
runs-on: ubuntu-20.04
|
||||
needs: crate_metadata
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install rust toolchain (v${{ env.MIN_SUPPORTED_RUST_VERSION }})
|
||||
uses: actions-rs/toolchain@v1
|
||||
- name: Install rust toolchain (v${{ needs.crate_metadata.outputs.msrv }})
|
||||
uses: dtolnay/rust-toolchain@master
|
||||
with:
|
||||
toolchain: ${{ env.MIN_SUPPORTED_RUST_VERSION }}
|
||||
default: true
|
||||
profile: minimal # minimal component installation (ie, no documentation)
|
||||
components: clippy, rustfmt
|
||||
|
||||
- name: Ensure `cargo fmt` has been run
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: -- --check
|
||||
|
||||
toolchain: ${{ needs.crate_metadata.outputs.msrv }}
|
||||
components: clippy
|
||||
- name: Run clippy (on minimum supported rust version to prevent warnings we can't fix)
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: clippy
|
||||
args: --locked --all-targets
|
||||
|
||||
run: cargo clippy --locked --all-targets ${{ env.MSRV_FEATURES }}
|
||||
- name: Run tests
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
args: --locked
|
||||
run: cargo test --locked ${{ env.MSRV_FEATURES }}
|
||||
|
||||
build:
|
||||
name: ${{ matrix.job.os }} (${{ matrix.job.target }})
|
||||
name: ${{ matrix.job.target }} (${{ matrix.job.os }})
|
||||
runs-on: ${{ matrix.job.os }}
|
||||
needs: crate_metadata
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
job:
|
||||
- { os: ubuntu-18.04, target: arm-unknown-linux-gnueabihf , use-cross: true }
|
||||
- { os: ubuntu-18.04, target: aarch64-unknown-linux-gnu , use-cross: true }
|
||||
- { os: ubuntu-18.04, target: i686-unknown-linux-gnu , use-cross: true }
|
||||
- { os: ubuntu-18.04, target: i686-unknown-linux-musl , use-cross: true }
|
||||
- { os: ubuntu-18.04, target: x86_64-unknown-linux-gnu }
|
||||
- { os: ubuntu-18.04, target: x86_64-unknown-linux-musl , use-cross: true }
|
||||
- { os: macos-10.15 , target: x86_64-apple-darwin }
|
||||
# - { os: windows-2019, target: i686-pc-windows-gnu } ## disabled; error: linker `i686-w64-mingw32-gcc` not found
|
||||
- { os: windows-2019, target: i686-pc-windows-msvc }
|
||||
- { os: windows-2019, target: x86_64-pc-windows-gnu }
|
||||
- { os: windows-2019, target: x86_64-pc-windows-msvc }
|
||||
- { target: aarch64-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true }
|
||||
- { target: arm-unknown-linux-gnueabihf , os: ubuntu-20.04, use-cross: true }
|
||||
- { target: arm-unknown-linux-musleabihf, os: ubuntu-20.04, use-cross: true }
|
||||
- { target: i686-pc-windows-msvc , os: windows-2019 }
|
||||
- { target: i686-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true }
|
||||
- { target: i686-unknown-linux-musl , os: ubuntu-20.04, use-cross: true }
|
||||
- { target: x86_64-apple-darwin , os: macos-12 }
|
||||
- { target: x86_64-pc-windows-gnu , os: windows-2019 }
|
||||
- { target: x86_64-pc-windows-msvc , os: windows-2019 }
|
||||
- { target: x86_64-unknown-linux-gnu , os: ubuntu-20.04, use-cross: true }
|
||||
- { target: x86_64-unknown-linux-musl , os: ubuntu-20.04, use-cross: true }
|
||||
env:
|
||||
BUILD_CMD: cargo
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install prerequisites
|
||||
shell: bash
|
||||
run: |
|
||||
case ${{ matrix.job.target }} in
|
||||
arm-unknown-linux-gnueabihf) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
|
||||
arm-unknown-linux-*) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
|
||||
aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;;
|
||||
esac
|
||||
|
||||
- name: Extract crate information
|
||||
shell: bash
|
||||
run: |
|
||||
echo "PROJECT_NAME=$(sed -n 's/^name = "\(.*\)"/\1/p' Cargo.toml | head -n1)" >> $GITHUB_ENV
|
||||
echo "PROJECT_VERSION=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n1)" >> $GITHUB_ENV
|
||||
echo "PROJECT_MAINTAINER=$(sed -n 's/^authors = \["\(.*\)"\]/\1/p' Cargo.toml)" >> $GITHUB_ENV
|
||||
echo "PROJECT_HOMEPAGE=$(sed -n 's/^homepage = "\(.*\)"/\1/p' Cargo.toml)" >> $GITHUB_ENV
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: stable
|
||||
target: ${{ matrix.job.target }}
|
||||
override: true
|
||||
profile: minimal # minimal component installation (ie, no documentation)
|
||||
targets: ${{ matrix.job.target }}
|
||||
|
||||
- name: Install cross
|
||||
if: matrix.job.use-cross
|
||||
uses: taiki-e/install-action@v2
|
||||
with:
|
||||
tool: cross
|
||||
|
||||
- name: Overwrite build command env variable
|
||||
if: matrix.job.use-cross
|
||||
shell: bash
|
||||
run: echo "BUILD_CMD=cross" >> $GITHUB_ENV
|
||||
|
||||
- name: Show version information (Rust, cargo, GCC)
|
||||
shell: bash
|
||||
@@ -104,21 +122,16 @@ jobs:
|
||||
rustc -V
|
||||
|
||||
- name: Build
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
use-cross: ${{ matrix.job.use-cross }}
|
||||
command: build
|
||||
args: --release --target=${{ matrix.job.target }}
|
||||
shell: bash
|
||||
run: $BUILD_CMD build --locked --release --target=${{ matrix.job.target }}
|
||||
|
||||
- name: Run example
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
use-cross: ${{ matrix.job.use-cross }}
|
||||
command: run
|
||||
args: --release --target=${{ matrix.job.target }} --example=simple
|
||||
if: ${{ !matrix.job.use-cross }}
|
||||
shell: bash
|
||||
run: $BUILD_CMD run --release --target=${{ matrix.job.target }} --example=simple
|
||||
|
||||
- name: Strip debug information from executable
|
||||
id: strip
|
||||
- name: Set binary name & path
|
||||
id: bin
|
||||
shell: bash
|
||||
run: |
|
||||
# Figure out suffix of binary
|
||||
@@ -127,31 +140,13 @@ jobs:
|
||||
*-pc-windows-*) EXE_suffix=".exe" ;;
|
||||
esac;
|
||||
|
||||
# Figure out what strip tool to use if any
|
||||
STRIP="strip"
|
||||
case ${{ matrix.job.target }} in
|
||||
arm-unknown-linux-gnueabihf) STRIP="arm-linux-gnueabihf-strip" ;;
|
||||
aarch64-unknown-linux-gnu) STRIP="aarch64-linux-gnu-strip" ;;
|
||||
*-pc-windows-msvc) STRIP="" ;;
|
||||
esac;
|
||||
|
||||
# Setup paths
|
||||
BIN_DIR="${{ env.CICD_INTERMEDIATES_DIR }}/stripped-release-bin/"
|
||||
mkdir -p "${BIN_DIR}"
|
||||
BIN_NAME="${{ env.PROJECT_NAME }}${EXE_suffix}"
|
||||
BIN_PATH="${BIN_DIR}/${BIN_NAME}"
|
||||
BIN_NAME="${{ needs.crate_metadata.outputs.name }}${EXE_suffix}"
|
||||
BIN_PATH="target/${{ matrix.job.target }}/release/${BIN_NAME}"
|
||||
|
||||
# Copy the release build binary to the result location
|
||||
cp "target/${{ matrix.job.target }}/release/${BIN_NAME}" "${BIN_DIR}"
|
||||
|
||||
# Also strip if possible
|
||||
if [ -n "${STRIP}" ]; then
|
||||
"${STRIP}" "${BIN_PATH}"
|
||||
fi
|
||||
|
||||
# Let subsequent steps know where to find the (stripped) bin
|
||||
echo ::set-output name=BIN_PATH::${BIN_PATH}
|
||||
echo ::set-output name=BIN_NAME::${BIN_NAME}
|
||||
# Let subsequent steps know where to find the binary
|
||||
echo "BIN_PATH=${BIN_PATH}" >> $GITHUB_OUTPUT
|
||||
echo "BIN_NAME=${BIN_NAME}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Set testing options
|
||||
id: test-options
|
||||
@@ -159,44 +154,41 @@ jobs:
|
||||
run: |
|
||||
# test only library unit tests and binary for arm-type targets
|
||||
unset CARGO_TEST_OPTIONS
|
||||
unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--lib --bin ${PROJECT_NAME}" ;; esac;
|
||||
echo ::set-output name=CARGO_TEST_OPTIONS::${CARGO_TEST_OPTIONS}
|
||||
unset CARGO_TEST_OPTIONS ; case ${{ matrix.job.target }} in arm-* | aarch64-*) CARGO_TEST_OPTIONS="--lib --bin ${{ needs.crate_metadata.outputs.name }}" ;; esac;
|
||||
echo "CARGO_TEST_OPTIONS=${CARGO_TEST_OPTIONS}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Run tests
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
use-cross: ${{ matrix.job.use-cross }}
|
||||
command: test
|
||||
args: --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}}
|
||||
shell: bash
|
||||
run: $BUILD_CMD test --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}}
|
||||
|
||||
- name: Setup Pandoc
|
||||
uses: r-lib/actions/setup-pandoc@v2
|
||||
|
||||
- name: Generate man page
|
||||
run: pandoc -s -f markdown -t man -o "doc/${{ env.PROJECT_NAME }}.1" "doc/${{ env.PROJECT_NAME }}.1.md"
|
||||
run: pandoc -s -f markdown -t man -o "doc/${{ needs.crate_metadata.outputs.name }}.1" "doc/${{ needs.crate_metadata.outputs.name }}.1.md"
|
||||
|
||||
- name: Create tarball
|
||||
id: package
|
||||
shell: bash
|
||||
run: |
|
||||
PKG_suffix=".tar.gz" ; case ${{ matrix.job.target }} in *-pc-windows-*) PKG_suffix=".zip" ;; esac;
|
||||
PKG_BASENAME=${PROJECT_NAME}-v${PROJECT_VERSION}-${{ matrix.job.target }}
|
||||
PKG_BASENAME=${{ needs.crate_metadata.outputs.name }}-v${{ needs.crate_metadata.outputs.version }}-${{ matrix.job.target }}
|
||||
PKG_NAME=${PKG_BASENAME}${PKG_suffix}
|
||||
echo ::set-output name=PKG_NAME::${PKG_NAME}
|
||||
echo "PKG_NAME=${PKG_NAME}" >> $GITHUB_OUTPUT
|
||||
|
||||
PKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/package"
|
||||
ARCHIVE_DIR="${PKG_STAGING}/${PKG_BASENAME}/"
|
||||
mkdir -p "${ARCHIVE_DIR}"
|
||||
|
||||
# Binary
|
||||
cp "${{ steps.strip.outputs.BIN_PATH }}" "$ARCHIVE_DIR"
|
||||
|
||||
# Man page
|
||||
cp "doc/${{ env.PROJECT_NAME }}.1" "$ARCHIVE_DIR"
|
||||
cp "${{ steps.bin.outputs.BIN_PATH }}" "$ARCHIVE_DIR"
|
||||
|
||||
# README, LICENSE and CHANGELOG files
|
||||
cp "README.md" "LICENSE-MIT" "LICENSE-APACHE" "CHANGELOG.md" "$ARCHIVE_DIR"
|
||||
|
||||
# Man page
|
||||
cp "doc/${{ needs.crate_metadata.outputs.name }}.1" "$ARCHIVE_DIR"
|
||||
|
||||
# base compressed package
|
||||
pushd "${PKG_STAGING}/" >/dev/null
|
||||
case ${{ matrix.job.target }} in
|
||||
@@ -206,7 +198,7 @@ jobs:
|
||||
popd >/dev/null
|
||||
|
||||
# Let subsequent steps know where to find the compressed package
|
||||
echo ::set-output name=PKG_PATH::"${PKG_STAGING}/${PKG_NAME}"
|
||||
echo "PKG_PATH=${PKG_STAGING}/${PKG_NAME}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Create Debian package
|
||||
id: debian-package
|
||||
@@ -218,10 +210,10 @@ jobs:
|
||||
DPKG_DIR="${DPKG_STAGING}/dpkg"
|
||||
mkdir -p "${DPKG_DIR}"
|
||||
|
||||
DPKG_BASENAME=${PROJECT_NAME}
|
||||
DPKG_CONFLICTS=${PROJECT_NAME}-musl
|
||||
case ${{ matrix.job.target }} in *-musl) DPKG_BASENAME=${PROJECT_NAME}-musl ; DPKG_CONFLICTS=${PROJECT_NAME} ;; esac;
|
||||
DPKG_VERSION=${PROJECT_VERSION}
|
||||
DPKG_BASENAME=${{ needs.crate_metadata.outputs.name }}
|
||||
DPKG_CONFLICTS=${{ needs.crate_metadata.outputs.name }}-musl
|
||||
case ${{ matrix.job.target }} in *-musl) DPKG_BASENAME=${{ needs.crate_metadata.outputs.name }}-musl ; DPKG_CONFLICTS=${{ needs.crate_metadata.outputs.name }} ;; esac;
|
||||
DPKG_VERSION=${{ needs.crate_metadata.outputs.version }}
|
||||
|
||||
unset DPKG_ARCH
|
||||
case ${{ matrix.job.target }} in
|
||||
@@ -233,14 +225,14 @@ jobs:
|
||||
esac;
|
||||
|
||||
DPKG_NAME="${DPKG_BASENAME}_${DPKG_VERSION}_${DPKG_ARCH}.deb"
|
||||
echo ::set-output name=DPKG_NAME::${DPKG_NAME}
|
||||
echo "DPKG_NAME=${DPKG_NAME}" >> $GITHUB_OUTPUT
|
||||
|
||||
# Binary
|
||||
install -Dm755 "${{ steps.strip.outputs.BIN_PATH }}" "${DPKG_DIR}/usr/bin/${{ steps.strip.outputs.BIN_NAME }}"
|
||||
install -Dm755 "${{ steps.bin.outputs.BIN_PATH }}" "${DPKG_DIR}/usr/bin/${{ steps.bin.outputs.BIN_NAME }}"
|
||||
|
||||
# Man page
|
||||
install -Dm644 "doc/${{ env.PROJECT_NAME }}.1" "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1"
|
||||
gzip -n --best "${DPKG_DIR}/usr/share/man/man1/${{ env.PROJECT_NAME }}.1"
|
||||
install -Dm644 'doc/${{ needs.crate_metadata.outputs.name }}.1' "${DPKG_DIR}/usr/share/man/man1/${{ needs.crate_metadata.outputs.name }}.1"
|
||||
gzip -n --best "${DPKG_DIR}/usr/share/man/man1/${{ needs.crate_metadata.outputs.name }}.1"
|
||||
|
||||
# README and LICENSE
|
||||
install -Dm644 "README.md" "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/README.md"
|
||||
@@ -251,12 +243,12 @@ jobs:
|
||||
|
||||
cat > "${DPKG_DIR}/usr/share/doc/${DPKG_BASENAME}/copyright" <<EOF
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: ${{ env.PROJECT_NAME }}
|
||||
Source: ${{ env.PROJECT_HOMEPAGE }}
|
||||
Upstream-Name: ${{ needs.crate_metadata.outputs.name }}
|
||||
Source: ${{ needs.crate_metadata.outputs.homepage }}
|
||||
|
||||
Files: *
|
||||
Copyright: ${{ env.PROJECT_MAINTAINER }}
|
||||
Copyright: $COPYRIGHT_YEARS ${{ env.PROJECT_MAINTAINER }}
|
||||
Copyright: ${{ needs.crate_metadata.outputs.maintainer }}
|
||||
Copyright: $COPYRIGHT_YEARS ${{ needs.crate_metadata.outputs.maintainer }}
|
||||
License: Apache-2.0 or MIT
|
||||
|
||||
License: Apache-2.0
|
||||
@@ -297,16 +289,16 @@ jobs:
|
||||
Version: ${DPKG_VERSION}
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Maintainer: ${{ env.PROJECT_MAINTAINER }}
|
||||
Homepage: ${{ env.PROJECT_HOMEPAGE }}
|
||||
Maintainer: ${{ needs.crate_metadata.outputs.maintainer }}
|
||||
Homepage: ${{ needs.crate_metadata.outputs.homepage }}
|
||||
Architecture: ${DPKG_ARCH}
|
||||
Provides: ${{ env.PROJECT_NAME }}
|
||||
Provides: ${{ needs.crate_metadata.outputs.name }}
|
||||
Conflicts: ${DPKG_CONFLICTS}
|
||||
Description: colorized hex viewer for the terminal.
|
||||
Description: A command-line benchmarking tool
|
||||
EOF
|
||||
|
||||
DPKG_PATH="${DPKG_STAGING}/${DPKG_NAME}"
|
||||
echo ::set-output name=DPKG_PATH::${DPKG_PATH}
|
||||
echo "DPKG_PATH=${DPKG_PATH}" >> $GITHUB_OUTPUT
|
||||
|
||||
# build dpkg
|
||||
fakeroot dpkg-deb --build "${DPKG_DIR}" "${DPKG_PATH}"
|
||||
@@ -329,7 +321,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
unset IS_RELEASE ; if [[ $GITHUB_REF =~ ^refs/tags/v[0-9].* ]]; then IS_RELEASE='true' ; fi
|
||||
echo ::set-output name=IS_RELEASE::${IS_RELEASE}
|
||||
echo "IS_RELEASE=${IS_RELEASE}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Publish archives and packages
|
||||
uses: softprops/action-gh-release@v1
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
# v0.13.0
|
||||
|
||||
## Features
|
||||
|
||||
- Support both little and big Endian dumps using `--endianness={little,big}`, see #189 and #104 (@RinHizakura)
|
||||
|
||||
## Changes
|
||||
|
||||
- **Breaking**: Changed the meaning of the short flag `-C` to be consistent with `hexdump -C`. Previously, this would *hide* the character panel, but now `-C` *shows* the character panel, in case it has been previously (e.g. in an `alias`) disabled with `--no-characters`, see #187 (@sharkdp)
|
||||
|
||||
## `hexyl` as a library
|
||||
|
||||
- New `endianness` method for `PrinterBuilder`
|
||||
|
||||
|
||||
# v0.12.0
|
||||
|
||||
## Features
|
||||
|
||||
Generated
+1
-1
@@ -200,7 +200,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "hexyl"
|
||||
version = "0.12.0"
|
||||
version = "0.13.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"assert_cmd",
|
||||
|
||||
+2
-1
@@ -7,8 +7,9 @@ license = "MIT/Apache-2.0"
|
||||
name = "hexyl"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/sharkdp/hexyl"
|
||||
version = "0.12.0"
|
||||
version = "0.13.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.60"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
|
||||
+47
-5
@@ -17,7 +17,7 @@ use thiserror::Error as ThisError;
|
||||
|
||||
use terminal_size::terminal_size;
|
||||
|
||||
use hexyl::{Base, BorderStyle, Input, PrinterBuilder};
|
||||
use hexyl::{Base, BorderStyle, Endianness, Input, PrinterBuilder};
|
||||
|
||||
const DEFAULT_BLOCK_SIZE: i64 = 512;
|
||||
|
||||
@@ -128,10 +128,17 @@ fn run() -> Result<()> {
|
||||
))
|
||||
.arg(
|
||||
Arg::new("no_chars")
|
||||
.short('C')
|
||||
.long("no-characters")
|
||||
.action(ArgAction::SetFalse)
|
||||
.help("Whether to display the character panel on the right."),
|
||||
.help("Do not show the character panel on the right."),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("chars")
|
||||
.short('C')
|
||||
.long("characters")
|
||||
.overrides_with("no_chars")
|
||||
.action(ArgAction::SetTrue)
|
||||
.help("Show the character panel on the right. This is the default, unless --no-characters has been specified."),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("no_position")
|
||||
@@ -174,10 +181,34 @@ fn run() -> Result<()> {
|
||||
.value_name("N")
|
||||
.help(
|
||||
"Number of bytes/octets that should be grouped together. \
|
||||
Possible group sizes are 1, 2, 4, 8. The default is 1. \
|
||||
'--groupsize can be used as an alias (xxd-compatibility).",
|
||||
Possible group sizes are 1, 2, 4, 8. The default is 1. You \
|
||||
can use the '--endianness' option to control the ordering of \
|
||||
the bytes within a group. '--groupsize' can be used as an \
|
||||
alias (xxd-compatibility).",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("endianness")
|
||||
.long("endianness")
|
||||
.num_args(1)
|
||||
.value_name("FORMAT")
|
||||
.value_parser(["big", "little"])
|
||||
.default_value("big")
|
||||
.help(
|
||||
"Whether to print out groups in little-endian or big-endian \
|
||||
format. This option only has an effect if the '--group-size' \
|
||||
is larger than 1. '-e' can be used as an alias for \
|
||||
'--endianness=little'.",
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("little_endian_format")
|
||||
.short('e')
|
||||
.action(ArgAction::SetTrue)
|
||||
.overrides_with("endianness")
|
||||
.hide(true)
|
||||
.help("An alias for '--endianness=little'."),
|
||||
)
|
||||
.arg(
|
||||
Arg::new("base")
|
||||
.short('b')
|
||||
@@ -425,6 +456,16 @@ fn run() -> Result<()> {
|
||||
)
|
||||
};
|
||||
|
||||
let little_endian_format = *matches.get_one::<bool>("little_endian_format").unwrap();
|
||||
let endianness = matches.get_one::<String>("endianness");
|
||||
let endianness = match (
|
||||
endianness.map(|s| s.as_ref()).unwrap(),
|
||||
little_endian_format,
|
||||
) {
|
||||
(_, true) | ("little", _) => Endianness::Little,
|
||||
("big", _) => Endianness::Big,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let stdout = io::stdout();
|
||||
let mut stdout_lock = BufWriter::new(stdout.lock());
|
||||
|
||||
@@ -437,6 +478,7 @@ fn run() -> Result<()> {
|
||||
.num_panels(panels)
|
||||
.group_size(group_size)
|
||||
.with_base(base)
|
||||
.endianness(endianness)
|
||||
.build();
|
||||
printer.display_offset(skip_offset + display_offset);
|
||||
printer.print_all(&mut reader).map_err(|e| anyhow!(e))?;
|
||||
|
||||
+42
-1
@@ -21,6 +21,7 @@ const COLOR_ASCII_OTHER: &[u8] = colors::Green::ANSI_FG.as_bytes();
|
||||
const COLOR_NONASCII: &[u8] = colors::Yellow::ANSI_FG.as_bytes();
|
||||
const COLOR_RESET: &[u8] = colors::Default::ANSI_FG.as_bytes();
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum ByteCategory {
|
||||
Null,
|
||||
AsciiPrintable,
|
||||
@@ -29,6 +30,12 @@ pub enum ByteCategory {
|
||||
NonAscii,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Endianness {
|
||||
Little,
|
||||
Big,
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum Squeezer {
|
||||
Print,
|
||||
@@ -159,6 +166,7 @@ pub struct PrinterBuilder<'a, Writer: Write> {
|
||||
panels: u64,
|
||||
group_size: u8,
|
||||
base: Base,
|
||||
endianness: Endianness,
|
||||
}
|
||||
|
||||
impl<'a, Writer: Write> PrinterBuilder<'a, Writer> {
|
||||
@@ -173,6 +181,7 @@ impl<'a, Writer: Write> PrinterBuilder<'a, Writer> {
|
||||
panels: 2,
|
||||
group_size: 1,
|
||||
base: Base::Hexadecimal,
|
||||
endianness: Endianness::Big,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,6 +225,11 @@ impl<'a, Writer: Write> PrinterBuilder<'a, Writer> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn endianness(mut self, endianness: Endianness) -> Self {
|
||||
self.endianness = endianness;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Printer<'a, Writer> {
|
||||
Printer::new(
|
||||
self.writer,
|
||||
@@ -227,6 +241,7 @@ impl<'a, Writer: Write> PrinterBuilder<'a, Writer> {
|
||||
self.panels,
|
||||
self.group_size,
|
||||
self.base,
|
||||
self.endianness,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -254,6 +269,8 @@ pub struct Printer<'a, Writer: Write> {
|
||||
group_size: u8,
|
||||
/// The number of digits used to write the base.
|
||||
base_digits: u8,
|
||||
/// Whether to show groups in little or big endian format.
|
||||
endianness: Endianness,
|
||||
}
|
||||
|
||||
impl<'a, Writer: Write> Printer<'a, Writer> {
|
||||
@@ -267,6 +284,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
|
||||
panels: u64,
|
||||
group_size: u8,
|
||||
base: Base,
|
||||
endianness: Endianness,
|
||||
) -> Printer<'a, Writer> {
|
||||
Printer {
|
||||
idx: 0,
|
||||
@@ -304,6 +322,7 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
|
||||
Base::Decimal => 3,
|
||||
Base::Hexadecimal => 2,
|
||||
},
|
||||
endianness,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,8 +542,26 @@ impl<'a, Writer: Write> Printer<'a, Writer> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn reorder_buffer_to_little_endian(&self, buf: &mut Vec<u8>) {
|
||||
let n = buf.len();
|
||||
let group_sz = self.group_size as usize;
|
||||
|
||||
for idx in (0..n).step_by(group_sz) {
|
||||
let remaining = n - idx;
|
||||
let total = remaining.min(group_sz);
|
||||
|
||||
buf[idx..idx + total].reverse();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_bytes(&mut self) -> io::Result<()> {
|
||||
for (i, &b) in self.line_buf.clone().iter().enumerate() {
|
||||
let mut buf = self.line_buf.clone();
|
||||
|
||||
if matches!(self.endianness, Endianness::Little) {
|
||||
self.reorder_buffer_to_little_endian(&mut buf);
|
||||
};
|
||||
|
||||
for (i, &b) in buf.iter().enumerate() {
|
||||
self.print_byte(i, b)?;
|
||||
}
|
||||
Ok(())
|
||||
@@ -682,6 +719,7 @@ mod tests {
|
||||
2,
|
||||
1,
|
||||
Base::Hexadecimal,
|
||||
Endianness::Big,
|
||||
);
|
||||
|
||||
printer.print_all(input).unwrap();
|
||||
@@ -736,6 +774,7 @@ mod tests {
|
||||
2,
|
||||
1,
|
||||
Base::Hexadecimal,
|
||||
Endianness::Big,
|
||||
);
|
||||
printer.display_offset(0xdeadbeef);
|
||||
|
||||
@@ -769,6 +808,7 @@ mod tests {
|
||||
4,
|
||||
1,
|
||||
Base::Hexadecimal,
|
||||
Endianness::Big,
|
||||
);
|
||||
|
||||
printer.print_all(input).unwrap();
|
||||
@@ -828,6 +868,7 @@ mod tests {
|
||||
3,
|
||||
1,
|
||||
Base::Hexadecimal,
|
||||
Endianness::Big,
|
||||
);
|
||||
|
||||
printer.print_all(input).unwrap();
|
||||
|
||||
@@ -292,12 +292,12 @@ mod display_settings {
|
||||
}
|
||||
}
|
||||
|
||||
mod group {
|
||||
mod group_and_endianness {
|
||||
use super::hexyl;
|
||||
use super::PrettyAssert;
|
||||
|
||||
#[test]
|
||||
fn group_2_bytes() {
|
||||
fn group_2_bytes_be() {
|
||||
hexyl()
|
||||
.arg("ascii")
|
||||
.arg("--color=never")
|
||||
@@ -312,7 +312,23 @@ mod group {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_4_bytes() {
|
||||
fn group_2_bytes_le() {
|
||||
hexyl()
|
||||
.arg("ascii")
|
||||
.arg("--color=never")
|
||||
.arg("--group-size=2")
|
||||
.arg("--endianness=little")
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(
|
||||
"┌────────┬─────────────────────┬─────────────────────┬────────┬────────┐\n\
|
||||
│00000000│ 3130 3332 3534 3736 ┊ 3938 6261 6463 0a65 │01234567┊89abcde_│\n\
|
||||
└────────┴─────────────────────┴─────────────────────┴────────┴────────┘\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_4_bytes_be() {
|
||||
hexyl()
|
||||
.arg("ascii")
|
||||
.arg("--color=never")
|
||||
@@ -327,7 +343,23 @@ mod group {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_8_bytes() {
|
||||
fn group_4_bytes_le() {
|
||||
hexyl()
|
||||
.arg("ascii")
|
||||
.arg("--color=never")
|
||||
.arg("--group-size=4")
|
||||
.arg("--endianness=little")
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(
|
||||
"┌────────┬───────────────────┬───────────────────┬────────┬────────┐\n\
|
||||
│00000000│ 33323130 37363534 ┊ 62613938 0a656463 │01234567┊89abcde_│\n\
|
||||
└────────┴───────────────────┴───────────────────┴────────┴────────┘\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_8_bytes_be() {
|
||||
hexyl()
|
||||
.arg("ascii")
|
||||
.arg("--color=never")
|
||||
@@ -341,6 +373,22 @@ mod group {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_8_bytes_le() {
|
||||
hexyl()
|
||||
.arg("ascii")
|
||||
.arg("--color=never")
|
||||
.arg("--group-size=8")
|
||||
.arg("--endianness=little")
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(
|
||||
"┌────────┬──────────────────┬──────────────────┬────────┬────────┐\n\
|
||||
│00000000│ 3736353433323130 ┊ 0a65646362613938 │01234567┊89abcde_│\n\
|
||||
└────────┴──────────────────┴──────────────────┴────────┴────────┘\n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn group_size_plain() {
|
||||
hexyl()
|
||||
|
||||
Reference in new issue
Block a user