[Bug 43557] New: Add declarative mutually-exclusive option support to Koha::Script->describe_options
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Bug ID: 43557 Summary: Add declarative mutually-exclusive option support to Koha::Script->describe_options Initiative type: --- Sponsorship --- status: Product: Koha Version: Main Hardware: All OS: All Status: NEW Severity: enhancement Priority: P5 - low Component: Command-line Utilities Assignee: koha-bugs@lists.koha-community.org Reporter: martin.renvoize@openfifth.co.uk QA Contact: testopia@bugs.koha-community.org CC: jake.deery@openfifth.co.uk, robin@catalyst.net.nz Target Milestone: --- Bug 43546 added Koha::Script->describe_options, a thin wrapper round Getopt::Long::Descriptive establishing a declarative convention for command-line option parsing: options can be marked required, and a positional-argument minimum can be declared, both enforced consistently before script logic runs, instead of every script rolling its own post-parse check and error text. Several cron scripts have their own hand-rolled "these two options are mutually exclusive" check, each with slightly different wording and mechanism: - misc/cronjobs/longoverdue.pl: --category/--skip-category, --library/--skip-library, --itemtype/--skip-itemtype (three separate pairs) - misc/cronjobs/membership_expiry.pl: --active/--inactive - misc/cronjobs/update_totalissues.pl: --since/--interval, --use-items/--incremental - misc/cronjobs/process_message_queue.pl: --code/--exclude-code (already converted to describe_options on bug 43551, using a one-off $usage->die() check since this feature didn't exist yet) That is seven pairs across four scripts, all reimplementing the same check. Getopt::Long::Descriptive's own one_of constraint looks like a fit at first glance, but testing shows it does not enforce exclusivity at all when the sub-options are array/repeatable types (e.g. our --code/--exclude-code, which both take multiple values): passing both options together with values is silently accepted, which would be a regression, not a fix. This bug is to add a declarative "exclusive" key to the trailing options hashref of Koha::Script->describe_options, alongside the existing "args" key, e.g.: my $opt = Koha::Script->describe_options( '%c %o', [ 'category|c=s@', 'category codes to include' ], [ 'skip-category|C=s@', 'category codes to exclude' ], { exclusive => [ [qw(category skip_category)] ] }, ); When more than one option in a declared exclusive group is supplied, the script should die with a clear, consistent error and the usage text, the same as a missing required option does today, instead of each script writing its own pod2usage/die/$usage->die variant. Test plan: 1. prove t/Koha/Script.t 2. Add regression tests covering: neither option given, one option given, both options given (dies with a clear message naming both options), and the fact that a bare optional-value flag with no value (see bug 37075) is not treated as "given" for this purpose. 3. koha-qa.pl passes for Koha/Script.pm Sponsored-by: OpenFifth <https://openfifth.co.uk/> -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Depends on| |43546 Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43546 [Bug 43546] Standardize command-line scripts on Getopt::Long::Descriptive for safer, more consistent option handling -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Blocks| |43551 Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43551 [Bug 43551] Convert misc/cronjobs/process_message_queue.pl to the Getopt::Long::Descriptive convention (see bug 43546) -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Blocks| |43558 Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43558 [Bug 43558] Convert misc/cronjobs/longoverdue.pl to the Getopt::Long::Descriptive convention (see bug 43546) -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Blocks| |43559 Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43559 [Bug 43559] Convert misc/cronjobs/membership_expiry.pl to the Getopt::Long::Descriptive convention (see bug 43546) -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Blocks| |43560 Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43560 [Bug 43560] Convert misc/cronjobs/update_totalissues.pl to the Getopt::Long::Descriptive convention (see bug 43546) -- You are receiving this mail because: You are watching all bug changes. You are the assignee for the bug.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 --- Comment #1 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 206174 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=206174&action=edit Bug 43557: Add declarative mutually-exclusive option support to Koha::Script->describe_options Adds an exclusive key to the trailing options hashref of Koha::Script->describe_options, alongside the existing required and args support. Declaring exclusive => [ [qw(code exclude-code)], ... ] makes a group of options mutually exclusive: if more than one is actually given a value, the script dies with a clear, consistent error and the usage text, the same as a missing required option already does, instead of every script rolling its own pod2usage/die check. Group members must be written using each option's first-declared spec name, hyphens and all (e.g. exclude-code, not the accessor's exclude_code) -- confirmed by testing that Getopt::Long::Descriptive's _specified() introspection method needs that exact form, not the canonicalised accessor name. An option only counts as "given" if it was specified on the command line and resolved to a non-empty value, so a bare optional-value (:s) flag left over as an empty string (bug 37075) does not by itself trigger the conflict -- this was tested directly against both scalar and repeatable (:s@) option types. Getopt::Long::Descriptive's own one_of constraint was considered as an alternative, since it already provides exclusivity checking for a group of options. Testing showed it does not enforce exclusivity at all when the group's options are array/repeatable types: passing two such options together with real values is silently accepted, which would have been a regression for scripts like process_message_queue.pl (bug 43551) whose --code/--exclude-code both take multiple values. Test plan: 1. prove t/Koha/Script.t 2. koha-qa.pl passes for Koha/Script.pm -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Assignee|koha-bugs@lists.koha-commun |martin.renvoize@openfifth.c |ity.org |o.uk Status|NEW |Needs Signoff -- You are receiving this mail because: You are the assignee for the bug. You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Blocks| |43549 Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43549 [Bug 43549] Convert misc/cronjobs/cleanup_database.pl to the Getopt::Long::Descriptive convention (see bug 43546) -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Frédéric Demians <f.demians@tamil.fr> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|Needs Signoff |Signed Off -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Frédéric Demians <f.demians@tamil.fr> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #206174|0 |1 is obsolete| | -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 --- Comment #2 from Frédéric Demians <f.demians@tamil.fr> --- Created attachment 207905 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=207905&action=edit Bug 43557: Add declarative mutually-exclusive option support to Koha::Script->describe_options Adds an exclusive key to the trailing options hashref of Koha::Script->describe_options, alongside the existing required and args support. Declaring exclusive => [ [qw(code exclude-code)], ... ] makes a group of options mutually exclusive: if more than one is actually given a value, the script dies with a clear, consistent error and the usage text, the same as a missing required option already does, instead of every script rolling its own pod2usage/die check. Group members must be written using each option's first-declared spec name, hyphens and all (e.g. exclude-code, not the accessor's exclude_code) -- confirmed by testing that Getopt::Long::Descriptive's _specified() introspection method needs that exact form, not the canonicalised accessor name. An option only counts as "given" if it was specified on the command line and resolved to a non-empty value, so a bare optional-value (:s) flag left over as an empty string (bug 37075) does not by itself trigger the conflict -- this was tested directly against both scalar and repeatable (:s@) option types. Getopt::Long::Descriptive's own one_of constraint was considered as an alternative, since it already provides exclusivity checking for a group of options. Testing showed it does not enforce exclusivity at all when the group's options are array/repeatable types: passing two such options together with real values is silently accepted, which would have been a regression for scripts like process_message_queue.pl (bug 43551) whose --code/--exclude-code both take multiple values. Test plan: 1. prove t/Koha/Script.t 2. koha-qa.pl passes for Koha/Script.pm Signed-off-by: Frédéric Demians <f.demians@tamil.fr> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 --- Comment #3 from Frédéric Demians <f.demians@tamil.fr> --- Created attachment 207906 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=207906&action=edit Bug 43557: (follow-up) Reject exclusive group members that are not first-declared option names An exclusive group only works if its members are written exactly as the options' first-declared names. An alias ('c'), an underscore form ('exclude_code') or a typo was silently accepted, and the group was then never enforced, without any warning. describe_options now throws a Koha::Exceptions::WrongParameter for such a member, naming the expected name when there is one. It also reports a negatable option given as --no-foo as --no-foo, instead of --foo. Test plan: 1. prove t/Koha/Script.t 2. koha-qa.pl passes for Koha/Script.pm -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Frédéric Demians <f.demians@tamil.fr> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|Signed Off |Failed QA CC| |f.demians@tamil.fr --- Comment #4 from Frédéric Demians <f.demians@tamil.fr> --- Martin, could you rebase the patches on top of bug 43546? Bug 43546 passed QA with a new follow-up, "Exit with status 1 on command-line errors". It changes Koha::Script->describe_options and adds a subtest to t/Koha/Script.t, at the same place as the subtest added here. I've seen that trying to sign-of subsequent patches: 43549, 43551, etc. Or I can rebase it myself? -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #207905|0 |1 is obsolete| | Attachment #207906|0 |1 is obsolete| | -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 --- Comment #5 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 208576 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=208576&action=edit Bug 43557: Add declarative mutually-exclusive option support to Koha::Script->describe_options Adds an exclusive key to the trailing options hashref of Koha::Script->describe_options, alongside the existing required and args support. Declaring exclusive => [ [qw(code exclude-code)], ... ] makes a group of options mutually exclusive: if more than one is actually given a value, the script dies with a clear, consistent error and the usage text, the same as a missing required option already does, instead of every script rolling its own pod2usage/die check. Group members must be written using each option's first-declared spec name, hyphens and all (e.g. exclude-code, not the accessor's exclude_code) -- confirmed by testing that Getopt::Long::Descriptive's _specified() introspection method needs that exact form, not the canonicalised accessor name. An option only counts as "given" if it was specified on the command line and resolved to a non-empty value, so a bare optional-value (:s) flag left over as an empty string (bug 37075) does not by itself trigger the conflict -- this was tested directly against both scalar and repeatable (:s@) option types. Getopt::Long::Descriptive's own one_of constraint was considered as an alternative, since it already provides exclusivity checking for a group of options. Testing showed it does not enforce exclusivity at all when the group's options are array/repeatable types: passing two such options together with real values is silently accepted, which would have been a regression for scripts like process_message_queue.pl (bug 43551) whose --code/--exclude-code both take multiple values. Test plan: 1. prove t/Koha/Script.t 2. koha-qa.pl passes for Koha/Script.pm Signed-off-by: Frédéric Demians <f.demians@tamil.fr> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 --- Comment #6 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 208577 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=208577&action=edit Bug 43557: (follow-up) Reject exclusive group members that are not first-declared option names An exclusive group only works if its members are written exactly as the options' first-declared names. An alias ('c'), an underscore form ('exclude_code') or a typo was silently accepted, and the group was then never enforced, without any warning. describe_options now throws a Koha::Exceptions::WrongParameter for such a member, naming the expected name when there is one. It also reports a negatable option given as --no-foo as --no-foo, instead of --foo. Test plan: 1. prove t/Koha/Script.t 2. koha-qa.pl passes for Koha/Script.pm -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Blocks| |43553 Referenced Bugs: https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43553 [Bug 43553] Convert misc/cronjobs/holds/holds_reminder.pl to the Getopt::Long::Descriptive convention (see bug 43546) -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #208576|0 |1 is obsolete| | Attachment #208577|0 |1 is obsolete| | -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 --- Comment #7 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 208589 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=208589&action=edit Bug 43557: Add declarative mutually-exclusive option support to Koha::Script->describe_options Adds an exclusive key to the trailing options hashref of Koha::Script->describe_options, alongside the existing required and args support. Declaring exclusive => [ [qw(code exclude-code)], ... ] makes a group of options mutually exclusive: if more than one is actually given a value, the script dies with a clear, consistent error and the usage text, the same as a missing required option already does, instead of every script rolling its own pod2usage/die check. Group members must be written using each option's first-declared spec name, hyphens and all (e.g. exclude-code, not the accessor's exclude_code) -- confirmed by testing that Getopt::Long::Descriptive's _specified() introspection method needs that exact form, not the canonicalised accessor name. An option only counts as "given" if it was specified on the command line and resolved to a non-empty value, so a bare optional-value (:s) flag left over as an empty string (bug 37075) does not by itself trigger the conflict -- this was tested directly against both scalar and repeatable (:s@) option types. Getopt::Long::Descriptive's own one_of constraint was considered as an alternative, since it already provides exclusivity checking for a group of options. Testing showed it does not enforce exclusivity at all when the group's options are array/repeatable types: passing two such options together with real values is silently accepted, which would have been a regression for scripts like process_message_queue.pl (bug 43551) whose --code/--exclude-code both take multiple values. Test plan: 1. prove t/Koha/Script.t 2. koha-qa.pl passes for Koha/Script.pm Signed-off-by: Frédéric Demians <f.demians@tamil.fr> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 --- Comment #8 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 208590 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=208590&action=edit Bug 43557: (follow-up) Reject exclusive group members that are not first-declared option names An exclusive group only works if its members are written exactly as the options' first-declared names. An alias ('c'), an underscore form ('exclude_code') or a typo was silently accepted, and the group was then never enforced, without any warning. describe_options now throws a Koha::Exceptions::WrongParameter for such a member, naming the expected name when there is one. It also reports a negatable option given as --no-foo as --no-foo, instead of --foo. Test plan: 1. prove t/Koha/Script.t 2. koha-qa.pl passes for Koha/Script.pm -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 --- Comment #9 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Created attachment 208591 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=208591&action=edit Bug 43557: (follow-up) Accept legacy single-dash long options with a deprecation warning Scripts converted to Koha::Script->describe_options used to be parsed by plain Getopt::Long, which also accepted a long option with a single dash (-days 5). Several of them documented that form (holds_reminder.pl lists -days, -lettercode, -date, -library and -holidays), so existing cron lines use it. Getopt::Long::Descriptive parses with bundling, and -days is then read as the flags -d -a -y -s: the script prints its usage and exits 1, and the cron job silently stops running. Rewrite such an argument as the standard --days, and print a deprecation warning to STDERR (cron mails it to the administrator) so existing command lines keep working while they are migrated. An argument is only rewritten if it is a single dash and at least two characters, and names a declared long option or the unique prefix of one (as plain Getopt::Long allowed), and it is not a bundle of declared one-character flags (-vc is still -v -c). The values given to options, and anything after --, are left alone. -help and -man work too. This is a compatibility shim to be removed in a future release; --long remains the documented form. Test plan: 1. Apply the patch 2. prove t/Koha/Script.t 3. Run a converted script with a legacy option, for example misc/cronjobs/holds/holds_reminder.pl -days 3 (with the patch of bug 43553): it runs, and prints WARNING: -days is deprecated, use --days instead (...) 4. Run it with --days 3: it runs and prints no warning Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|Failed QA |Signed Off --- Comment #10 from Martin Renvoize (ashimema) <martin.renvoize@openfifth.co.uk> --- Rebased on current main (bug 43546 and its follow-ups are now pushed), as Frédéric asked, so the patches apply again. Back to Signed Off for QA. New attachments: - 208589 (the original patch) and 208590 (Frédéric's follow-up) are rebased on main. They conflicted with the "Exit with status 1 on command-line errors" follow-up of bug 43546, which also changes Koha::Script->describe_options and adds a subtest to t/Koha/Script.t. In t/Koha/Script.t both subtests are kept and the plan count is updated. In Koha/Script.pm the exclusive-group validation from 208590 now runs before the eval-wrapped call to describe_options added by bug 43546, so an unknown option still exits with status 1. Frédéric's sign-off on 208589 is kept. - 208591 is a new follow-up: accept legacy single-dash long options with a deprecation warning. Why the new follow-up: Andrew failed QA on bug 43553 because the double-dash spelling breaks existing cron lines. Several of the scripts documented the single-dash form (the old holds_reminder.pl usage lists -days, -lettercode, -date, -library and -holidays), and Getopt::Long::Descriptive parses with bundling, so "-days 5" is read as -d -a -y -s: the script prints its usage and exits 1, and the cron job silently stops running. How it is solved: Koha::Script->describe_options now rewrites such an argument as the standard --days and prints a deprecation warning to STDERR (cron mails it to the administrator), so existing command lines keep working while they are migrated. It is deliberately narrow: only a single dash followed by at least two characters, naming a declared long option or the unique prefix of one (as plain Getopt::Long allowed), and not a bundle of declared one-character flags (-vc is still -v -c). The values given to options, and anything after --, are left alone. -help and -man work too. --long stays the documented form, and the shim is meant to be removed in a future release. It lives here because this bug extends describe_options; bug 43553 now depends on this bug, and it also covers runreport.pl from bug 43548, which is already pushed. Test plan for 208591: 1. Apply the patches 2. prove t/Koha/Script.t 3. perl misc/cronjobs/holds/holds_reminder.pl -days 3 -lettercode HOLD_REMINDER -v (with the patch of bug 43553): it runs and prints WARNING: -days is deprecated, use --days instead (...) 4. Repeat with --days 3 --lettercode HOLD_REMINDER: it runs and prints no warning Bugs 43549, 43551, 43558, 43559 and 43560 depend on this one and have been rebased on top of these patches. -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Andrew Fuerste-Henry <andrew@bywatersolutions.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|Signed Off |Passed QA QA Contact|testopia@bugs.koha-communit |andrew@bywatersolutions.com |y.org | -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 Andrew Fuerste-Henry <andrew@bywatersolutions.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #208589|0 |1 is obsolete| | Attachment #208590|0 |1 is obsolete| | Attachment #208591|0 |1 is obsolete| | -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 --- Comment #11 from Andrew Fuerste-Henry <andrew@bywatersolutions.com> --- Created attachment 208605 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=208605&action=edit Bug 43557: Add declarative mutually-exclusive option support to Koha::Script->describe_options Adds an exclusive key to the trailing options hashref of Koha::Script->describe_options, alongside the existing required and args support. Declaring exclusive => [ [qw(code exclude-code)], ... ] makes a group of options mutually exclusive: if more than one is actually given a value, the script dies with a clear, consistent error and the usage text, the same as a missing required option already does, instead of every script rolling its own pod2usage/die check. Group members must be written using each option's first-declared spec name, hyphens and all (e.g. exclude-code, not the accessor's exclude_code) -- confirmed by testing that Getopt::Long::Descriptive's _specified() introspection method needs that exact form, not the canonicalised accessor name. An option only counts as "given" if it was specified on the command line and resolved to a non-empty value, so a bare optional-value (:s) flag left over as an empty string (bug 37075) does not by itself trigger the conflict -- this was tested directly against both scalar and repeatable (:s@) option types. Getopt::Long::Descriptive's own one_of constraint was considered as an alternative, since it already provides exclusivity checking for a group of options. Testing showed it does not enforce exclusivity at all when the group's options are array/repeatable types: passing two such options together with real values is silently accepted, which would have been a regression for scripts like process_message_queue.pl (bug 43551) whose --code/--exclude-code both take multiple values. Test plan: 1. prove t/Koha/Script.t 2. koha-qa.pl passes for Koha/Script.pm Signed-off-by: Frédéric Demians <f.demians@tamil.fr> Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 --- Comment #12 from Andrew Fuerste-Henry <andrew@bywatersolutions.com> --- Created attachment 208606 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=208606&action=edit Bug 43557: (follow-up) Reject exclusive group members that are not first-declared option names An exclusive group only works if its members are written exactly as the options' first-declared names. An alias ('c'), an underscore form ('exclude_code') or a typo was silently accepted, and the group was then never enforced, without any warning. describe_options now throws a Koha::Exceptions::WrongParameter for such a member, naming the expected name when there is one. It also reports a negatable option given as --no-foo as --no-foo, instead of --foo. Test plan: 1. prove t/Koha/Script.t 2. koha-qa.pl passes for Koha/Script.pm Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> -- You are receiving this mail because: You are watching all bug changes.
https://bugs.koha-community.org/bugzilla3/show_bug.cgi?id=43557 --- Comment #13 from Andrew Fuerste-Henry <andrew@bywatersolutions.com> --- Created attachment 208607 --> https://bugs.koha-community.org/bugzilla3/attachment.cgi?id=208607&action=edit Bug 43557: (follow-up) Accept legacy single-dash long options with a deprecation warning Scripts converted to Koha::Script->describe_options used to be parsed by plain Getopt::Long, which also accepted a long option with a single dash (-days 5). Several of them documented that form (holds_reminder.pl lists -days, -lettercode, -date, -library and -holidays), so existing cron lines use it. Getopt::Long::Descriptive parses with bundling, and -days is then read as the flags -d -a -y -s: the script prints its usage and exits 1, and the cron job silently stops running. Rewrite such an argument as the standard --days, and print a deprecation warning to STDERR (cron mails it to the administrator) so existing command lines keep working while they are migrated. An argument is only rewritten if it is a single dash and at least two characters, and names a declared long option or the unique prefix of one (as plain Getopt::Long allowed), and it is not a bundle of declared one-character flags (-vc is still -v -c). The values given to options, and anything after --, are left alone. -help and -man work too. This is a compatibility shim to be removed in a future release; --long remains the documented form. Test plan: 1. Apply the patch 2. prove t/Koha/Script.t 3. Run a converted script with a legacy option, for example misc/cronjobs/holds/holds_reminder.pl -days 3 (with the patch of bug 43553): it runs, and prints WARNING: -days is deprecated, use --days instead (...) 4. Run it with --days 3: it runs and prints no warning Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Andrew Fuerste Henry <andrew@bywatersolutions.com> -- You are receiving this mail because: You are watching all bug changes.
participants (1)
-
bugzilla-daemon@bugs.koha-community.org