diff --git a/lenses/aptsources822.aug b/lenses/aptsources822.aug new file mode 100644 index 000000000..ba6d67d97 --- /dev/null +++ b/lenses/aptsources822.aug @@ -0,0 +1,104 @@ +(* +Module: Aptsources822 + Augeas module for sources list (Deb822 style) for Apt package manager + +Authors: + James Valleroy + Sunil Mohan Adapa + +About: Reference + 1. Deb822(5): + https://manpages.debian.org/bullseye/dpkg-dev/deb822.5.en.html + 2. sources.list(5): + https://manpages.debian.org/bullseye/apt/sources.list.5.en.html + +About: License + This file is licensed under the LGPLv2+, like the rest of Augeas. + +About: Configuration files + This lens applies to files in /etc/apt/sources.list.d/ ending with the + extension .sources. See . + +*) + + +module Aptsources822 = + +autoload xfm + +(* Variable: single_value_field_name + Names of known fields for which only a single value is allowed. *) +let single_value_field_name = /(Enabled|PDiffs|By-Hash|Allow-Insecure|Allow-Weak|Allow-Downgrade-To-Insecure|Trusted|Check-Valid-Until|Valid-Until-Min|Valid-Until-Max|Check-Date|Date-Max-Future|InRelease-Path)/ + +(* Variable: multi_value_field_name + Names of known fields for which multiple values are allowed and names of + unknown fields. Unknown fields are assumed to contain multiple values as + that is the safest assumption. + + According to deb822(5) man page, "The field name is composed of US-ASCII + characters excluding control characters, space, and colon (i.e., characters + in the ranges U+0021 ‘!’ through U+0039 ‘9’, and U+003B ‘;’ through U+007E + ‘~’, inclusive). Field names must not begin with the comment character + (U+0023 ‘#’), nor with the hyphen character (U+002D ‘-’)." *) +let multi_value_field_name = /[!"$-,.-9;-~][!-9;-~]*/ - single_value_field_name + +(* Variable: field_value + Value that a field can contain. Deb822 styles sources list files defines some + fields to have multiple values separated by space, tab or a newline. *) +let field_value = /[!-Z\\^-~][!-Z\\^-~]*/ + +(* Variable: empty_line + Lens for an empty line separating two stanzas. It can't be a comment. Only + tabs and spaces are allowed. *) +let empty_line = Util.empty_generic /[ \t]*/ + +(* Variable: name_value_separator + Lens for separating a name and value. Field name is followed by a ':' and + then optionally space. The file format also allow for a value to be on a + new line when the new line starts with space or a tab. *) +let name_value_separator = Sep.colon . del (Rx.opt_space . /(\n[ \t])?/) " " + +(* Variable: field_value_with_newline + Lens for value that followed by a new line and a space. This indicates that + another value follows it. *) +let field_value_with_newline = [seq "item" . store (field_value . /\n/) . + del /[\t ]/ " "] + +(* Variable: field_value_with_separator + Lens for value that followed by a space or a tab. This indicates that another + value follows it. *) +let field_value_with_separator = [seq "item" . store field_value . del Rx.space " "] + +(* Variable: field_value_with_eol + Lens for value that followed by an end-of-line. This indicates that this is + the last value for this field. *) +let field_value_with_eol = [seq "item" . store field_value . Util.eol] + +(* Variable: single_value_field + Lens for a field (field name, separator and field value) with only a single + value. *) +let single_value_field = [ key single_value_field_name . name_value_separator . + store field_value . Util.eol ] + +(* Variable: multi_value_field + Lens for a field (field name, separator and field value) with multiple values + *) +let multi_value_field = [ key multi_value_field_name . name_value_separator . + counter "item" . (field_value_with_newline | field_value_with_separator)* . + field_value_with_eol ] + +(* Variable: stanza + Lens for a stanza that describes one or more sources for apt. *) +let stanza = [ seq "source" . (single_value_field | multi_value_field | + Util.comment_noindent)+ ] + +(* Variable: lns + Lens for parsing the entire apt sources file in Deb822 format. *) +let lns = stanza . (empty_line . stanza)* + +(* Variable: filter + All files in the sources.list.d directory are files describing sources. + However, only those ending with .sources extension are in Deb822 format. *) +let filter = incl "/etc/apt/sources.list.d/*.sources" + +let xfm = transform lns filter diff --git a/lenses/tests/test_aptsources822.aug b/lenses/tests/test_aptsources822.aug new file mode 100644 index 000000000..0c4b10d12 --- /dev/null +++ b/lenses/tests/test_aptsources822.aug @@ -0,0 +1,120 @@ +module Test_Aptsources822 = + +(* Test multiple values, multi-line values and multiple source stanzas *) +let sources1 = "Enabled: yes +Types: deb deb-src +URIs: http://deb.debian.org/debian +Suites: bullseye + bullseye-backports +Components: main non-free-firmware +Allow-Insecure: no +Signed-By: + -----BEGIN PGP PUBLIC KEY BLOCK----- + . + mDMEYCQjIxYJKwYBBAHaRw8BAQdAD/P5Nvvnvk66SxBBHDbhRml9ORg1WV5CvzKY + CuMfoIS0BmFiY2RlZoiQBBMWCgA4FiEErCIG1VhKWMWo2yfAREZd5NfO31cFAmAk + IyMCGyMFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQREZd5NfO31fbOwD6ArzS + dM0Dkd5h2Ujy1b6KcAaVW9FOa5UNfJ9FFBtjLQEBAJ7UyWD3dZzhvlaAwunsk7DG + 3bHcln8DMpIJVXht78sL + =IE0r + -----END PGP PUBLIC KEY BLOCK----- + +Enabled: no +URIs: http://dl.google.com/linux/chrome/deb +Suites: stable +Components: main +Architectures: amd64 +" +test Aptsources822.lns get sources1 = + { "1" + { "Enabled" = "yes" } + { "Types" + { "1" = "deb" } + { "2" = "deb-src" } + } + { "URIs" { "1" = "http://deb.debian.org/debian" } } + { "Suites" + { "1" = "bullseye\n" } + { "2" = "bullseye-backports" } + } + { "Components" + { "1" = "main" } + { "2" = "non-free-firmware" } + } + { "Allow-Insecure" = "no" } + { "Signed-By" + { "1" = "-----BEGIN" } + { "2" = "PGP" } + { "3" = "PUBLIC" } + { "4" = "KEY" } + { "5" = "BLOCK-----\n" } + { "6" = ".\n" } + { "7" = "mDMEYCQjIxYJKwYBBAHaRw8BAQdAD/P5Nvvnvk66SxBBHDbhRml9ORg1WV5CvzKY\n" } + { "8" = "CuMfoIS0BmFiY2RlZoiQBBMWCgA4FiEErCIG1VhKWMWo2yfAREZd5NfO31cFAmAk\n" } + { "9" = "IyMCGyMFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQREZd5NfO31fbOwD6ArzS\n" } + { "10" = "dM0Dkd5h2Ujy1b6KcAaVW9FOa5UNfJ9FFBtjLQEBAJ7UyWD3dZzhvlaAwunsk7DG\n" } + { "11" = "3bHcln8DMpIJVXht78sL\n" } + { "12" = "=IE0r\n" } + { "13" = "-----END" } + { "14" = "PGP" } + { "15" = "PUBLIC" } + { "16" = "KEY" } + { "17" = "BLOCK-----" } + } + } + { } + { "2" + { "Enabled" = "no" } + { "URIs" { "1" = "http://dl.google.com/linux/chrome/deb" } } + { "Suites" { "1" = "stable" } } + { "Components" { "1" = "main" } } + { "Architectures" { "1" = "amd64" } } + } + +let sources2 = "Enabled: yes +Types: deb deb-src +URIs: http://archive.ubuntu.com/ubuntu +Suites: disco disco-updates disco-security disco-backports +Components: main universe multiverse restricted + +Enabled: yes +Types: deb +URIs: http://ppa.launchpad.net/system76/pop/ubuntu +Suites: disco +Components: main +" +test Aptsources822.lns get sources2 = + { "1" + { "Enabled" = "yes" } + { "Types" + { "1" = "deb" } + { "2" = "deb-src" } + } + { "URIs" { "1" = "http://archive.ubuntu.com/ubuntu" } } + { "Suites" + { "1" = "disco" } + { "2" = "disco-updates" } + { "3" = "disco-security" } + { "4" = "disco-backports" } + } + { "Components" + { "1" = "main" } + { "2" = "universe" } + { "3" = "multiverse" } + { "4" = "restricted" } + } + } + { } + { "2" + { "Enabled" = "yes" } + { "Types" { "1" = "deb" } } + { "URIs" { "1" = "http://ppa.launchpad.net/system76/pop/ubuntu" } } + { "Suites" { "1" = "disco" } } + { "Components" { "1" = "main" } } + } + +(* Test adding nodes to tree *) +test Aptsources822.lns put "Types: deb\n" after set "/1/Enabled" "yes" = "Types: deb\nEnabled: yes\n" +test Aptsources822.lns put "Types: deb\n" after + set "/1/URIs/1" "uri1\n"; + set "/1/URIs/2" "uri2" = "Types: deb\nURIs: uri1\n uri2\n" diff --git a/tests/Makefile.am b/tests/Makefile.am index b5f29f50b..98182f48a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -30,6 +30,7 @@ lens_tests = \ lens-aptpreferences.sh \ lens-aptconf.sh \ lens-aptsources.sh \ + lens-aptsources822.sh \ lens-authinfo2.sh \ lens-authorized_keys.sh \ lens-authselectpam.sh \