diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000000..9befa73fa39 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,36 @@ +FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04 + +# install gnu coreutils test dependencies +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + attr \ + autoconf \ + automake \ + autopoint \ + bison \ + g++ \ + gcc \ + gdb \ + gperf \ + jq \ + libacl1-dev \ + libattr1-dev \ + libcap-dev \ + libexpect-perl \ + libselinux1-dev \ + python3-pyinotify \ + quilt \ + texinfo \ + valgrind \ + && rm -rf /var/lib/apt/lists/* + +# install dependencies for uutils +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + clang \ + gdb \ + python3-pip \ + && rm -rf /var/lib/apt/lists/* + +# pre-commit +RUN pip3 install --break-system-packages pre-commit diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000000..dab74a3082a --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,50 @@ +{ + "name": "uutils-devcontainer", + "build": { + "dockerfile": "Dockerfile" + }, + "features": { + "ghcr.io/devcontainers/features/rust:1": + { + "version": "latest", + "profile": "default", + "components": "llvm-tools-preview" + } + }, + "onCreateCommand": { + "install pre-commit hooks": "pre-commit install", + "update permissions for gnu coreutils volume": "sudo chown vscode:vscode ${containerWorkspaceFolder}/../gnu" + }, + "mounts": [ + { + "source": "devcontainer-gnu-coreutils-${devcontainerId}", + "target": "${containerWorkspaceFolder}/../gnu", + "type": "volume" + } + ], + "customizations": { + "vscode": { + "extensions": [ + "streetsidesoftware.code-spell-checker", + "foxundermoon.shell-format", + "ms-vscode.cpptools" + ], + "settings": { + "rust-analyzer.check.command": "clippy", + "rust-analyzer.debug.engine": "ms-vscode.cpptools", + "rust-analyzer.debug.engineSettings": { + "cppdbg": { + "miDebuggerPath": "rust-gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": false + } + ] + } + } + } + } + } +} diff --git a/.github/workflows/devcontainer.yml b/.github/workflows/devcontainer.yml new file mode 100644 index 00000000000..cbc0d0f87af --- /dev/null +++ b/.github/workflows/devcontainer.yml @@ -0,0 +1,34 @@ +name: Devcontainer + +# spell-checker:ignore devcontainers nextest + +on: + pull_request: + push: + branches: + - '*' + +permissions: + contents: read # to fetch code (actions/checkout) + +# End the current execution if there is a new changeset in the PR. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +jobs: + test: + name: Verify devcontainer + runs-on: ubuntu-latest + timeout-minutes: 45 + steps: + - uses: actions/checkout@v5 + with: + persist-credentials: false + - name: Run test in devcontainer + uses: devcontainers/ci@v0.3 + with: + push: never + runCmd: | + curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin + cargo nextest run --hide-progress-bar --profile ci diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c4c511210c4..91847f96bd1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,6 +7,7 @@ repos: - id: check-added-large-files - id: check-executables-have-shebangs - id: check-json + exclude: '.vscode/cSpell\.json' # cSpell.json uses comments - id: check-shebang-scripts-are-executable exclude: '.+\.rs' # would be triggered by #![some_attribute] - id: check-symlinks diff --git a/.vscode/cSpell.json b/.vscode/cSpell.json index 51dd4a30ce9..bd58ee1d230 100644 --- a/.vscode/cSpell.json +++ b/.vscode/cSpell.json @@ -28,7 +28,8 @@ "vendor/**", "**/*.svg", "src/uu/*/locales/*.ftl", - "src/uucore/locales/*.ftl" + "src/uucore/locales/*.ftl", + ".devcontainer/**" ], "enableGlobDot": true, diff --git a/.vscode/settings.json b/.vscode/settings.json index 54df63a5b40..74447bc9101 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1 +1,5 @@ -{ "cSpell.import": [".vscode/cspell.json"] } +{ + "cSpell.import": [ + "./.vscode/cSpell.json" + ] +} diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 6091c394fc4..912af1ca9a4 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -25,6 +25,9 @@ This section will explain how to install and configure these tools. We also have an extensive CI that uses these tools and will check your code before it can be merged. The next section [Testing](#testing) will explain how to run those checks locally to avoid waiting for the CI. +As an alternative to host installation of the tools, you can open the project with the provided development container configuration. +For more information about development containers, see the [Visual Studio Code Dev Containers documentation](https://code.visualstudio.com/docs/devcontainers/containers). + ### Rust toolchain [Install Rust](https://www.rust-lang.org/tools/install) diff --git a/tests/by-util/test_dd.rs b/tests/by-util/test_dd.rs index 74701e962ce..be556c93f04 100644 --- a/tests/by-util/test_dd.rs +++ b/tests/by-util/test_dd.rs @@ -1559,7 +1559,9 @@ fn test_skip_past_dev() { // NOTE: This test intends to trigger code which can only be reached with root permissions. let ts = TestScenario::new(util_name!()); - if let Ok(result) = run_ucmd_as_root_with_stdin_stdout( + if !ts.fixtures.file_exists("/dev/sda1") { + print!("Test skipped; no /dev/sda1 device found"); + } else if let Ok(result) = run_ucmd_as_root_with_stdin_stdout( &ts, &["bs=1", "skip=10000000000000000", "count=0", "status=noxfer"], Some("/dev/sda1"), @@ -1581,7 +1583,9 @@ fn test_seek_past_dev() { // NOTE: This test intends to trigger code which can only be reached with root permissions. let ts = TestScenario::new(util_name!()); - if let Ok(result) = run_ucmd_as_root_with_stdin_stdout( + if !ts.fixtures.file_exists("/dev/sda1") { + print!("Test skipped; no /dev/sda1 device found"); + } else if let Ok(result) = run_ucmd_as_root_with_stdin_stdout( &ts, &["bs=1", "seek=10000000000000000", "count=0", "status=noxfer"], None, diff --git a/util/build-gnu.sh b/util/build-gnu.sh index e9a54998654..ae85dc63fc2 100755 --- a/util/build-gnu.sh +++ b/util/build-gnu.sh @@ -71,7 +71,9 @@ fi release_tag_GNU="v9.7" -if test ! -d "${path_GNU}"; then +# check if the GNU coreutils has been cloned, if not print instructions +# note: the ${path_GNU} might already exist, so we check for the .git directory +if test ! -d "${path_GNU}/.git"; then echo "Could not find GNU coreutils (expected at '${path_GNU}')" echo "Run the following to download into the expected path:" echo "git clone --recurse-submodules https://github.com/coreutils/coreutils.git \"${path_GNU}\"" @@ -136,7 +138,7 @@ cd - touch g echo "stat with selinux support" ./target/debug/stat -c%C g || true - +rm g cp "${UU_BUILD_DIR}/install" "${UU_BUILD_DIR}/ginstall" # The GNU tests rename this script before running, to avoid confusion with the make target # Create *sum binaries