- fix: Specify Poetry dependencies (
d3e3b5c
)
-
chore: Add CHANGELOG (
c5ce0f4
)Add a dummy CHANGELOG.md to be overwritten by Semantic Release.
-
chore: Add example requirements (
343b8e7
)Add a blank requirements file for the examples to facilitate adding requirements in the future.
-
ci: Omit
--fix
arg (2207516
)When running
ruff
via pre-commit, don't automatically fix the problems; instead tell the user what's wrong to train them into not making the problems in the first place. -
ci: Add semantic release templates (
0cb13c1
)Add templates for the release notes and
CHANGELOG
sopython-semantic-release
can generate these files correctly in CI. -
ci: Check documentation spelling and coverage (
e5b3719
) -
ci: pre-commit auto-update (
452fb68
)updates:
-
ci: Add semantic release workflow (
7725e5e
)
- docs: Slight tweaks to contributing guidelines (
59325de
)
-
patch: Indicate that the package is typed (
55a20c9
)According to PEP 561, we need to add this file to static type checkers can infer the types from the package.
- test: Run the examples and check their output (
ccfa0d9
)
-
refactor!: Make boolean parameters keyword-only (
2f3098f
) -
refactor!: Rename package (
8f42c66
)Rename
driver-script
tostaged-script
in preparation for a future decoupling of the stage behavior from the shell interaction. -
refactor!: Stages no longer registered by default (
b3ac262
)Since its inception,
DriverScript
'sstage
decorator has attempted to capture all thestage
s defined byDriverScript
subclasses in thestages
class variable automatically. The desire was to keep things as easy as possible for subclass developers, in that all they'd need to do was inherit fromDriverScript
, define some methods decorated withstage
, and thenDriverScript
would automatically handle things like stage-specific arguments (retries, etc.) and methods (pre/post, begin/end, etc.). Unfortunately this feature has been a thorn in our side for development, due to, e.g.,pytest
multiple-loading modules (and therefore redefining stages),DriverScript
subclass hierarchies, etc.In order to pave the way for the flexibility for one
DriverScript
subclass to use stages defined within a separateDriverScript
subclass, this commit makes it such that stages are no longer automatically registered. Instead subclass developers must pass the set of stages to register into the constructor when instantiating an object. This is a minor inconvenience, but it removes a good deal of hacky code and makes it such thatDriverScript
subclasses are decoupled from one another, so we believe the change is well worth it in the long run.Note that this is a breaking change, as all subclasses must be update their constructor definitions and any instantiations.
-
refactor!: Switch stages to standard set (
525fd79
)Initially the
stages
attribute of aDriverScript
class was implemented as an ordered set (which in Python is a value-lessdict
converted to alist
). The thinking there was that aDriverScript
subclass should define a series of stages in order and they would be executed in that order. However, this failed to consider the following use case: ClassA
inherits fromDriverScript
and defines a few stages, then classB
inherits fromA
and defines few more, but the intended sequence of stages isn't all fromA
followed by all fromB
; instead, they're meant to be interspersed. Since this is a valid use case, it makes sense to switchstages
over to a standardset
.Another motivation for the
stages
being an ordered set was considering the possibility of wanting to return to a prior stage if a certain stage failed. Consider an exampleDriverScript
subclass with stages to configure, build, and test a code. If the test stage fails, perhaps the failure was seemingly random, and it'd be worthwhile to automatically rewind and retry the build and test stages again before notifying anyone of the failure. Or perhaps a certain regex match in the test output indicates you should rewind further and reconfigure. However, after further reflection, allowing such flexibility would open up a can of worms that probably shouldn't be opened.DriverScript
already allows a subclass developer to automatically retry a stage. If something's happening that would cause you to back up further than the current stage and try things again, that probably means there's flakiness either in your code base or its surrounding infrastructure that a human should look into, soDriverScript
probably shouldn't allow you to hide that.Note that this might be a breaking change if any subclasses were relying on the ordering of the
stages
. -
feat!: Create RetryStage exception (
d5e8941
)Rather than relying on stages raising a
tenacity.TryAgain
exception to trigger retrying a stage, add aRetryStage
exception to the package. This makes things more explicit for subclass developers, and makes it such that something outside the subclass developer's control that happens to raise aTryAgain
doesn't trigger retying the stage, unless of course the subclass developer catches it and then raises aRetryStage
in its place.Note that this is a breaking change, because any subclasses relying on raising
TryAgain
to trigger a stage retry will need to be updated to raise the new exception. -
fix!: Handle --dry-run correctly (
8f436af
)When a
DriverScript
subclass is run in dry-run mode, instead of executing commands in the shell, print a message indicating what would have been run. Prior to this,DriverScript
provided the flag, but relied on subclass developers to ensure commands weren't run. This was an oversight.Note that this is a breaking change, as behavior of the
run()
method has fundamentally changed for dry-run mode. -
feat!: Add stage retry functionality (
d27ce6f
)Add the ability to automatically retry a stage that raises a
tenacity.TryAgain
exception:- Provide default implementations for methods to prepare to retry a stage and appropriately handle when retrying ultimately fails, while allowing subclass developers to override them or customize them on a stage-by-stage basis.
- Provide documentation to instruct subclass developers on how to make use of the retry functionality.
- Wrap the Begin-Stage Actions, Stage Body, and End-Stage Actions in the retrying loop.
Note that this is marked as a breaking change, as it's unclear what will happen to any subclasses that implemented their own stage retry functionality outside of this. The safest thing will be for subclass developers to update their subclasses to use this capability now provided by the base class.
-
feat!: Provide retry args for every stage (
281c376
)Automatically add command line arguments to govern stage retry behavior (number of retry attempts, how long to wait between retries, total time to spend trying the stage) for every stage defined in a subclass.
Note that this is a breaking change, because existing subclasses that currently define identical command line arguments will no longer work. Subclasses must be updated to remove their retry arguments and allow the base class to define them.
-
refactor!: Set current stage earlier (
27d571f
)Set the
current_stage
upon entering thestage
wrapper, rather than in the_begin_stage
method. Usecurrent_stage
in place of thestage_name
passed into the wrapper, where appropriate.Note that this is a breaking change, as it changes the signature for the
_begin_stage
method. -
refactor!: Stages always return None (
b1238be
)In preparation for adding stage retry functionality, make it such that a function decorated with
DriverScript.stage
must returnNone
. This is reasonable because a conceptual stage of a script does something, but doesn't return something.Note that this is a breaking change for
DriverScript
, as any subclasses relying on returning values from functions decorated withstage
will no longer work. A follow-up commit will fix this problem forGMSSystemTest
. -
test!: Cover
_add_stage
(e079a72
)Ensure
_add_stage
results in the correct list ofstages
, and that invalid identifiers do indeed throw an exception.Note that this is a breaking change because it now disallows certain stage names that were previously allowable.
-
feat!: Allow stages to be run multiple times (
e147b03
)Convert the
durations
attribute from adict
to alist
to allow for the possibility that one or more stages might be run multiple times (e.g., if something failed). Introduce aStageDuration
class that inherits fromNamedTuple
, such that the entries added to the list must always be a(str, timedelta)
tuple
that will from then on be immutable and allow easy member access via dot notation.
-
chore: Update .gitignore (
815c8cd
) -
chore: Ignore mypy warnings (
4dbf516
)Temporarily disable these warnings until there's time to revisit and address them.
-
chore: Add version to init.py (
f42f22d
) -
chore: Remove YAPF comments (
86f5cfe
)No longer needed after switching from YAPF to Ruff.
-
chore: Ignore mypy warnings (
a21b0c2
)Temporarily disable these warnings until there's time to revisit and address them.
-
chore: Ignore unchecked shell input (
520b68e
)When we built the precursor to
staged-script
, we didn't understand the security implications of having the user pass commands to the underlying shell as a string rather than a list of strings. It just seemed like a better interface, to make it easy for the user writing their Python scripts to simply wrap their bash commands. However, this opens up a danger for bad actors to cause problems via command injection. We can remove the vulnerability by switching to only allowing a list of strings as input torun()
, but that breaking change will need to wait till another day when I have more time available. -
chore: Use installed reverse_argparse (
7a3d1b7
) -
chore: Move init.py (
ba94a17
) -
chore: Remove unnecessary shebang lines (
3516d84
) -
chore: Add requirements files (
0dc5512
) -
chore: Add pyproject.toml (
e81f2d2
) -
chore: Add GitHub issur/PR templates (
017b544
)
-
ci: pre-commit auto-update (
11cc2e1
)updates:
-
ci: pre-commit auto-update (
ff4203a
)updates:
-
ci: pre-commit auto-update (
66eb281
)updates:
-
ci: Add ReadTheDocs configuration (
40f08f2
) -
ci: Don't fail fast (
0d3a5e3
)If one job in the matrix of jobs fails, we still want to be able to see the results from the other jobs.
-
ci: Stub out workflow (
c2ab413
) -
ci: Add OpenSSF Scorecard workflow (
f2904b7
) -
ci: pre-commit auto-update (
82b4201
)updates:
-
ci: pre-commit auto-update (
099b7e6
)updates:
-
ci: pre-commit auto-update (
47ba3b7
)updates:
-
ci: Add pre-commit configuration (
d4823f4
)
-
docs: Remove WIP banner (
59bd6ce
)In preparation for the initial release, remove the banner indicating that open sourcing is still a work in progress.
-
docs: Fix typo (
e68b838
) -
docs: Create documentation and examples (
5336421
) -
docs: Stub out Sphinx documentation (
00bd9af
) -
docs: Add copyright/license text to source files (
b0c22fc
) -
docs: Fix docstring issues (
7365c87
) -
docs: Update OpenSSF Best Practices badge (
1633c78
) -
docs: Add contributing guidelines (
8c04e16
) -
docs: Add code of conduct (
579786e
) -
docs: Add security guidelines (
c66c1dd
) -
docs: Add README (
29c2ed3
) -
docs: Add license file (
4be6ebf
) -
docs: Update docstrings (
aaccd8d
)Provide additional clarity in
DriverScript
's documentation. -
docs: Update syntax (
5bb662a
)Update the instructions for overriding
print_script_execution_summary
to use the |= syntax for updating dictionaries. -
docs: Use "subclass" everywhere (
c6fa97d
)Instead of inconsistently switching between "subclass" and "child class" in docstrings, use "subclass" everywhere for consistency's sake.
-
docs: Add docstrings to
stage
inner functions (09b4797
)The number and size of the inner functions for the
stage
decorator are getting substantial enough that they really need docstrings at this point. -
docs: Update docstrings for stage methods (
966103c
)Fill in all the details regarding subclassing that were omitted in earlier commits.
-
feat: Add script name/stem attributes (
74c387d
)Capture the name and stem of the file being executed as attributes of
DriverScript
such that subclass developers can easily refer to them rather than determining them on the fly. This is useful for things like the script execution summary.Also add a unit test for
raise_parser_error()
, which was accidentally omitted in a prior commit. -
feat: Add help formatter to package (
b458d95
)Add a class to the
driver_script
package to use as a formatter class for theDriverScript
ArgumentParser
. Make it such that the parser description is treated as raw text (no automatic formatting is done), and show the default values for all arguments. -
feat: Add flag for printing commands (
7a7a0e0
)Add a flag when instantiating a
DriverScript
to govern whether commands should be printed immediately before running them. Default it toTrue
for backwards compatibility. Also provide a keyword argument to therun()
method that, if specified, will override the class flag. In this way users could, e.g., instantiate aDriverScript
, telling it to print all commands, and then specify that certain commands should not be printed. The opposite of this is also possible (e.g., don't print any commands, except this one and that one). -
feat: Add raise_parser_error (
0f60f8d
)Add a method to the
DriverScript
base class to raise a parser error when a user has done something wrong in specifying the command line arguments. This differs fromargparse.ArgumentParser.error()
in that it's a little more user friendly, printing the help text first, and then the particular error in yellow. -
feat: Capture script success/failure (
68ea1ae
)Provide an instance attribute to allow subclass developers to toggle whether the script has succeeded or failed, and include the result in the script execution summary.
-
feat: Allow custom "skip stage" phases (
7b27bfa
)Provide subclass developers with the flexibility to specialize the "skip stage" actions on a stage by stage basis.
-
feat: Allow custom "end stage" phases (
b30ea55
)Provide subclass developers with the flexibility to specialize the "end stage" actions on a stage by stage basis.
-
feat: Add post-stage actions (
8670752
)Add the flexibility to allow subclass designers to specify post-stage actions to run after a stage ends. These can be specified for all stages, and they can also optionally be customized on a stage by stage basis.
-
feat: Allow custom "begin stage" phases (
f05a5d4
)Provide subclass developers with the flexibility to specialize the "begin stage" actions on a stage by stage basis.
-
feat: Add pre-stage actions (
fb6d51e
)Add the flexibility to allow subclass designers to specify pre-stage actions to run before a stage begins. These can be specified for all stages, and they can also optionally be customized on a stage by stage basis.
-
feat: Add script execution summary (
689a84a
)Add the ability to generate a summary of everything that was done by a derivative of
DriverScript
, including:- The effective command line invocation of the script.
- Any commands executed in the underlying shell.
- A timing report of the stages executed.
- Any additional information the user wishes to pass in.
-
fix: Retry group help text (
d237e38
)When I created the retry group in the argument parser, I didn't realize that I was using
add_argument_group
in a way in which it wasn't intended to be used. This commit brings things into conformity with howargparse
is intended to be used, specifying a one-word group name, followed by a more detailed group description.
-
refactor: Use functools.cached_property instead (
3d91282
)This package was originally developed for Python 3.6, before
functools.cached_property
was introduced. That should be a drop-in replacement for the home-grownlazy_property
, though, so now that we just support Python 3.8+, we should use it instead. -
refactor: Support down to Python 3.8 (
0c69f03
)- Switch type hinting to the older style.
- Use
dict.update()
instead of the|=
operator.
-
refactor: Reduce setup file (
b233553
)Remove the guts of the
setup.py
file so it just uses thepyproject.toml
under the hood. -
refactor: Specify UTC timezone (
1a95cd0
) -
refactor: Explicitly don't check for errors (
ed9d050
) -
refactor: Re-raise exception correctly (
889645d
) -
refactor: Save exception messages to variable (
2715390
) -
refactor: Rearrange DriverScript class (
e351982
)Rearrange the methods in the
DriverScript
class to make the class easier to understand. No functional changes; just cut from here, paste to there. Also prefix some methods with_
to indicate they're only intended for internal use. -
refactor: Use function from
reverse_argparse
(1c7fae0
)Since
reverse_argparse
now providesquote_arg_if_necessary()
as a public function, use this instead of reimplementing the functionality inDriverScript
. -
refactor: Get phase method rather than running it (
8af3f75
)In preparation for adding automatic retry functionality to the
stage
decorator, rewrite therun_phase
method such that instead of running the method corresponding to the phase, it simply returns theCallable
, which is then run outside the function. This generalization will make it such that we can pass a phase method to theRetrying
object when we're ready for that. -
refactor: Wrap retryable phases into a function (
345b77c
)In preparation for adding automatic retry functionality to the stage decorator, wrap the phases that are to be retried into a function so they're easy to call together.
-
refactor: Change custom naming convention (
e0b0f5f
)For simplicity's sake, when specializing one of the stage phases for a particular stage, just append the stage name to the end of the default method name.
-
refactor: Consolidate helper functions (
980dd7c
)Replace the helper functions inside the
stage
decorator with a single one that executes the correct methods based on input arguments. -
refactor: Use finally to end the stage (
c8539ba
)Rather than having
_end_stage()
called in two different places, consolidate those calls into one using afinally
clause of thetry
block. -
refactor: Add
run
method (2fe663a
)Create a
run
method to wrap calls tosubprocess.run
and capture the command executed. -
refactor: Add
parse_args
method to base class (c73e8eb
)Add the
parse_args
method to theDriverScript
base class to handle parsing the command line argument supplied by the base class. This will be overridden and extended by child classes. -
refactor: Add parser property to base class (
1c4f10f
)Add a
parser
lazily-evaluated property to theDriverScript
base class to handle parsing of arguments supplied by the base class. This will be overridden and extended by child classes. -
refactor: Use Rich Table for timing report (
1d24cd1
)Rather than generating the timing report table manually, use
rich.table.Table
to handle the magic automatically. Also abandon the Markdown format for the table, as Rich's default styling looks nicer, and if a user needs to copy it into an issue, they can always place it in a code block. -
refactor: Create DriverScript base class (
bb8ea46
)Create an initial cut of the
DriverScript
base class, such that any Python scripts designed to drive a series of commands in the underlying shell can inherit from it.
- style: Automatically format the code base (
2413186
) - style: Pytest parametrize tuple (
0211644
) - style: Match exception message (
c2353bd
) - style: User iterable unpacking (
9b18fac
) - style: Use f-string conversion flag (
56b2c45
)
-
test: Cover
run()
in dry-run mode (c44d6ff
) -
test: Add coverage configuration (
27bc6d6
) -
test: Fix imports for unit/integration tests (
e1836e3
) -
test: Rename tests (
2723351
)The convention is to name tests
test_<function_to_test>
, but these tests accidentally omitted the leading underscore. -
test: Rename test fixtures (
5f7b063
)Remove acronyms for clarity.
-
test: Disable warning on too many parametrizations (
99e59d9
) -
test: Remove duplicate test case (
176bb6f
) -
test: Reduce cognitive complexity (
5153a1b
)Extract a method from the test to reduce the amount of copy/paste/modify.
-
test: Complete testing of
DriverScript
(298b4a9
)Create a basic subclass of
DriverScript
to test the functionality of thestage
decorator. -
test: Cover additional case (
0ede83f
)Cover the base case when no additional sections are supplied when printing the script execution summary.
-
Merge branch 'driver-script-switch-stages-to-set' into 'develop' (
9157e38
)refactor!(DriverScript): Switch stages to standard set
See merge request gms/gms-common!10807
-
Merge branch 'driver-script-retry-stage-exception' into 'develop' (
10783ae
)DriverScript: Create RetryStage exception
See merge request gms/gms-common!10742
-
Merge branch 'driver-script-custom-help-formatter' into 'develop' (
928203c
)DriverScript: Add help formatter to package
See merge request gms/gms-common!10688
-
Merge branch 'driver-script-fix-help-text' into 'develop' (
e04abe6
)DriverScript: Fix retry group help text
Closes #2272
See merge request gms/gms-common!10685
-
Merge branch '2216-fix-how-driver-script-handles-dry-run' into 'develop' (
f94c3fd
)Fix how DriverScript handles --dry-run
Closes #2216
See merge request gms/gms-common!10576
-
Merge branch 'move-script-success-to-driver-script' into 'develop' (
6e1f46e
)Move script_success to DriverScript
Closes #2215
See merge request gms/gms-common!10574