From 6acdf9b94bade1097db03e5a926cfb9fe388fc68 Mon Sep 17 00:00:00 2001 From: "Luke A. Guest" Date: Thu, 31 Jul 2025 20:32:58 +0100 Subject: [PATCH 01/20] Add Gentoo and Portage into the platforms and package managers. --- src/alire/alire-platforms.ads | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/alire/alire-platforms.ads b/src/alire/alire-platforms.ads index bf879bd7d..460b61df5 100644 --- a/src/alire/alire-platforms.ads +++ b/src/alire/alire-platforms.ads @@ -44,6 +44,7 @@ package Alire.Platforms with Preelaborate is Suse, Homebrew, Macports, + Gentoo, Distribution_Unknown); subtype Known_Distributions is @@ -61,6 +62,7 @@ package Alire.Platforms with Preelaborate is Zypper, Homebrew, Macports, + Portage, Packager_Unknown); Distro_Manager : constant array (Distributions) of Package_Managers := @@ -71,6 +73,7 @@ package Alire.Platforms with Preelaborate is Suse => Zypper, Homebrew => Homebrew, Macports => Macports, + Gentoo => Portage, Distribution_Unknown => Packager_Unknown); type Toolchains is (System, From 00d04925bce662a108c3933f3b6bf06db51e0110 Mon Sep 17 00:00:00 2001 From: "Luke A. Guest" Date: Thu, 31 Jul 2025 20:34:01 +0100 Subject: [PATCH 02/20] Add a new package to support portage on Gentoo. --- ...alire-origins-deployers-system-portage.adb | 140 ++++++++++++++++++ ...alire-origins-deployers-system-portage.ads | 18 +++ 2 files changed, 158 insertions(+) create mode 100644 src/alire/alire-origins-deployers-system-portage.adb create mode 100644 src/alire/alire-origins-deployers-system-portage.ads diff --git a/src/alire/alire-origins-deployers-system-portage.adb b/src/alire/alire-origins-deployers-system-portage.adb new file mode 100644 index 000000000..a4cfb693a --- /dev/null +++ b/src/alire/alire-origins-deployers-system-portage.adb @@ -0,0 +1,140 @@ +with Ada.Characters.Latin_1; +with AAA.Strings; use AAA.Strings; + +with Alire.Errors; +with Alire.OS_Lib.Subprocess; +-- with Alire.Utils.Regex; + +package body Alire.Origins.Deployers.System.Portage is + + package L1 renames Ada.Characters.Latin_1; + package Subprocess renames Alire.OS_Lib.Subprocess; + + ----------------------- + -- Already_Installed -- + ----------------------- + + overriding function Already_Installed (This : Deployer) return Boolean + is + -- The following call is faster than using emerge. + Output : constant AAA.Strings.Vector := + Subprocess.Checked_Spawn_And_Capture + ("eix", + Empty_Vector & "-ce" & This.Base.Package_Name, + -- Check the category (A), + -- whether it is installed (I) and + -- match against the exact string (e). + -- i.e. "app-editors/zed" + Valid_Exit_Codes => (1, 0), -- returns 1 when not found + Err_To_Out => True); + + Indicator : constant String := "[I]"; + Line : constant String := AAA.Strings.First_Element (Output); + begin + Trace.Info ("Already_Installed: " & This.Base.Package_Name); + + return (if Line (Line'First .. Line'First + Indicator'Length) = Indicator + then True else False); + end Already_Installed; + + function To_Semantic_Version (Gentoo_Version : String) return String is + Tmp : String := Gentoo_Version; + begin + for C in Tmp'Range loop + -- Format: 0.0.0_release-rc9 + if Tmp (C) = L1.Low_Line then + Tmp (C) := L1.Hyphen; + + Trace.Info ("To_Semantic_Version: " & Tmp); + + return Tmp; + end if; + end loop; + + Trace.Info ("To_Semantic_Version: " & Tmp); + + return Tmp; + end To_Semantic_Version; + + ------------ + -- Detect -- + ------------ + + overriding + function Detect (This : Deployer) return Version_Outcomes.Outcome + is + function Split_Version (Gentoo_Package_Version : String) return String is + begin + for Index in Gentoo_Package_Version'Range loop + if Gentoo_Package_Version (Index) = L1.Hyphen then + return Gentoo_Package_Version + (Index + 1 .. Gentoo_Package_Version'Last); + end if; + end loop; + + return ""; + end Split_Version; + pragma Unreferenced (Split_Version); + + PortageQ_Output : constant AAA.Strings.Vector := + Subprocess.Checked_Spawn_And_Capture + ("portageq", + Empty_Vector & "best_visible" & "/" & + This.Base.Package_Name, + Valid_Exit_Codes => (0, 1), -- Returned when not found + Err_To_Out => True); + -- portageq should *always* produce zero or one line result. + + Output : constant AAA.Strings.Vector := + Subprocess.Checked_Spawn_And_Capture + ("qatom", + Empty_Vector & "-F%{PVR}" & + First_Element (PortageQ_Output), + Valid_Exit_Codes => (0, 1), -- Returned when not found + Err_To_Out => True); + Gentoo_Version : constant String := First_Element (Output); + + -- Regexp : constant String := + -- "[0-9]+(\.[0-9]+)*[a-z](_[a-z]+[0-9]?)*(-r[0-9]*)*"; + -- From the pms.pdf. + begin + if Gentoo_Version /= "" then + Trace.Info ("Detect: " & This.Base.Package_Name & " - " & + Gentoo_Version & " - " & To_Semantic_Version (Gentoo_Version) & + " => " & Semantic_Versioning.Parse + (To_Semantic_Version (Gentoo_Version), + Relaxed => True).Image); + + return + Version_Outcomes.New_Result + (Semantic_Versioning.Parse + (To_Semantic_Version (Gentoo_Version), Relaxed => True)); + end if; + + Trace.Debug ("System deployer could not detect: " & This.Base.Image); + return Version_Outcomes.Outcome_Failure ("could not be detected", + Report => False); + end Detect; + + ------------- + -- Install -- + ------------- + + overriding + function Install (This : Deployer) return Outcome is + begin + Trace.Info ("Install: " & This.Base.Package_Name); + + Subprocess.Checked_Spawn + ("sudo", Empty_Vector & + "emerge" & + "-av" & + This.Base.Package_Name); + + return Outcome_Success; + exception + when E : others => + return Alire.Errors.Get (E); + end Install; + +end Alire.Origins.Deployers.System.Portage; diff --git a/src/alire/alire-origins-deployers-system-portage.ads b/src/alire/alire-origins-deployers-system-portage.ads new file mode 100644 index 000000000..7ddd69bc3 --- /dev/null +++ b/src/alire/alire-origins-deployers-system-portage.ads @@ -0,0 +1,18 @@ +package Alire.Origins.Deployers.System.Portage is + + type Deployer is new Deployers.System.Deployer with null record; + + overriding + function Already_Installed (This : Deployer) return Boolean; + + overriding + function Detect (This : Deployer) + return Version_Outcomes.Outcome; + + overriding + function Install (This : Deployer) return Outcome; + + overriding + function Executable_Name (This : Deployer) return String is ("apt"); + +end Alire.Origins.Deployers.System.Portage; From 24357e3bddd99dc646d9c02d2317bc878d262ea6 Mon Sep 17 00:00:00 2001 From: "Luke A. Guest" Date: Thu, 31 Jul 2025 20:34:23 +0100 Subject: [PATCH 03/20] Hook in Gentoo/Portage into the Deployers --- src/alire/alire-origins-deployers-system.adb | 5 +++++ src/alire/alire-utils-tools.adb | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/alire/alire-origins-deployers-system.adb b/src/alire/alire-origins-deployers-system.adb index 521e2f3d7..e282b8e24 100644 --- a/src/alire/alire-origins-deployers-system.adb +++ b/src/alire/alire-origins-deployers-system.adb @@ -1,4 +1,5 @@ with Alire.Origins.Deployers.System.Apt; +with Alire.Origins.Deployers.System.Portage; with Alire.Origins.Deployers.System.Homebrew; with Alire.Origins.Deployers.System.Macports; with Alire.Origins.Deployers.System.Pacman; @@ -11,6 +12,7 @@ with Alire.Toolchains; with CLIC.User_Input; with GNAT.IO; +-- with System; package body Alire.Origins.Deployers.System is @@ -118,6 +120,9 @@ package body Alire.Origins.Deployers.System is when Platforms.Macports => System.Macports.Deployer'(Deployers.Deployer'(Base => From) with others => <>), + when Platforms.Portage => + System.Portage.Deployer'(Deployers.Deployer'(Base => From) + with others => <>), when Platforms.Packager_Unknown => System.Unknown.Deployer'(Deployers.Deployer'(Base => From) with others => <>) diff --git a/src/alire/alire-utils-tools.adb b/src/alire/alire-utils-tools.adb index 2e7241c5e..014abe81d 100644 --- a/src/alire/alire-utils-tools.adb +++ b/src/alire/alire-utils-tools.adb @@ -59,7 +59,7 @@ package body Alire.Utils.Tools is return ""; when Msys2 | Debian | Ubuntu | Arch | Centos | Fedora | Rhel | Suse - | Homebrew | Macports => + | Homebrew | Macports | Gentoo => return (case Tool is when Easy_Graph => (if Distribution in Centos | Fedora | Rhel | Suse From ba4154d6d29cb857db88b407fcbe6b5747ff37be Mon Sep 17 00:00:00 2001 From: Alejandro R Mosteo Date: Fri, 15 Aug 2025 20:35:39 +0200 Subject: [PATCH 04/20] dev: check templates are up to date (#1995) * dev: check templates are up to date * Touch template * Better feedback * Restore touched template --- .github/workflows/ci-integrity.yml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-integrity.yml b/.github/workflows/ci-integrity.yml index b3eda88ea..eaf46637a 100644 --- a/.github/workflows/ci-integrity.yml +++ b/.github/workflows/ci-integrity.yml @@ -14,4 +14,19 @@ jobs: uses: actions/checkout@v4 - name: Verify pinned dependencies - run: scripts/verify-pins.sh \ No newline at end of file + run: scripts/verify-pins.sh + + templates: + name: Templates + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Verify templates are up to date + run: | + ( support/embedder/embedder.sh | \ + grep "No changes in templates, skipping generation" ) || \ + ( echo "Templates are not up to date, please run 'support/embedder/embedder.sh' to update them." + echo "Commit and push the changes to generated files and their hash before opening a PR." + exit 1 ) From 9f400ff6904f72b791f1d35764de6ad61f480aa8 Mon Sep 17 00:00:00 2001 From: Alejandro R Mosteo Date: Sat, 16 Aug 2025 21:26:36 +0200 Subject: [PATCH 05/20] dev: guidelines for automatic Copilot reviews (#1998) * dev: instructions for copilot reviews * Add info about testing --- .github/copilot-instructions.md | 106 ++++++++++++++++++++++++++++++++ CONTRIBUTING.md | 9 +++ src/alire/alire-errors.adb | 2 +- src/alire/alire-errors.ads | 2 +- 4 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 .github/copilot-instructions.md create mode 100644 CONTRIBUTING.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000..ae90e4f6a --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,106 @@ +# Project Overview + +This project is a command-line tool (`alr`) and a supporting library +(`libalire`) designed to manage dependencies in Ada and SPARK projects, and +related operations like initialization, building, and running tests. + +This tool fulfills a similar role as `cargo` for Rust, `go` for Go, `opam` for +OCaml, for the Ada language and its subset SPARK. + +The tool leverages an online repository of packages (crates) which is a regular +git repository at GitHub, named the "community index". + +## Folder Structure + +- `/src/alire`: Contains the source code for the library. +- `/src/alr`: Contains the source code for the command-line tool. +- `/src/templates`: Contains generated source files from templates. +- `/doc`: Contains documentation for the project, including index specification + and user guides, used also for generating the website. +- `/doc/catalog-format-spec.md`: Contains the specification for the + index format used by the project. +- `/doc/user-changes.md`: Contains notices about user-facing changes. +- `/testsuite`: Contains the test suite for the project, including unit tests + and integration tests. +- `/testsuite/tests`: Contains end-to-end tests using the Python e3-testsuite + framework. +- `/testsuite/tests_ada`: Contains unit tests written in Ada. +- `/BREAKING.md`: Contains information about breaking changes in the master + branch wrt the latest stable release. +- `/RELEASING.md`: Contains instructions for releasing a new version of the + project. +- `/RELEASING-post.md`: Contains instructions for post-release tasks. + +## Coding Standards + +- Use subprogram boxes before all top-level subprogram bodies. + +- Use subprogram boxes before non-trivial (more than 3-4 body lines) nested + subprogram bodies. + +- Use one empty line before and after subprogram boxes, and before and after + subprogram bodies. + +- Use formal English for all error messages (e.g., avoid contractions). + +- Do not have long blocks of uncommented code, even if it is trivial code. A + comment should prefix such long blocks of trivial code explaining its + purpose, with one blank line before and after. + +- Comment all complex code, no matter if it is a single line. Comments that + refer to a single statement should be immediately after the statement and + without separation (no blank line in between). + +## Implementation Practices + +- The exception `Checked_Error` is used for errors that should *not* result in + an exception backtrace being exposed to the user. This exception is caught by + the top-level exception handler, resulting in a pretty-printed error message. + `Checked_Error` is raised with `Alire.Raise_Checked_Error` so the error + message can be as long as needed (using `raise` directly has an unspecified + maximum error message length and hence is not recommended). + +- Exceptions `Child_Failed`, `Command_Failed` and `Wrong_Command_Arguments` + also result in pretty-printed error messages, but are used for specific + purposes. They do not result in observable differences but should be used + accordingly. These are never raised directly; rather they are triggered with + subprograms `Reportaise_Command_Failed` and `Reportaise_Wrong_Arguments`. + `Child_Failed` is raised by spawning subprograms when the forked process + fails. Typically, there is no need to raise this exception directly. + +- `Program_Error` is the preferred exception to be triggered for diagnosed + abnormal situations that should not occur and will result in a bug box and + exception backtrace (in verbose mode) being exposed to the user. + +- Other Ada exceptions triggered by the Ada runtime that are not handled on a + case-by-case basis are OK to be propagated but will also result in a bug box. + Hence, erroneous but expected situations should be handled (e.g., a + `Constraint_Error` when validating user inputs) and not propagated when it is + OK to exit with code 0, or re-raised as a `Checked_Error` to terminate + execution gracefully with non-zero exit code. + +- Situations that are dubious and can be considered an error, but that we want + to allow if the user is absolutely sure, can be reported with + `Alire.Recoverable_User_Error`. This will result in a checked error or just a + warning depending on whether `--force` flag is in effect. + +- Use `Alire.Recoverable_Program_Error` for anomalous situations that can + somehow be detected and recovered from, despite not being the user fault and + indicating a bug in the program. A bug box will be printed, but the program + will continue normally. This usage should be very rare. + +- Use the `Alire.Unimplemented` exception for temporary missing functionality. + In general, use of this exception should not make into the master branch. + +## Pull-request Checklist + +Before submitting a PR, ensure you have met as many as applicable of the tasks +described in `/.github/PULL_REQUEST_TEMPLATE.md`. Namely, at least: + +- Include functional tests for new features or bug fixes. See + `/testsuite/README.md` for further information. +- Include Ada unit tests for critical new subprograms, type definitions, etc. + Each unit test is a main procedure in a file in `/testsuite/tests_ada`. +- Document user-facing changes in `/doc/user-changes.md`. +- Document breaking changes in `/BREAKING.md`. +- Document index format changes in `/doc/catalog-format-spec.md`. \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..6c798f966 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,9 @@ +Contributions should normally be made via a pull-request against the main +repository at https://github.com/alire-project/alire + +Please read the guidelines at /.github/copilot-instructions.md for expected +coding practices. + +For complex or controversial contributions, please open an issue first to +gather feedback and discuss the design before starting work that might be +ultimately not accepted. \ No newline at end of file diff --git a/src/alire/alire-errors.adb b/src/alire/alire-errors.adb index 68ab2233c..0b902886a 100644 --- a/src/alire/alire-errors.adb +++ b/src/alire/alire-errors.adb @@ -231,7 +231,7 @@ package body Alire.Errors is Msg : UString; use UStrings; begin - -- Remove duplicates that may have creeped in when generating the final + -- Remove duplicates that may have crept in when generating the final -- stack: for I in Error_Stack.First_Index .. Error_Stack.Last_Index loop diff --git a/src/alire/alire-errors.ads b/src/alire/alire-errors.ads index a4a2ba596..50ae7e410 100644 --- a/src/alire/alire-errors.ads +++ b/src/alire/alire-errors.ads @@ -135,7 +135,7 @@ package Alire.Errors with Preelaborate is -- adequate, but we do not want to bomb on the user because continuing is -- acceptable. We log a stack trace, print a warning and continue, so a -- motivated user can report an issue, but we don't needlessly raise. If - -- not Survivable, then do raise a Program_Error. If Stack_Trace /= "", + -- not Recoverable, then do raise a Program_Error. If Stack_Trace /= "", -- use it instead of generating one. private From 949aa161c0b5be0128f6142928a8c2893ffbc110 Mon Sep 17 00:00:00 2001 From: Alejandro R Mosteo Date: Sat, 16 Aug 2025 21:59:48 +0200 Subject: [PATCH 06/20] fix: pass GH token in Docker tests too (#1999) --- .github/workflows/ci-docker.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-docker.yml b/.github/workflows/ci-docker.yml index c77912db0..55222ceee 100644 --- a/.github/workflows/ci-docker.yml +++ b/.github/workflows/ci-docker.yml @@ -47,7 +47,11 @@ jobs: with: image: ghcr.io/alire-project/docker/gnat:${{matrix.tag}} command: scripts/ci-github.sh use_external # Use external compiler already installed - params: -v${PWD}:/alire -w /alire + params: > + -v${PWD}:/alire + -w /alire + -e GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} + # Token required for self-update tests to not hit GH API rate limits - name: Upload logs (if failed) if: failure() From 4ae0f4eb74227d21a572c7b021c1adf11b11c82f Mon Sep 17 00:00:00 2001 From: Alejandro R Mosteo Date: Sun, 17 Aug 2025 18:40:41 +0200 Subject: [PATCH 07/20] dev: placeholder for ignoring known future properties (#2000) * Minimal spec for future property * Implementation & Test * Do not leak hidden property --- src/alire/alire-properties-from_toml.ads | 5 ++ src/alire/alire-properties-future.adb | 59 +++++++++++++++++ src/alire/alire-properties-future.ads | 50 ++++++++++++++ .../tests/index/future-compatibility/test.py | 65 +++++++++++++++++++ .../index/future-compatibility/test.yaml | 1 + 5 files changed, 180 insertions(+) create mode 100644 src/alire/alire-properties-future.adb create mode 100644 src/alire/alire-properties-future.ads create mode 100644 testsuite/tests/index/future-compatibility/test.py create mode 100644 testsuite/tests/index/future-compatibility/test.yaml diff --git a/src/alire/alire-properties-from_toml.ads b/src/alire/alire-properties-from_toml.ads index 6579742dc..c90d12329 100644 --- a/src/alire/alire-properties-from_toml.ads +++ b/src/alire/alire-properties-from_toml.ads @@ -6,6 +6,7 @@ with Alire.Properties.Configurations; with Alire.Properties.Environment; with Alire.Properties.Build_Profiles; with Alire.Properties.Build_Switches; +with Alire.Properties.Future; with Alire.Properties.Labeled; with Alire.Properties.Licenses; with Alire.Properties.Scenarios; @@ -28,6 +29,7 @@ package Alire.Properties.From_TOML is Description, Environment, Executables, + Future, -- Placeholder for unknown future properties GPR_Externals, GPR_Set_Externals, Hint, @@ -102,6 +104,7 @@ package Alire.Properties.From_TOML is Description => Unique, Environment => Unique, Executables => Multiple, + Future => Multiple, GPR_Externals => Unique, GPR_Set_Externals => Unique, Hint => Unique, @@ -157,6 +160,7 @@ package Alire.Properties.From_TOML is Environment => Properties.Environment.From_TOML'Access, Executables => Labeled.From_TOML'Access, + Future => Properties.Future.From_TOML'Access, GPR_Externals | GPR_Set_Externals => Scenarios.From_TOML'Access, @@ -183,6 +187,7 @@ package Alire.Properties.From_TOML is Configuration | Environment | Executables | + Future | GPR_Set_Externals | Hint | Project_Files | diff --git a/src/alire/alire-properties-future.adb b/src/alire/alire-properties-future.adb new file mode 100644 index 000000000..ae23bc312 --- /dev/null +++ b/src/alire/alire-properties-future.adb @@ -0,0 +1,59 @@ +with Ada.Environment_Variables; + +with Alire.Environment; +with Alire.Warnings; + +package body Alire.Properties.Future is + + Future_Key : constant String := "future"; + + --------------- + -- From_TOML -- + --------------- + + function From_TOML (From : TOML_Adapters.Key_Queue) + return Conditional.Properties + is + use TOML; + use type Conditional.Properties; + begin + + -- Pop first the key.value table artificially constructed by the parser + + if From.Unwrap.Kind /= TOML_Table then + From.Checked_Error + ("future: table with assignments expected, but got: " + & From.Unwrap.Kind'Img); + end if; + + -- Now, the value can be an actual table or an scalar, depending on the + -- actual manifest schema. For future properties we do not want to be + -- overly picky as things might change, so accept whatever. + + declare + Raw : TOML_Value; + Key : constant String := From.Pop (Raw); + begin + + -- We use the "future" key in the testsuite, but it should not be + -- allowed during regular use: + + if Key = Future_Key and then + not Ada.Environment_Variables.Exists (Alire.Environment.Testsuite) + then + Raise_Checked_Error ("Forbidden property outside of testing: " + & Future_Key); + end if; + + Warnings.Warn_Once + ("Discarding future property in manifest: " & Key + & "(" & Raw.Kind'Image & ")"); + + return Conditional.No_Properties + and Property'(Name_Len => Key'Length, + Name => Key, + Object => Raw); + end; + end From_TOML; + +end Alire.Properties.Future; diff --git a/src/alire/alire-properties-future.ads b/src/alire/alire-properties-future.ads new file mode 100644 index 000000000..6f2b492fd --- /dev/null +++ b/src/alire/alire-properties-future.ads @@ -0,0 +1,50 @@ +with Alire.Conditional; +with Alire.TOML_Adapters; + +package Alire.Properties.Future with Preelaborate is + + -- A loader that simply discards a given property, because we don't support + -- it yet but know of its existence. + + type Property (<>) is new Properties.Property with private; + + overriding + function Image (V : Property) return String; + + overriding + function To_YAML (V : Property) return String; + + overriding + function Key (V : Property) return String; + + function From_TOML (From : TOML_Adapters.Key_Queue) + return Conditional.Properties; + +private + + type Property (Name_Len : Positive) is new Properties.Property with record + Name : String (1 .. Name_Len); + Object : TOML.TOML_Value; + end record; + + overriding + function To_TOML (V : Property) return TOML.TOML_Value; + + overriding + function Image (V : Property) return String + is (AAA.Strings.To_Mixed_Case (V.Name) + & ": "); + + overriding + function To_YAML (V : Property) return String + is (""); + + overriding + function To_TOML (V : Property) return TOML.TOML_Value + is (V.Object); + + overriding + function Key (V : Property) return String + is (V.Name); + +end Alire.Properties.Future; diff --git a/testsuite/tests/index/future-compatibility/test.py b/testsuite/tests/index/future-compatibility/test.py new file mode 100644 index 000000000..1e5e70670 --- /dev/null +++ b/testsuite/tests/index/future-compatibility/test.py @@ -0,0 +1,65 @@ +""" +Check that we can safely ignore known future entries in manifests +""" + +import os + +from drivers.alr import init_local_crate, run_alr, alr_manifest +from drivers.asserts import assert_substring + +TELLTALE = "Discarding future property in manifest: future" + +start_path = os.getcwd() + +def test_future_property(crate_name, future_content): + """Test that future properties are safely ignored with proper warning""" + os.chdir(start_path) + init_local_crate(crate_name) + with open(alr_manifest(), "a") as f: + f.write(future_content) + + p = run_alr("show", quiet=False) + assert_substring(crate_name, p.out) + assert_substring(TELLTALE, p.out) + +# Test table +test_future_property("xxx", """ +[future] +unknown = "property" +""") + +# Test array +test_future_property("yyy", """ +[[future]] +unknown = "property" +""") + +# Test scalar +test_future_property("zzz", """ +future = "is bright" +""") + +# Ensure that actually unknown properties are still rejected + +os.chdir(start_path) +init_local_crate("qqq") +with open(alr_manifest(), "a") as f: + f.write(""" +unknowns = "aren't scary" +""") +p = run_alr("show", quiet=False, complain_on_error=False) +assert_substring("invalid property: 'unknowns'", p.out) + +# Ensure we are not leaking a "hidden" property + +os.chdir(start_path) +del os.environ["ALR_TESTSUITE"] +init_local_crate("vvv") +with open(alr_manifest(), "a") as f: + f.write(""" +future = "bleak" +""") +p = run_alr("show", quiet=False, complain_on_error=False) +assert_substring("Forbidden property outside of testing: future", p.out) + +print("SUCCESS") \ No newline at end of file diff --git a/testsuite/tests/index/future-compatibility/test.yaml b/testsuite/tests/index/future-compatibility/test.yaml new file mode 100644 index 000000000..a8cf9e3e9 --- /dev/null +++ b/testsuite/tests/index/future-compatibility/test.yaml @@ -0,0 +1 @@ +driver: python-script \ No newline at end of file From 4c31954dde29198df1a7cf1211b5897c73efa563 Mon Sep 17 00:00:00 2001 From: Manuel Date: Wed, 3 Sep 2025 20:39:07 +0200 Subject: [PATCH 08/20] fix: typos in `catalog-format-spec.md` (#2002) --- doc/catalog-format-spec.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/catalog-format-spec.md b/doc/catalog-format-spec.md index 2ac180202..a66612641 100644 --- a/doc/catalog-format-spec.md +++ b/doc/catalog-format-spec.md @@ -1081,7 +1081,7 @@ Derivative = {type = "Real"} ``` #### Worst case allocation -Integer variable can be used to define The maximum length of file names in a +Integer variables can be used to define the maximum length of file names in a file-system: ```toml [configuration.variables] @@ -1100,8 +1100,8 @@ Sort_Algorithm = {type = "Enum", values = ["bubble", "quick", "merge"]} The generated GPR will look something like this: ```ada project Test_Config is - type Sort_Algorith_Kind is ("bubble", "quick", "merge"); - Sort_Algorith : Sort_Algorith_Kind := "quick"; + type Sort_Algorithm_Kind is ("bubble", "quick", "merge"); + Sort_Algorithm : Sort_Algorithm_Kind := "quick"; end Test_Config; ``` @@ -1109,7 +1109,7 @@ It can be used in the main GPR file like so: ```ada package Naming is - for Body ("Test.Sort") use "test-sort__" & Test_Config.Sort_Algorith; + for Body ("Test.Sort") use "test-sort__" & Test_Config.Sort_Algorithm; end Naming; ``` With the files `test-sort__bubble.adb`, `test-sort__quick.adb` and @@ -1117,7 +1117,7 @@ With the files `test-sort__bubble.adb`, `test-sort__quick.adb` and ## Platform Specific Code -In the crate configuration Alire also generates a few built-in values to +In the crate configuration, Alire also generates a few built-in values to identify the host platform: - `Alire_Host_OS` - `Alire_Host_Arch` @@ -1177,7 +1177,7 @@ By default, the root crate is in `Development` and the dependencies are in Each crate can customize the compiler switches corresponding to its profiles using the `[build-switches]` table. In general, this should be avoided to preserve consistency in the ecosystem. However, there are cases where it makes -sense for a crates to change its build switches. For instance, a SPARK crate +sense for a crate to change its build switches. For instance, a SPARK crate that is proved to be safe from errors can disable run-time checks in all profiles: ```toml @@ -1198,7 +1198,7 @@ Alire will generate a list of switches in the crate configuration GPR file. It will look something like this: ```ada -abstract project my_crate_Config is +abstract project My_Crate_Config is [...] Ada_Compiler_Switches := External_As_List ("ADAFLAGS", " ") & ( From c021b26565095462e59269566dcbdab638b0daee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Sagaert?= Date: Thu, 4 Sep 2025 12:15:30 +0200 Subject: [PATCH 09/20] fix: workflow on aarch64 linux, macOS 14 instead of latest (#2003) * attempt fixing workflow on aarch64 linux * dev: force macOS 14 macos-latest runner is now macOS 15 which breaks things, yet to diagnose... * fix: force macOS 14 in `ci-toolchain.yml` * dev: remove custom aarch case from `ci-release.yml` * Revert "dev: remove custom aarch case from `ci-release.yml`" This reverts commit 069997e57484208f9638a4980fb9e31a9cb09b5a. --------- Co-authored-by: Alejandro R Mosteo --- .github/workflows/ci-release.yml | 13 +++++++------ .github/workflows/ci-toolchain.yml | 8 ++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml index 047855bf1..6ad412d64 100644 --- a/.github/workflows/ci-release.yml +++ b/.github/workflows/ci-release.yml @@ -50,7 +50,7 @@ jobs: - os: macos-13 # x64 id: x86_64-macos - - os: macos-latest # arm64 + - os: macos-14 # arm64 (macos-latest is now v15 and it breaks things, TODO) id: aarch64-macos - os: ubuntu-22.04 # x64, oldest supported so releases can run on older distros @@ -75,6 +75,7 @@ jobs: - name: Install system toolchain (Ubuntu ARM) if: matrix.platform.id == 'aarch64-linux' run: | + sudo apt-get update sudo apt-get install -y gnat gprbuild echo ALIRE_TESTSUITE_DISABLE_DOCKER=true >> $GITHUB_ENV # We need to disable Docker tests on Ubuntu ARM. @@ -148,7 +149,7 @@ jobs: build-macos-universal: name: Create macOS universal binary - runs-on: macos-latest + runs-on: macos-14 # See above about macos-latest needs: build steps: @@ -221,10 +222,10 @@ jobs: - os: macos-13 id: x86_64-macos - - os: macos-latest + - os: macos-14 # See above about macos-latest id: aarch64-macos - - os: macos-latest + - os: macos-14 # See above about macos-latest id: universal-macos - os: ubuntu-22.04 @@ -499,10 +500,10 @@ jobs: - os: macos-13 id: x86_64-macos - - os: macos-latest + - os: macos-14 # See above about macos-latest id: aarch64-macos - - os: macos-latest + - os: macos-14 # See above about macos-latest id: universal-macos - os: ubuntu-22.04 diff --git a/.github/workflows/ci-toolchain.yml b/.github/workflows/ci-toolchain.yml index 78fb412fc..3a643f888 100644 --- a/.github/workflows/ci-toolchain.yml +++ b/.github/workflows/ci-toolchain.yml @@ -27,7 +27,7 @@ jobs: matrix: os: - macos-13 - - macos-latest + - macos-14 # See ci-release.yml about macos-latest - ubuntu-22.04 - ubuntu-latest - windows-latest @@ -47,11 +47,11 @@ jobs: gcc_version: 13 # No builds of gcc-10, -11, -12 that work on arm64 - - os: macos-latest + - os: macos-14 # See ci-release.yml about macos-latest gcc_version: 10 - - os: macos-latest + - os: macos-14 # See ci-release.yml about macos-latest gcc_version: 11 - - os: macos-latest + - os: macos-14 # See ci-release.yml about macos-latest gcc_version: 12 # gcc-10 and -11 do not work on LTS 24.04 anymore From e1fe270cf893d9848ab82a361febd1834ed71279 Mon Sep 17 00:00:00 2001 From: Seb M'Caw Date: Sat, 6 Sep 2025 21:34:05 +0100 Subject: [PATCH 10/20] feat: prevent incidental output breaking structured output (#2005) * Add test * Fix incidental output breaking structured output * Add note to `--format`'s description * Fix typo in test comment Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/alr/alr-commands.adb | 30 ++++++++++------- .../outdated_index/index/index.toml | 1 + .../structured-output-always-quiet/test.py | 33 +++++++++++++++++++ .../structured-output-always-quiet/test.yaml | 6 ++++ 4 files changed, 59 insertions(+), 11 deletions(-) create mode 100644 testsuite/tests/misc/structured-output-always-quiet/outdated_index/index/index.toml create mode 100644 testsuite/tests/misc/structured-output-always-quiet/test.py create mode 100644 testsuite/tests/misc/structured-output-always-quiet/test.yaml diff --git a/src/alr/alr-commands.adb b/src/alr/alr-commands.adb index a7fc8e004..50914365d 100644 --- a/src/alr/alr-commands.adb +++ b/src/alr/alr-commands.adb @@ -23,6 +23,7 @@ with Alire.Solutions; with Alire.Toolchains; with Alire.Utils.Did_You_Mean; with Alire.Utils.Tables; +with Alire.Utils.User_Input; with Alr.Commands.Action; with Alr.Commands.Build; @@ -185,7 +186,8 @@ package body Alr.Commands is Long_Switch => "--format?", Argument => "FORMAT", Help => - "Use structured output for tables (JSON, TOML, YAML)"); + "Use structured output for tables (JSON, TOML, YAML)." + & " Implies -n and -q."); Define_Switch (Config, No_Color'Access, @@ -515,24 +517,30 @@ package body Alr.Commands is Alire.Utils.Did_You_Mean.Upper_Case); begin - if Structured_Format.all /= "unset" then - Alire.Utils.Tables.Structured_Output := True; - else + -- Do nothing if there is no `--format` argument (or in the unlikely + -- event `--formatunset` is passed) + if Structured_Format.all = "unset" then return; end if; - if Format_Str /= "" and then not Is_Valid (Format_Str) then - Reportaise_Wrong_Arguments - ("Unknown argument in --format" & Structured_Format.all - & "." & Suggest (Format_Str)); - end if; + -- Enable structured output + Alire.Utils.Tables.Structured_Output := True; - if Format_Str /= "" then + -- Set the output format, defaulting to JSON if unspecified. + if Format_Str = "" then + Alire.Utils.Tables.Structured_Output_Format := JSON; + elsif Is_Valid (Format_Str) then Alire.Utils.Tables.Structured_Output_Format := Alire.Utils.Tables.Formats'Value (Format_Str); else - Alire.Utils.Tables.Structured_Output_Format := JSON; + Reportaise_Wrong_Arguments + ("Unknown argument in --format" & Structured_Format.all + & "." & Suggest (Format_Str)); end if; + + -- Disable any additional messages/prompts which can render the + -- output unparsable + Alire.Utils.User_Input.Enable_Silent_Running; end Set_Structured_Output; use all type Alire.Platforms.Operating_Systems; diff --git a/testsuite/tests/misc/structured-output-always-quiet/outdated_index/index/index.toml b/testsuite/tests/misc/structured-output-always-quiet/outdated_index/index/index.toml new file mode 100644 index 000000000..bad265e4f --- /dev/null +++ b/testsuite/tests/misc/structured-output-always-quiet/outdated_index/index/index.toml @@ -0,0 +1 @@ +version = "1.1" diff --git a/testsuite/tests/misc/structured-output-always-quiet/test.py b/testsuite/tests/misc/structured-output-always-quiet/test.py new file mode 100644 index 000000000..7c7d287e4 --- /dev/null +++ b/testsuite/tests/misc/structured-output-always-quiet/test.py @@ -0,0 +1,33 @@ +"""Verify that structured output is not broken by extraneous output.""" + +import json +from drivers.alr import alr_settings_set, init_local_crate, run_alr +from drivers.asserts import assert_substring, assert_eq, assert_not_substring + + +# Load an old (but compatible) index with the associated warning enabled. +alr_settings_set("warning.old_index", "true") +json_search = run_alr("--format=json", "search", "--list", quiet=False) +plain_search = run_alr("search", "--list", quiet=False) + +# The warning should be included in the plain output, but not in the formatted +# output, which should parse as valid JSON. +assert_substring("is older than the newest supported by alr", plain_search.out) +assert_not_substring("is older than the newest supported by alr", json_search.out) +parsed_search = json.loads(json_search.out) +assert_eq(["hello", "libhello"], [c["name"] for c in parsed_search]) + + +# Run `alr show` on a local crate with no toolchain configured and the toolchain +# assistant enabled. +init_local_crate(name="local_crate_name") +alr_settings_set("toolchain.assistant", "true") +p = run_alr("--format=json", "show", quiet=False) + +# The toolchain assistant should not output anything that breaks JSON parsing. +assert_not_substring("toolchain", p.out) +parsed_show = json.loads(p.out) +assert_eq("local_crate_name", parsed_show["name"]) + + +print("SUCCESS") diff --git a/testsuite/tests/misc/structured-output-always-quiet/test.yaml b/testsuite/tests/misc/structured-output-always-quiet/test.yaml new file mode 100644 index 000000000..ee2ef657b --- /dev/null +++ b/testsuite/tests/misc/structured-output-always-quiet/test.yaml @@ -0,0 +1,6 @@ +driver: python-script +indexes: + outdated_index: + in_fixtures: false + basic_index: + in_fixtures: true From ff774960dfda35f5928a56e35cda6ab98ab19c1a Mon Sep 17 00:00:00 2001 From: "Luke A. Guest" Date: Sat, 13 Sep 2025 17:09:11 +0100 Subject: [PATCH 11/20] Add documentation for Gentoo. --- doc/user-changes.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/user-changes.md b/doc/user-changes.md index ec90ca994..06efb7ea4 100644 --- a/doc/user-changes.md +++ b/doc/user-changes.md @@ -6,6 +6,10 @@ stay on top of `alr` new features. ## Release `3.0` +### Gentoo support + +Add Gentoo's Portage support via sudo, if the base package contains a section for gentoo, see libsdl2 for example, emerge will be called if the package is not installed. + ### New `--github` switch for `alr init` command PR [#1972](https://github.com/alire-project/alire/pull/1972) @@ -81,9 +85,9 @@ easily. It takes several optional command line flags: - `--location=` to specify where to install the new binary - `--release=` to download and install a specific version (provided - that Alire builds binaries for this version on your platform) + that Alire builds binaries for this version on your platform) - `--nightly` to install a pre-release version of Alire. - + **Disclaimer**: nightly versions may have incomplete features, unresolved bugs and may delete features or break compatibility without warning. From 7345f7a8c235470ee3d1eca3e6e6dd889510e02c Mon Sep 17 00:00:00 2001 From: "Luke A. Guest" Date: Sat, 13 Sep 2025 17:58:24 +0100 Subject: [PATCH 12/20] Simplify the expression. --- src/alire/alire-origins-deployers-system-portage.adb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/alire/alire-origins-deployers-system-portage.adb b/src/alire/alire-origins-deployers-system-portage.adb index a4cfb693a..8a233557e 100644 --- a/src/alire/alire-origins-deployers-system-portage.adb +++ b/src/alire/alire-origins-deployers-system-portage.adb @@ -33,8 +33,7 @@ package body Alire.Origins.Deployers.System.Portage is begin Trace.Info ("Already_Installed: " & This.Base.Package_Name); - return (if Line (Line'First .. Line'First + Indicator'Length) = Indicator - then True else False); + return Line (Line'First .. Line'First + Indicator'Length) = Indicator; end Already_Installed; function To_Semantic_Version (Gentoo_Version : String) return String is From bdea4b0fdb07119381705de9b41fe383430d3941 Mon Sep 17 00:00:00 2001 From: "Luke A. Guest" Date: Sat, 27 Sep 2025 20:16:44 +0100 Subject: [PATCH 13/20] Fix indexing error. Check to make sure we have a line to check before checking the line. --- src/alire/alire-origins-deployers-system-portage.adb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/alire/alire-origins-deployers-system-portage.adb b/src/alire/alire-origins-deployers-system-portage.adb index 8a233557e..92b668904 100644 --- a/src/alire/alire-origins-deployers-system-portage.adb +++ b/src/alire/alire-origins-deployers-system-portage.adb @@ -33,7 +33,12 @@ package body Alire.Origins.Deployers.System.Portage is begin Trace.Info ("Already_Installed: " & This.Base.Package_Name); - return Line (Line'First .. Line'First + Indicator'Length) = Indicator; + if Line'Length >= Indicator'Length then + return + Line (Line'First .. Line'First + Indicator'Length - 1) = Indicator; + end if; + + return False; end Already_Installed; function To_Semantic_Version (Gentoo_Version : String) return String is From c0bf7b9d9965e91d157085f4b71f780ec1aab460 Mon Sep 17 00:00:00 2001 From: Alejandro R Mosteo Date: Mon, 15 Sep 2025 18:39:05 +0200 Subject: [PATCH 14/20] feat: validation of GH PATs (#1994) * feat: minimal vetting of GH PATs * Old check when forcing --- doc/publishing.md | 4 ++ src/alire/alire-github.adb | 25 +++++++++++++ src/alire/alire-github.ads | 4 ++ src/alire/alire-publish-submit.adb | 17 ++++++--- src/alire/alire-utils-regex.adb | 25 +++++++++++++ src/alire/alire-utils-regex.ads | 8 ++++ src/alire/alire-utils.ads | 4 ++ .../tests_ada/src/alr_tests-github_tokens.adb | 14 +++++++ testsuite/tests_ada/src/alr_tests-regexes.adb | 37 +++++++++++++++++++ 9 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 testsuite/tests_ada/src/alr_tests-github_tokens.adb create mode 100644 testsuite/tests_ada/src/alr_tests-regexes.adb diff --git a/doc/publishing.md b/doc/publishing.md index 32ef6e9b1..2fe324ecc 100644 --- a/doc/publishing.md +++ b/doc/publishing.md @@ -31,6 +31,10 @@ and finally open a pull-request against the community repository. The PAT, once created, is a plain string. You can either export the environment variable `GH_TOKEN` set to this string, or provide it when Alire asks for it. +**NOTE**: whenever Alire asks for the token, you need to provide the full +string that Github shows only during its creation. Do not provide the token +name instead. + There are two kinds of PATs on GitHub: classic and fine-grained. The latter are in beta and not documented here yet. Follow these steps to create a classic PAT: diff --git a/src/alire/alire-github.adb b/src/alire/alire-github.adb index 791079cc7..1c0bd63c6 100644 --- a/src/alire/alire-github.adb +++ b/src/alire/alire-github.adb @@ -5,8 +5,10 @@ with Alire.Errors; with Alire.OS_Lib; with Alire.Publish; with Alire.URI; +with Alire.Utils.Regex; with Alire.Utils.TTY; with Alire.Version; +with Alire.VCSs.Git; with GNATCOLL.JSON.Utility; with GNATCOLL.Strings; @@ -511,4 +513,27 @@ package body Alire.GitHub is end if; end Check_Alire_Binary_Release; + ------------------------- + -- Is_Possibly_A_Token -- + ------------------------- + + function Is_Possibly_A_Token (S : String) return Boolean + is + begin + -- https://docs.github.com/en/authentication/ + -- keeping-your-account-and-data-secure/about-authentication-to-github + -- ?utm_source=chatgpt.com#githubs-token-formats + + -- Classic PAT, just a 40 hexa string + if S in VCSs.Git.Git_Commit then + return True; + end if; + + -- Newer PATs that start with gh?_ or github_pat_. Probably not all of + -- those can work, this would require further digging. + return Utils.Regex.Fully_Matches + (Regex => "(github_pat|gh[pours])_[a-f0-9]+", + Text => S); + end Is_Possibly_A_Token; + end Alire.GitHub; diff --git a/src/alire/alire-github.ads b/src/alire/alire-github.ads index 744cc313f..5ec21b2ac 100644 --- a/src/alire/alire-github.ads +++ b/src/alire/alire-github.ads @@ -106,4 +106,8 @@ package Alire.GitHub is -- In case of error, the resulting Outcome will contain an error message -- specifying whether the release or the specific archive was not found. + function Is_Possibly_A_Token (S : String) return Boolean; + -- Check that S looks like a Personal Access Token. Not exhaustive, just + -- protect about obvious non-tokens + end Alire.GitHub; diff --git a/src/alire/alire-publish-submit.adb b/src/alire/alire-publish-submit.adb index 2cc3ac40f..eef41c52c 100644 --- a/src/alire/alire-publish-submit.adb +++ b/src/alire/alire-publish-submit.adb @@ -55,11 +55,11 @@ package body Alire.Publish.Submit is function Ask_For_Token (Reason : String) return String is - -------------- - -- Validate -- - -------------- + --------------- + -- Non_Empty -- + --------------- - function Validate (S : String) return Boolean + function Non_Empty (S : String) return Boolean is (S /= ""); GH_Token : constant String := OS_Lib.Getenv (GitHub.Env_GH_Token, ""); @@ -81,9 +81,14 @@ package body Alire.Publish.Submit is then GH_Token else CLIC.User_Input.Query_String - ("Please provide your GitHub Personal Access Token: ", + ("Please provide your GitHub Personal Access Token " + & "(full value): ", Default => "", - Validation => Validate'Unrestricted_Access)); + Validation => + -- Allow bypassing in case some day GitHub introduces new + -- token formats so not to stop everybody completely. + (if Force then Non_Empty'Unrestricted_Access + else GitHub.Is_Possibly_A_Token'Access))); end Ask_For_Token; ------------ diff --git a/src/alire/alire-utils-regex.adb b/src/alire/alire-utils-regex.adb index aee4a5086..de81c7b3e 100644 --- a/src/alire/alire-utils-regex.adb +++ b/src/alire/alire-utils-regex.adb @@ -60,4 +60,29 @@ package body Alire.Utils.Regex is return ""; end First_Match; + + ------------- + -- Matches -- + ------------- + + function Matches (Regex : String; Text : String) return Boolean is + begin + return GNAT.Regpat.Match (Expression => Regex, Data => Text); + end Matches; + + ------------------- + -- Fully_Matches -- + ------------------- + + function Fully_Matches (Regex : String; Text : String) return Boolean is + begin + if Regex = "" or else Regex (Regex'First) /= '^' then + return Fully_Matches ('^' & Regex, Text); + elsif Regex = "" or else Regex (Regex'Last) /= '$' then + return Fully_Matches (Regex & '$', Text); + else + return Matches (Regex, Text); + end if; + end Fully_Matches; + end Alire.Utils.Regex; diff --git a/src/alire/alire-utils-regex.ads b/src/alire/alire-utils-regex.ads index 30c32c8b7..c5e06f2c4 100644 --- a/src/alire/alire-utils-regex.ads +++ b/src/alire/alire-utils-regex.ads @@ -12,4 +12,12 @@ package Alire.Utils.Regex is -- is the second matching expression. In case of no match, it will return -- an empty string. At least one capture must be attempted in the Regex. + function Matches (Regex : String; Text : String) return Boolean; + -- Wrapper on GNAT.Regpat, just say if Text matches Regex. Remember to use + -- anchors (^$) for full string matching, as otherwise a substring match is + -- reported as a valid match. See Fully_Matches below. + + function Fully_Matches (Regex : String; Text : String) return Boolean; + -- Returns true if Text is matched in full by regex + end Alire.Utils.Regex; diff --git a/src/alire/alire-utils.ads b/src/alire/alire-utils.ads index 30b09c919..9fadb2818 100644 --- a/src/alire/alire-utils.ads +++ b/src/alire/alire-utils.ads @@ -8,6 +8,10 @@ package Alire.Utils with Preelaborate is subtype Hexadecimal_Character is Character with Static_Predicate => Hexadecimal_Character in '0' .. '9' | 'a' .. 'f'; + subtype Hexadecimal_String is String with + Predicate => (for all Char of Hexadecimal_String => + Char in Hexadecimal_Character); + function Command_Line_Contains (Prefix : String) return Boolean; -- Say if any of the command-line arguments begins with Prefix. This is -- needed for string arguments, that even when not supplied are initialized diff --git a/testsuite/tests_ada/src/alr_tests-github_tokens.adb b/testsuite/tests_ada/src/alr_tests-github_tokens.adb new file mode 100644 index 000000000..4032374d5 --- /dev/null +++ b/testsuite/tests_ada/src/alr_tests-github_tokens.adb @@ -0,0 +1,14 @@ +with Alire.GitHub; + +procedure Alr_Tests.Github_Tokens is + use Alire.GitHub; +begin + pragma Assert (Is_Possibly_A_Token ("12345678abcdefab12345678abcdefab12345678"), + "Failed for old GitHub PAT format"); + pragma Assert (Is_Possibly_A_Token ("github_pat_1234567890abcdef"), + "Failed for GitHub fine-grained PAT format"); + pragma Assert (Is_Possibly_A_Token ("ghp_1234567890abcdef"), + "Failed new GitHub PAT format"); + pragma Assert (not Is_Possibly_A_Token ("MY_PERSONAL_TOKEN"), + "Should not accept invalid GitHub PAT format"); +end Alr_Tests.Github_Tokens; \ No newline at end of file diff --git a/testsuite/tests_ada/src/alr_tests-regexes.adb b/testsuite/tests_ada/src/alr_tests-regexes.adb new file mode 100644 index 000000000..62528947d --- /dev/null +++ b/testsuite/tests_ada/src/alr_tests-regexes.adb @@ -0,0 +1,37 @@ +with Alire.Utils.Regex; + +procedure Alr_Tests.Regexes is + use Alire.Utils.Regex; + + GH_Token_Regex : constant String := "(github_pat|gh[pours])_[a-f0-9]+"; + +begin + -- Partial matches with unanchored expressions + pragma Assert (Matches ("abc", "abcde"), "Failed unanchored match at beginning"); + pragma Assert (Matches ("cde", "abcde"), "Failed unanchored match at end"); + pragma Assert (Matches ("bcd", "abcde"), "Failed unanchored match in the middle"); + + -- Full matches with unanchored expressions + pragma Assert (Fully_Matches ("abc", "abc"), "Failed full match"); + pragma Assert (not Fully_Matches ("abc", "abcde"), "Should not partially match"); + + -- Anchored full matches + pragma Assert (Matches ("^abc$", "abc"), "Failed full anchored match"); + pragma Assert (Fully_Matches ("^abc$", "abc"), "Failed redundant full anchored match"); + + -- Some failing matches + pragma Assert (not Matches ("abc", "def"), "Should not match different strings"); + pragma Assert (not Matches ("abc", "ab"), "Should not match shorter string"); + pragma Assert (not Fully_Matches ("abc", "abcd"), "Should not match longer string"); + + -- Some actual regex tests + pragma Assert (Matches ("^\d{3}-\d{2}-\d{4}$", "123-45-6789"), "Failed regex match for SSN format"); + pragma Assert (Fully_Matches ("[0-9a-f]{8}", "1a2b3c4d"), "Failed regex match for hex format"); + pragma Assert (not Fully_Matches ("[0-9a-f]{8}", "1a2b3c4d5"), "Should not match longer hex format"); + pragma Assert (Fully_Matches (GH_Token_Regex, "github_pat_1234567890abcdef"), + "Failed regex match for GitHub fine-grained PAT format"); + pragma Assert (Fully_Matches (GH_Token_Regex, "ghp_1234567890abcdef"), + "Failed match for new GitHub PAT format"); + pragma Assert (not Fully_Matches (GH_Token_Regex, "MY_PERSONAL_TOKEN"), + "Should not match invalid GitHub PAT format"); +end Alr_Tests.Regexes; \ No newline at end of file From 60705e7cb4b32a5d841933e4ec4d871d74613c0d Mon Sep 17 00:00:00 2001 From: "Luke A. Guest" Date: Fri, 28 Nov 2025 09:34:22 +0000 Subject: [PATCH 15/20] Correct the package manager's name to emerge. --- deps/den | 2 +- src/alire/alire-origins-deployers-system-portage.ads | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/den b/deps/den index bab6ef56b..7732f9247 160000 --- a/deps/den +++ b/deps/den @@ -1 +1 @@ -Subproject commit bab6ef56b74b3b348daf402f09f4b04c304bc280 +Subproject commit 7732f9247f7436cd264a10a7e2a8a16c47a0fb57 diff --git a/src/alire/alire-origins-deployers-system-portage.ads b/src/alire/alire-origins-deployers-system-portage.ads index 7ddd69bc3..1b63c8a91 100644 --- a/src/alire/alire-origins-deployers-system-portage.ads +++ b/src/alire/alire-origins-deployers-system-portage.ads @@ -13,6 +13,6 @@ package Alire.Origins.Deployers.System.Portage is function Install (This : Deployer) return Outcome; overriding - function Executable_Name (This : Deployer) return String is ("apt"); + function Executable_Name (This : Deployer) return String is ("emerge"); end Alire.Origins.Deployers.System.Portage; From 395b759a63a0036dd3b7b1e27d5e22c4a71b368c Mon Sep 17 00:00:00 2001 From: "Luke A. Guest" Date: Fri, 28 Nov 2025 09:35:20 +0000 Subject: [PATCH 16/20] Change the log level to Detail. --- src/alire/alire-origins-deployers-system-portage.adb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/alire/alire-origins-deployers-system-portage.adb b/src/alire/alire-origins-deployers-system-portage.adb index 92b668904..39b285c61 100644 --- a/src/alire/alire-origins-deployers-system-portage.adb +++ b/src/alire/alire-origins-deployers-system-portage.adb @@ -31,7 +31,7 @@ package body Alire.Origins.Deployers.System.Portage is Indicator : constant String := "[I]"; Line : constant String := AAA.Strings.First_Element (Output); begin - Trace.Info ("Already_Installed: " & This.Base.Package_Name); + Trace.Detail ("Already_Installed: " & This.Base.Package_Name); if Line'Length >= Indicator'Length then return From 7a54348549f55e2547e430202927c0145d95dd26 Mon Sep 17 00:00:00 2001 From: "Luke A. Guest" Date: Fri, 28 Nov 2025 09:38:10 +0000 Subject: [PATCH 17/20] Change Info -> Debug. --- src/alire/alire-origins-deployers-system-portage.adb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/alire/alire-origins-deployers-system-portage.adb b/src/alire/alire-origins-deployers-system-portage.adb index 39b285c61..74812ce44 100644 --- a/src/alire/alire-origins-deployers-system-portage.adb +++ b/src/alire/alire-origins-deployers-system-portage.adb @@ -49,13 +49,13 @@ package body Alire.Origins.Deployers.System.Portage is if Tmp (C) = L1.Low_Line then Tmp (C) := L1.Hyphen; - Trace.Info ("To_Semantic_Version: " & Tmp); + Trace.Debug ("To_Semantic_Version: " & Tmp); return Tmp; end if; end loop; - Trace.Info ("To_Semantic_Version: " & Tmp); + Trace.Debug ("To_Semantic_Version: " & Tmp); return Tmp; end To_Semantic_Version; From 25737fbfbeef0948ea5cd1ccb200082cadfdfa93 Mon Sep 17 00:00:00 2001 From: "Luke A. Guest" Date: Fri, 28 Nov 2025 11:07:46 +0000 Subject: [PATCH 18/20] Add the comment box. --- src/alire/alire-origins-deployers-system-portage.adb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/alire/alire-origins-deployers-system-portage.adb b/src/alire/alire-origins-deployers-system-portage.adb index 74812ce44..51968ccf7 100644 --- a/src/alire/alire-origins-deployers-system-portage.adb +++ b/src/alire/alire-origins-deployers-system-portage.adb @@ -41,6 +41,10 @@ package body Alire.Origins.Deployers.System.Portage is return False; end Already_Installed; + ------------------------- + -- To_Semantic_Version -- + ------------------------- + function To_Semantic_Version (Gentoo_Version : String) return String is Tmp : String := Gentoo_Version; begin From 321447eca30127c6d27a6f784f7a6f8fbb7ef478 Mon Sep 17 00:00:00 2001 From: "Alejandro R. Mosteo" Date: Fri, 5 Dec 2025 10:24:10 +0100 Subject: [PATCH 19/20] Bump den dependency --- deps/den | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/den b/deps/den index 7732f9247..bab6ef56b 160000 --- a/deps/den +++ b/deps/den @@ -1 +1 @@ -Subproject commit 7732f9247f7436cd264a10a7e2a8a16c47a0fb57 +Subproject commit bab6ef56b74b3b348daf402f09f4b04c304bc280 From c59d0aecd85dec62f8a86e2f076d30c0fb89b0eb Mon Sep 17 00:00:00 2001 From: "Alejandro R. Mosteo" Date: Fri, 5 Dec 2025 11:17:50 +0100 Subject: [PATCH 20/20] Downgrade level of some logs --- src/alire/alire-origins-deployers-system-portage.adb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/alire/alire-origins-deployers-system-portage.adb b/src/alire/alire-origins-deployers-system-portage.adb index 51968ccf7..cdab964c8 100644 --- a/src/alire/alire-origins-deployers-system-portage.adb +++ b/src/alire/alire-origins-deployers-system-portage.adb @@ -107,7 +107,7 @@ package body Alire.Origins.Deployers.System.Portage is -- From the pms.pdf. begin if Gentoo_Version /= "" then - Trace.Info ("Detect: " & This.Base.Package_Name & " - " & + Trace.Debug ("Detect: " & This.Base.Package_Name & " - " & Gentoo_Version & " - " & To_Semantic_Version (Gentoo_Version) & " => " & Semantic_Versioning.Parse (To_Semantic_Version (Gentoo_Version), @@ -131,7 +131,7 @@ package body Alire.Origins.Deployers.System.Portage is overriding function Install (This : Deployer) return Outcome is begin - Trace.Info ("Install: " & This.Base.Package_Name); + Trace.Debug ("Install: " & This.Base.Package_Name); Subprocess.Checked_Spawn ("sudo", Empty_Vector &