|
| 1 | +#!/bin/bash |
| 2 | +set -euxC |
| 3 | + |
| 4 | +target="$1" |
| 5 | +test -n "$target" |
| 6 | + |
| 7 | +# Arrange for the indirect `tzdata` dependency to be installed and configured |
| 8 | +# without prompting for the time zone. (Passing `-y` is not enough.) |
| 9 | +export DEBIAN_FRONTEND=noninteractive TZ=UTC |
| 10 | + |
| 11 | +# Install tools for setting up APT repositores. Install `apt-utils` before the |
| 12 | +# others, so the installation of `gnupg` can use it for debconf. |
| 13 | +apt-get update |
| 14 | +apt-get install --no-install-recommends -y apt-utils |
| 15 | +apt-get install --no-install-recommends -y apt-transport-https dpkg-dev gnupg |
| 16 | +type dpkg-architecture # Make sure we really have this. |
| 17 | + |
| 18 | +# Decide what architecture to use for `git`, shared libraries `git` links to, |
| 19 | +# and shared libraries gitoxide links to when building `max`. Instead of this |
| 20 | +# custom logic, we could use `$CROSS_DEB_ARCH`, which `cross` tries to provide |
| 21 | +# (https://github.com/cross-rs/cross/blob/v0.2.5/src/lib.rs#L268), and which is |
| 22 | +# available for roughly the same architectures where this logic gets a nonempty |
| 23 | +# value. But using `$CROSS_DEB_ARCH` may make it harder to build and test the |
| 24 | +# image manually. In particular, if it is not passed, we would conclude that we |
| 25 | +# should install the versions of those packages with the host's architecture. |
| 26 | +apt_suffix= |
| 27 | +if target_arch="$(dpkg-architecture --host-type "$target" --query DEB_HOST_ARCH)" |
| 28 | +then |
| 29 | + dpkg --add-architecture "$target_arch" |
| 30 | + apt_suffix=":$target_arch" |
| 31 | + printf 'INFO: Using target architecture for `git` and libs in container.\n' |
| 32 | + printf 'INFO: This architecture is %s.\n' "$target_arch" |
| 33 | +else |
| 34 | + apt_suffix='' |
| 35 | + printf 'WARNING: Using HOST architecture for `git` and libs in container.\n' |
| 36 | +fi |
| 37 | + |
| 38 | +# Get release codename. Like `lsb_release -sc`. (`lsb_release` may be absent.) |
| 39 | +release="$(sed -n 's/^VERSION_CODENAME=//p' /etc/os-release)" |
| 40 | + |
| 41 | +# Add the git-core PPA manually. (Faster than installing `add-apt-repository`.) |
| 42 | +echo "deb https://ppa.launchpadcontent.net/git-core/ppa/ubuntu $release main" \ |
| 43 | + >/etc/apt/sources.list.d/git-core-ubuntu-ppa.list |
| 44 | +apt-key adv --keyserver keyserver.ubuntu.com \ |
| 45 | + --recv-keys F911AB184317630C59970973E363C90F8F1B6217 |
| 46 | +apt-get update |
| 47 | + |
| 48 | +# Remove the old `git` and associated packages. |
| 49 | +apt-get purge --autoremove -y git |
| 50 | + |
| 51 | +# Git dependencies. These are for the desired architecture, except `git-man` is |
| 52 | +# the same package for all architectures, and we can't always install `perl` or |
| 53 | +# `liberror-perl` for the desired architecture (at least in s390x). |
| 54 | +# TODO(maint): Resolve these dynamically to support future `cross` base images. |
| 55 | +git_deps=( |
| 56 | + git-man |
| 57 | + "libc6$apt_suffix" |
| 58 | + "libcurl3-gnutls$apt_suffix" |
| 59 | + "libexpat1$apt_suffix" |
| 60 | + liberror-perl |
| 61 | + "libpcre2-8-0$apt_suffix" |
| 62 | + "zlib1g$apt_suffix" |
| 63 | + perl |
| 64 | +) |
| 65 | + |
| 66 | +# Other dependencies for running the gitoxide test suite and fixture scripts, |
| 67 | +# and for building and testing gitoxide for feature sets beyond `max-pure`. |
| 68 | +gix_test_deps=( |
| 69 | + ca-certificates |
| 70 | + cmake |
| 71 | + "curl$apt_suffix" |
| 72 | + jq |
| 73 | + "libc-dev$apt_suffix" |
| 74 | + "libssl-dev$apt_suffix" |
| 75 | + patch |
| 76 | + pkgconf |
| 77 | +) |
| 78 | + |
| 79 | +if test -n "$apt_suffix"; then |
| 80 | + # Install everything we need except `git` (and what we already have). We |
| 81 | + # can't necessarily install `git` this way, because it insists on `perl` |
| 82 | + # and `liberror-perl` dependencies of the same architecture as it. These |
| 83 | + # may not be possible to install in a mixed environment, where most |
| 84 | + # packages are a different architecture, and where `perl` is a dependency |
| 85 | + # of other important packages. So we will install everything else first |
| 86 | + # (then manually add `git`). |
| 87 | + apt-get install --no-install-recommends -y \ |
| 88 | + "${git_deps[@]}" "${gix_test_deps[@]}" file |
| 89 | + |
| 90 | + # Add `git` by manually downloading it and installing it with `dpkg`, |
| 91 | + # forcing installation to proceed even if its `perl` and `liberror-perl` |
| 92 | + # dependencies, as declared by `git`, are absent. (We have already |
| 93 | + # installed them, but in a possibly different architecture. `git` can still |
| 94 | + # use them, because its use is to run scripts, rather than to link to a |
| 95 | + # shared library they provide.) It is preferred to let `apt-get download` |
| 96 | + # drop privileges to the `_apt` user during download, so we download it |
| 97 | + # inside `/tmp`. But we create a subdirectory so it is safe to make |
| 98 | + # assumptions about what files globs can expand to, even if `/tmp` is |
| 99 | + # mounted to an outside share temp dir on a multi-user system. |
| 100 | + mkdir /tmp/dl # Don't use `-p`; if it exists already, we cannot trust it. |
| 101 | + chown _apt /tmp/dl # Use owner, as the container may have no `_apt` group. |
| 102 | + (cd /tmp/dl && apt-get download "git$apt_suffix") |
| 103 | + dpkg --ignore-depends="perl$apt_suffix,liberror-perl$apt_suffix" \ |
| 104 | + -i /tmp/dl/git[-_]*.deb |
| 105 | + rm -r /tmp/dl |
| 106 | +else |
| 107 | + # Install everything we need, including `git`. |
| 108 | + apt-get install --no-install-recommends -y git "${gix_test_deps[@]}" file |
| 109 | +fi |
| 110 | + |
| 111 | +# Show information about the newly installed `git` (and ensure it can run). |
| 112 | +git version --build-options |
| 113 | +git="$(command -v git)" |
| 114 | +file -- "$git" |
| 115 | + |
| 116 | +# Clean up files related to package management that we won't need anymore. |
| 117 | +apt-get clean |
| 118 | +rm -rf /var/lib/apt/lists/* |
| 119 | + |
| 120 | +# If this image has a runner script `cross` uses for Android, patch the script |
| 121 | +# to add the ability to suppress its customization of `LD_PRELOAD`. The runner |
| 122 | +# script sets `LD_PRELOAD` to the path of `libc++_shared.so` in the Android NDK |
| 123 | +# (https://github.com/cross-rs/cross/blob/v0.2.5/docker/android-runner#L34). |
| 124 | +# But this causes a problem for us. When a host-architecture program is run, |
| 125 | +# `ld.so` shows a message about the "wrong ELF class". Such programs can still |
| 126 | +# run, but when we rely on their specific output to stderr, fixtures and tests |
| 127 | +# fail. The change we make here lets us set `NO_PRELOAD_CXX=1` to avoid that. |
| 128 | +runner=/android-runner |
| 129 | +patch='s/^[[:blank:]]*export LD_PRELOAD=/test "${NO_PRELOAD_CXX:-0}" != 0 || &/' |
| 130 | +if test -f "$runner"; then sed -i.orig "$patch" -- "$runner"; fi |
| 131 | + |
| 132 | +# Ensure a nonempty Git `system` scope (for the `installation_config` tests). |
| 133 | +git config --system gitoxide.imaginary.arbitraryVariable arbitraryValue |
0 commit comments