pax_global_header00006660000000000000000000000064146347516470014533gustar00rootroot0000000000000052 comment=35516080b31afd516603b6756866d195674fb64d lsb-release-minimal-12.1/000077500000000000000000000000001463475164700153005ustar00rootroot00000000000000lsb-release-minimal-12.1/.gitignore000066400000000000000000000000751463475164700172720ustar00rootroot00000000000000# Generated files lsb_release.1 # Vim temporary files *.sw* lsb-release-minimal-12.1/.woodpecker.yaml000066400000000000000000000020761463475164700204110ustar00rootroot00000000000000when: - event: [push, pull_request, manual] steps: - name: check-dash image: codeberg.org/gioele/lsb-release-minimal:debian-12 commands: - make check depends_on: [] - name: check-bash image: codeberg.org/gioele/lsb-release-minimal:debian-12 commands: - apt install --quiet --no-install-recommends bash - ln -s bash /usr/bin/sh.new && mv /usr/bin/sh.new /usr/bin/sh - /bin/sh -c 'test "$${BASH_VERSION:-x}" != "x"' - make check - name: check-busybox image: codeberg.org/gioele/lsb-release-minimal:debian-12 commands: - apt install --quiet --no-install-recommends busybox - ln -s busybox /usr/bin/sh.new && mv /usr/bin/sh.new /usr/bin/sh - /bin/sh -c 'test "$${BASH_VERSION:-x}" = "x"' - make check - name: check-mksh image: codeberg.org/gioele/lsb-release-minimal:debian-12 commands: - apt install --quiet --no-install-recommends mksh - ln -s lksh /usr/bin/sh.new && mv /usr/bin/sh.new /usr/bin/sh - /bin/sh -c 'test "$${KSH_VERSION:-x}" != "x"' - make check lsb-release-minimal-12.1/LICENSE.txt000066400000000000000000000013431463475164700171240ustar00rootroot00000000000000Copyright (c) 2021-2024 Gioele Barabucci Permission to use, copy, modify, and/or 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. lsb-release-minimal-12.1/Makefile000066400000000000000000000015601463475164700167420ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2021 Gioele Barabucci # SPDX-License-Identifier: ISC VERSION = 12.1 # Paths prefix = /usr exec_prefix = $(prefix) bindir = $(prefix)/bin datarootdir = $(prefix)/share mandir = $(datarootdir)/man # Programs and options BATS = bats INSTALL = install POD2MAN = pod2man POD2MAN_OPTS = --center="User Commands" --release="lsb_release $(VERSION)" SHELLCHECK = shellcheck SHELLCHECK_OPTS = -e SC1090 -x # Genrated files MANPAGE = lsb_release.1 GENERATED_FILES = $(MANPAGE) all: $(GENERATED_FILES) %.1: %.pod $(POD2MAN) $(POD2MAN_OPTS) $< > $@ check: $(SHELLCHECK) $(SHELLCHECK_OPTS) lsb_release $(BATS) lsb_release.bats @echo "All checks passed" clean: rm -f $(GENERATED_FILES) install: all $(INSTALL) -D lsb_release $(DESTDIR)$(bindir)/lsb_release $(INSTALL) -D $(MANPAGE) -m 0444 -t $(DESTDIR)$(mandir)/man1/ .PHONY: all check clean install lsb-release-minimal-12.1/README.md000066400000000000000000000014141463475164700165570ustar00rootroot00000000000000# lsb-release-minimal This repository contains a bare-bones version of the `lsb_release` command, implemented as a tiny POSIX shell script (less than 100 lines of commented code). Instead of using LSB packages, this version of `lsb_release` uses the information in `/etc/os-release`. Nevertheless, the output of this version is byte-for-byte compatible with the Python-based version provided by Debian and its derivatives. Using this implementation it is possible to avoid installing Python in a base OS image while still retaining compatibility with older scripts that expect `lsb_release` to exist. ## Authors * Gioele Barabucci https://gioele.io ## License This is free software released under the terms of the ISC license. See the `LICENCE.txt` file for more details. lsb-release-minimal-12.1/lsb_release000077500000000000000000000054221463475164700175110ustar00rootroot00000000000000#!/bin/sh # SPDX-FileCopyrightText: 2021 Gioele Barabucci # SPDX-License-Identifier: ISC set -eu export LC_ALL="C.UTF-8" help () { cat <<-EOD Usage: lsb_release [options] Options: -h, --help show this help message and exit -v, --version show LSB modules this system supports -i, --id show distributor ID -d, --description show description of this distribution -r, --release show release number of this distribution -c, --codename show code name of this distribution -a, --all show all of the above information -s, --short show requested information in short format EOD } show_warning=false show_id=false show_desc=false show_release=false show_codename=false short_format=false options=$(getopt --name lsb_release -o hvidrcas -l help,version,id,description,release,codename,all,short -- "$@") || exit 2 eval set -- "$options" [ "$1" = "--" ] && show_warning=true while [ $# -gt 0 ] ; do case "$1" in -h|--help) help; exit ;; -v|--version) show_warning=true ;; -i|--id) show_id=true ;; -d|--description) show_desc=true ;; -r|--release) show_release=true ;; -c|--codename) show_codename=true ;; -a|--all) show_warning=true; show_id=true; show_desc=true; show_release=true; show_codename=true ;; -s|--short) short_format=true ;; --) ;; *) { help; echo; echo "lsb_release: error: No arguments are permitted"; } >&2; exit 2 esac shift done display_line () { label="$1" value="$2" if $short_format ; then printf "%s\n" "$value" else printf "%s:\t%s\n" "$label" "$value" fi } # Load release info from standard identification data files [ -f /usr/lib/os-release ] && os_release=/usr/lib/os-release [ -f /etc/os-release ] && os_release=/etc/os-release [ "${LSB_OS_RELEASE-x}" != "x" ] && [ -f "$LSB_OS_RELEASE" ] && os_release="$LSB_OS_RELEASE" [ "${os_release-x}" != "x" ] && . "$os_release" # Mimic the output of Debian's Python-based lsb_release # Capitalize ID : "${ID=}" ID="$(printf "%s" "$ID" | cut -c1 | tr '[:lower:]' '[:upper:]')$(printf "%s" "$ID" | cut -c2-)" # Use NAME if set and different from ID only in capitalization. if [ "${NAME-x}" != "x" ] ; then lower_case_id=$(printf "%s" "$ID" | tr '[:upper:]' '[:lower:]') lower_case_name=$(printf "%s" "$NAME" | tr '[:upper:]' '[:lower:]') if [ "${lower_case_id}" = "${lower_case_name}" ] ; then ID="$NAME" fi fi # Generate minimal standard-conform output (if stdout is a TTY). [ -t 1 ] && $show_warning && echo "No LSB modules are available." >&2 if $show_id ; then display_line "Distributor ID" "${ID:-n/a}" fi if $show_desc ; then display_line "Description" "${PRETTY_NAME:-n/a}" fi if $show_release ; then display_line "Release" "${VERSION_ID:-n/a}" fi if $show_codename ; then display_line "Codename" "${VERSION_CODENAME:-n/a}" fi lsb-release-minimal-12.1/lsb_release.bats000066400000000000000000000155061463475164700204420ustar00rootroot00000000000000#!/usr/bin/env bats bats_require_minimum_version 1.5.0 bats_load_library "bats-support" bats_load_library "bats-assert" LSB_RELEASE="$BATS_TEST_DIRNAME/lsb_release" assert_equal_ws () { local s1=$(echo "$1" | sed -E -e '/\s+/ /') local s2=$(echo "$2" | sed -E -e '/\s+/ /') [ "$s1" = "$s2" ] && return 0 echo "expected '$s2', got '$s1'" >&2 return 1 } assert_equal_fields () { local fields_got=$(echo "$1" | cut -f2) ; shift oIFS="$IFS" ; IFS="$(printf '\n ')" ; local fields_expected="$*" ; IFS="$oIFS" assert_equal "$fields_got" "$fields_expected" } assert_equal_fields_ws () { local fields_got=$(echo "$1" | cut -f2) ; shift oIFS="$IFS" ; IFS="$(printf '\n ')" ; local fields_expected="$*" ; IFS="$oIFS" assert_equal_ws "$fields_got" "$fields_expected" } skip_if_no_unicode () { if [ "$(echo 'åβ' | cut -c1)" != "β" ]; then skip "\`cut\` and \`tr\` are not yet Unicode-aware" fi } run_in_prog () { run --separate-stderr "$@" } run_in_tty () { local stderr_file="$BATS_TEST_TMPDIR/stderr" run --separate-stderr sh -c "script -eqfc \"sh -c '$* 2>$stderr_file'\" /dev/null ; cat $stderr_file >&2" echo "$BASH_RUN_COMMAND" } @test "No output without options" { export LSB_OS_RELEASE="$BATS_TEST_TMPDIR/os-release" echo "$OS_RELEASE_UBUNTU_2204" > "$LSB_OS_RELEASE" run_in_prog $LSB_RELEASE assert_equal "$status" "0" assert_equal "$output" "" assert_equal "$stderr" "" } @test "LSB modules warning is displayed for -a, -v, or with no args, when run in a tty" { export LSB_OS_RELEASE="$BATS_TEST_TMPDIR/os-release" echo "$OS_RELEASE_UBUNTU_2204" > "$LSB_OS_RELEASE" run_in_tty $LSB_RELEASE assert_equal "$status" "0" assert_not_equal "$stderr" "" run_in_tty $LSB_RELEASE -a assert_equal "$status" "0" assert_not_equal "$stderr" "" run_in_tty $LSB_RELEASE -v assert_equal "$status" "0" assert_not_equal "$stderr" "" } @test "LSB modules warning is not displayed when run in a tty" { export LSB_OS_RELEASE="$BATS_TEST_TMPDIR/os-release" echo "$OS_RELEASE_UBUNTU_2204" > "$LSB_OS_RELEASE" run_in_tty $LSB_RELEASE -i assert_equal "$status" "0" assert_equal "$stderr" "" run_in_tty $LSB_RELEASE -d assert_equal "$status" "0" assert_equal "$stderr" "" run_in_tty $LSB_RELEASE -r assert_equal "$status" "0" assert_equal "$stderr" "" run_in_tty $LSB_RELEASE -c assert_equal "$status" "0" assert_equal "$stderr" "" } @test "Fields are read from os-release" { export LSB_OS_RELEASE="$BATS_TEST_TMPDIR/os-release" echo "$OS_RELEASE_UBUNTU_2204" > "$LSB_OS_RELEASE" run_in_prog $LSB_RELEASE -a assert_equal "$status" "0" assert_equal_fields "$output" "Ubuntu" "Ubuntu 20.04.4 LTS" "20.04" "focal" assert_equal "$stderr" "" } @test "Fields are reported as n/a if missing" { export LSB_OS_RELEASE="$BATS_TEST_TMPDIR/os-release" echo "$OS_RELEASE_DEBIAN_SID" > "$LSB_OS_RELEASE" run_in_prog $LSB_RELEASE -a assert_equal "$status" "0" assert_equal_fields "$output" "Debian" "Debian GNU/Linux bookworm/sid" "n/a" "n/a" assert_equal "$stderr" "" } @test "All fields are reported as n/a if missing" { export LSB_OS_RELEASE="$BATS_TEST_TMPDIR/os-release" echo "" > "$LSB_OS_RELEASE" run_in_prog $LSB_RELEASE -a assert_equal "$status" "0" assert_equal_fields "$output" "n/a" "n/a" "n/a" "n/a" assert_equal "$stderr" "" } @test "Only ID is shown with -i" { export LSB_OS_RELEASE="$BATS_TEST_TMPDIR/os-release" echo "$OS_RELEASE_UBUNTU_2204" > "$LSB_OS_RELEASE" run_in_prog $LSB_RELEASE -i assert_equal "$status" "0" assert_equal_ws "$output" "Distributor ID: Ubuntu" assert_equal "$stderr" "" } @test "Only Description is shown with -d" { export LSB_OS_RELEASE="$BATS_TEST_TMPDIR/os-release" echo "$OS_RELEASE_UBUNTU_2204" > "$LSB_OS_RELEASE" run_in_prog $LSB_RELEASE -d assert_equal "$status" "0" assert_equal_ws "$output" "Description: Ubuntu 20.04.4 LTS" assert_equal "$stderr" "" } @test "Only Release is shown with -r" { export LSB_OS_RELEASE="$BATS_TEST_TMPDIR/os-release" echo "$OS_RELEASE_UBUNTU_2204" > "$LSB_OS_RELEASE" run_in_prog $LSB_RELEASE -r assert_equal "$status" "0" assert_equal_ws "$output" "Release: 20.04" assert_equal "$stderr" "" } @test "Only Codename is shown with -c" { export LSB_OS_RELEASE="$BATS_TEST_TMPDIR/os-release" echo "$OS_RELEASE_UBUNTU_2204" > "$LSB_OS_RELEASE" run_in_prog $LSB_RELEASE -c assert_equal "$status" "0" assert_equal_ws "$output" "Codename: focal" assert_equal "$stderr" "" } @test "Multiple fields are showns when multiple options are passed" { export LSB_OS_RELEASE="$BATS_TEST_TMPDIR/os-release" echo "$OS_RELEASE_UBUNTU_2204" > "$LSB_OS_RELEASE" run_in_prog $LSB_RELEASE -c -i assert_equal "$status" "0" assert_equal_fields_ws "$output" "Distributor ID: Ubuntu" "Codename: focal" assert_equal "$stderr" "" } @test "Field names are not shown when --short is passed" { export LSB_OS_RELEASE="$BATS_TEST_TMPDIR/os-release" echo "$OS_RELEASE_UBUNTU_2204" > "$LSB_OS_RELEASE" run_in_prog $LSB_RELEASE -c -i --short assert_equal "$status" "0" assert_equal_fields "$output" "Ubuntu" "focal" assert_equal "$stderr" "" } @test "Name is preferred to ID if only different in capitalization" { export LSB_OS_RELEASE="$BATS_TEST_TMPDIR/os-release" cat > "$LSB_OS_RELEASE" < "$LSB_OS_RELEASE" run_in_prog $LSB_RELEASE -i --short assert_equal "$status" "0" assert_equal_fields "$output" "Đεбıå№" assert_equal "$stderr" "" } @test "Non-ASCII data in ID/NAME is correctly handled" { skip_if_no_unicode export LSB_OS_RELEASE="$BATS_TEST_TMPDIR/os-release" echo "$OS_RELEASE_UNICODE" > "$LSB_OS_RELEASE" echo 'NAME="đεБIå№"' >> "$LSB_OS_RELEASE" run_in_prog $LSB_RELEASE -i --short assert_equal "$status" "0" assert_equal_fields "$output" "đεБIå№" assert_equal "$stderr" "" } # Fixtures OS_RELEASE_DEBIAN_SID=$(cat < I<[options]> =head1 DESCRIPTION This is a bare-bones version of the B command, implemented as a tiny POSIX shell script (less than 100 lines of commented code). Instead of using LSB packages, this version of B uses the information in F and F. Nevertheless, the output of this version is byte-for-byte compatible with the Python-based version provided by Debian and its derivatives. Using this implementation it is possible to avoid installing Python in a base OS image while still retaining compatibility with older scripts that expect B to exist. =head1 OPTIONS The program follows the usual GNU command line syntax, with long options starting with two dashes (C<-->). A summary of options are included below. =over 4 =item B<-h>, B<--help> Show a help message with a list of options and exit. =item B<-v>, B<--version> Show LSB modules this system supports. =item B<-i>, B<--id> Show distributor ID. =item B<-d>, B<--description> Show description of this distribution. =item B<-r>, B<--release> Show release number of this distribution. =item B<-c>, B<--codename> Show code name of this distribution. =item B<-a>, B<--all> Show all of the above information. =item B<-s>, B<--short> Show requested information in short format. =back =head1 FILES =over 4 =item F Distribution-provided file with operating system identification data. =item F Machine-specific file with operating system identification data. If present, F is read instead of F. =back =head1 SEE ALSO L =head1 AUTHOR Gioele Barabucci L =head1 LICENSE This implementation of B is free software released under the terms of the ISC license.