backlogops 1.1__tar.gz → 1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {backlogops-1.1 → backlogops-1.3}/PKG-INFO +45 -11
- {backlogops-1.1 → backlogops-1.3}/README_pypi.md +40 -6
- {backlogops-1.1 → backlogops-1.3}/backlogops.egg-info/PKG-INFO +45 -11
- {backlogops-1.1 → backlogops-1.3}/backlogops.egg-info/SOURCES.txt +4 -0
- backlogops-1.3/backlogops.egg-info/requires.txt +8 -0
- {backlogops-1.1 → backlogops-1.3}/setup.py +5 -5
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/__init__.py +19 -8
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/available_teams_config.py +28 -17
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/backlog.py +7 -2
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/backlog_helpers.py +39 -3
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/backlog_ops_config.py +58 -21
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/backlog_ops_wizard.py +64 -2
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/backlog_releases.py +11 -3
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/config_descriptions.py +38 -2
- backlogops-1.3/src/backlogops/default_story_points.py +371 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/demo_backlog.py +69 -16
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/estimate_ready_date.py +70 -12
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/io_config.py +34 -18
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_io_config.py +12 -6
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_order_releases.py +9 -8
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_rank_move_keys.py +11 -11
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_read.py +6 -13
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_rename_releases.py +20 -19
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_update_backlog.py +124 -96
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_update_releases.py +13 -13
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_write.py +261 -299
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_write_fields.py +64 -7
- backlogops-1.3/src/backlogops/jira_write_format.py +173 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_write_releases.py +16 -15
- backlogops-1.3/src/backlogops/jira_write_status.py +136 -0
- backlogops-1.3/src/backlogops/jira_write_types.py +154 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/table_rows.py +26 -4
- backlogops-1.3/src/backlogops/use_story_points.py +76 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/wizard_helpers.py +109 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/wizard_navigator.py +17 -3
- backlogops-1.1/backlogops.egg-info/requires.txt +0 -8
- backlogops-1.1/src/backlogops/jira_write_format.py +0 -101
- {backlogops-1.1 → backlogops-1.3}/LICENSE.txt +0 -0
- {backlogops-1.1 → backlogops-1.3}/backlogops.egg-info/dependency_links.txt +0 -0
- {backlogops-1.1 → backlogops-1.3}/backlogops.egg-info/top_level.txt +0 -0
- {backlogops-1.1 → backlogops-1.3}/pyproject.toml +0 -0
- {backlogops-1.1 → backlogops-1.3}/setup.cfg +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/apply_format_rules.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/available_teams.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/backlog_in_release_order.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/backlog_releases_io.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/blo_version_reporter.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/config_editing.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/config_file_io.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/date_ranges.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/format_rules.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/io_preset_wizard.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_connect.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_rank_backlog.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_rank_by_keys.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_search.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_token.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/jira_wizard.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/key_list_io.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/levels.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/move_keys_first.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/name_list_io.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/no_text_io.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/order_by_dependencies.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/person.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/py.typed +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/release_backlog_updates.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/release_change_io.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/releases.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/rename_list_io.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/table_create.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/team.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/wizard_forms.py +0 -0
- {backlogops-1.1 → backlogops-1.3}/src/backlogops/work_hours.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: backlogops
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3
|
|
4
4
|
Summary: Library with backlog operations.
|
|
5
5
|
Author: Tom Björkholm
|
|
6
6
|
Author-email: Tom Björkholm <klausuler_linnet0q@icloud.com>
|
|
@@ -21,14 +21,14 @@ Classifier: Typing :: Typed
|
|
|
21
21
|
Requires-Python: >=3.12
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE.txt
|
|
24
|
-
Requires-Dist: config-as-json>=1.
|
|
24
|
+
Requires-Dist: config-as-json>=1.7
|
|
25
25
|
Requires-Dist: cryptography>=50.0.1
|
|
26
26
|
Requires-Dist: jira[cli,opt]>=3.10.5
|
|
27
27
|
Requires-Dist: tableio>=1.1
|
|
28
|
-
Requires-Dist: tableio-cfg-json>=1.
|
|
29
|
-
Requires-Dist: wizard-ui-bridge[textual]>=1.
|
|
28
|
+
Requires-Dist: tableio-cfg-json>=1.4
|
|
29
|
+
Requires-Dist: wizard-ui-bridge[textual]>=1.4
|
|
30
30
|
Requires-Dist: versionreporter>=0.4
|
|
31
|
-
Requires-Dist: edit-cfg-json>=0.
|
|
31
|
+
Requires-Dist: edit-cfg-json>=0.3.0
|
|
32
32
|
Dynamic: author
|
|
33
33
|
Dynamic: license-file
|
|
34
34
|
Dynamic: requires-dist
|
|
@@ -77,6 +77,10 @@ The following functionality is available in all 3 packages:
|
|
|
77
77
|
- Estimate ready date for the backlog items based on available teams, team
|
|
78
78
|
velocity, vacation dates, periods with half time work, etc.
|
|
79
79
|
|
|
80
|
+
- Configure what a backlog item that nobody has estimated counts as, per backlog
|
|
81
|
+
item level, so that an unestimated item does not make the estimated dates too
|
|
82
|
+
optimistic.
|
|
83
|
+
|
|
80
84
|
- Extract backlog keys at given backlog item levels.
|
|
81
85
|
|
|
82
86
|
- Reorder the backlog so that the dependencies are satisfied.
|
|
@@ -111,7 +115,16 @@ The following functionality is available in all 3 packages:
|
|
|
111
115
|
- Migrate an older configuration or preset file to the current file format.
|
|
112
116
|
|
|
113
117
|
- A wizard to create a backlog-ops configuration file with the workforce, named
|
|
114
|
-
input and output presets, level names,
|
|
118
|
+
input and output presets, level names, status name mapping, the guess for
|
|
119
|
+
unestimated items, how the graphical user interface shows the data, and the
|
|
120
|
+
Jira integration.
|
|
121
|
+
|
|
122
|
+
- An editor showing a whole configuration file or a stand-alone preset file at
|
|
123
|
+
once, folded where it is deep, to change a single value without stepping
|
|
124
|
+
through the wizard.
|
|
125
|
+
|
|
126
|
+
- Encrypt the Jira API token to a pass-phrase-protected file, so that no
|
|
127
|
+
configuration file holds the token in clear text.
|
|
115
128
|
|
|
116
129
|
- Read a backlog and releases from Jira into a backlog and release table.
|
|
117
130
|
|
|
@@ -130,6 +143,10 @@ The following functionality is available in all 3 packages:
|
|
|
130
143
|
- Move backlog items to a chosen anchor in the Jira rank order, following a key
|
|
131
144
|
list.
|
|
132
145
|
|
|
146
|
+
- Report what a Jira operation did not do. Every Jira result opens with what
|
|
147
|
+
Jira refused or what was skipped, so a value that was not written is visible
|
|
148
|
+
without reading the whole listing.
|
|
149
|
+
|
|
133
150
|
## The operating model
|
|
134
151
|
|
|
135
152
|
The operating model that most of the functionality is designed for is that the
|
|
@@ -154,7 +171,10 @@ the library:
|
|
|
154
171
|
|
|
155
172
|
- `title` The title of the backlog item. Required.
|
|
156
173
|
|
|
157
|
-
- `story_points` The story points of the backlog item.
|
|
174
|
+
- `story_points` The story points of the backlog item. Optional. An item with no
|
|
175
|
+
story points is one that nobody has estimated yet, and what such an item is
|
|
176
|
+
worked with when a completion date is estimated is configured. May be a
|
|
177
|
+
fraction, such as 0.5.
|
|
158
178
|
|
|
159
179
|
- `status` The status of the backlog item. Required.
|
|
160
180
|
|
|
@@ -262,8 +282,10 @@ from backlogops import (
|
|
|
262
282
|
|
|
263
283
|
- `read_backlog_ops_config`, `write_backlog_ops_config`,
|
|
264
284
|
`get_backlog_ops_config`: read, write, and look up the top-level
|
|
265
|
-
`BacklogOpsConfig` (workforce, named input and output presets,
|
|
266
|
-
|
|
285
|
+
`BacklogOpsConfig` (workforce, named input and output presets, the
|
|
286
|
+
status-name map, the guess for unestimated items, the GUI display
|
|
287
|
+
settings, the Jira configuration, and the optional backlog item
|
|
288
|
+
levels).
|
|
267
289
|
|
|
268
290
|
- `read_key_list`, `write_key_list`: read and write a list of keys.
|
|
269
291
|
|
|
@@ -295,6 +317,11 @@ from backlogops import (
|
|
|
295
317
|
- `estimate_ready_date`, `set_plan_from_estimate`: estimate ready dates
|
|
296
318
|
and set planned dates from the estimate.
|
|
297
319
|
|
|
320
|
+
- `DefaultStoryPoints`, `use_story_points`: what a backlog item that
|
|
321
|
+
nobody has estimated counts as, and the story points to work any one
|
|
322
|
+
item with. The estimate uses them, so an unestimated item does not
|
|
323
|
+
count as free.
|
|
324
|
+
|
|
298
325
|
- `estimate_release_dates`, `release_plan_on_estimate`,
|
|
299
326
|
`adjust_release_content`: estimate and plan release dates, and adjust
|
|
300
327
|
release content to fit the planned dates.
|
|
@@ -321,14 +348,21 @@ from backlogops import (
|
|
|
321
348
|
- `JiraIOConfig`, `JiraPreset`: the Jira connection and preset
|
|
322
349
|
configuration.
|
|
323
350
|
|
|
351
|
+
- `format_add_result`, `format_backlog_updates`, `format_release_result`,
|
|
352
|
+
`format_release_updates`, `format_rank_result`, `format_order_result`,
|
|
353
|
+
`format_rename_result`: turn the result of a Jira operation into a
|
|
354
|
+
listing that opens with what Jira refused or what was skipped.
|
|
355
|
+
`report_has_problems` answers whether such a listing reports something
|
|
356
|
+
that did not happen, which is what marks it in a user interface.
|
|
357
|
+
|
|
324
358
|
For the full set of public names see the API documentation linked above.
|
|
325
359
|
|
|
326
360
|
## Test summary
|
|
327
361
|
|
|
328
|
-
- Test result:
|
|
362
|
+
- Test result: 2555 passed, 1 deselected in 58s
|
|
329
363
|
- No flake8 warnings.
|
|
330
364
|
- No mypy errors found.
|
|
331
365
|
- No pylint warnings.
|
|
332
366
|
- No python layout warnings.
|
|
333
|
-
- Built version(s): 1.
|
|
367
|
+
- Built version(s): 1.3
|
|
334
368
|
- Build and test using Python 3.14.7
|
|
@@ -41,6 +41,10 @@ The following functionality is available in all 3 packages:
|
|
|
41
41
|
- Estimate ready date for the backlog items based on available teams, team
|
|
42
42
|
velocity, vacation dates, periods with half time work, etc.
|
|
43
43
|
|
|
44
|
+
- Configure what a backlog item that nobody has estimated counts as, per backlog
|
|
45
|
+
item level, so that an unestimated item does not make the estimated dates too
|
|
46
|
+
optimistic.
|
|
47
|
+
|
|
44
48
|
- Extract backlog keys at given backlog item levels.
|
|
45
49
|
|
|
46
50
|
- Reorder the backlog so that the dependencies are satisfied.
|
|
@@ -75,7 +79,16 @@ The following functionality is available in all 3 packages:
|
|
|
75
79
|
- Migrate an older configuration or preset file to the current file format.
|
|
76
80
|
|
|
77
81
|
- A wizard to create a backlog-ops configuration file with the workforce, named
|
|
78
|
-
input and output presets, level names,
|
|
82
|
+
input and output presets, level names, status name mapping, the guess for
|
|
83
|
+
unestimated items, how the graphical user interface shows the data, and the
|
|
84
|
+
Jira integration.
|
|
85
|
+
|
|
86
|
+
- An editor showing a whole configuration file or a stand-alone preset file at
|
|
87
|
+
once, folded where it is deep, to change a single value without stepping
|
|
88
|
+
through the wizard.
|
|
89
|
+
|
|
90
|
+
- Encrypt the Jira API token to a pass-phrase-protected file, so that no
|
|
91
|
+
configuration file holds the token in clear text.
|
|
79
92
|
|
|
80
93
|
- Read a backlog and releases from Jira into a backlog and release table.
|
|
81
94
|
|
|
@@ -94,6 +107,10 @@ The following functionality is available in all 3 packages:
|
|
|
94
107
|
- Move backlog items to a chosen anchor in the Jira rank order, following a key
|
|
95
108
|
list.
|
|
96
109
|
|
|
110
|
+
- Report what a Jira operation did not do. Every Jira result opens with what
|
|
111
|
+
Jira refused or what was skipped, so a value that was not written is visible
|
|
112
|
+
without reading the whole listing.
|
|
113
|
+
|
|
97
114
|
## The operating model
|
|
98
115
|
|
|
99
116
|
The operating model that most of the functionality is designed for is that the
|
|
@@ -118,7 +135,10 @@ the library:
|
|
|
118
135
|
|
|
119
136
|
- `title` The title of the backlog item. Required.
|
|
120
137
|
|
|
121
|
-
- `story_points` The story points of the backlog item.
|
|
138
|
+
- `story_points` The story points of the backlog item. Optional. An item with no
|
|
139
|
+
story points is one that nobody has estimated yet, and what such an item is
|
|
140
|
+
worked with when a completion date is estimated is configured. May be a
|
|
141
|
+
fraction, such as 0.5.
|
|
122
142
|
|
|
123
143
|
- `status` The status of the backlog item. Required.
|
|
124
144
|
|
|
@@ -226,8 +246,10 @@ from backlogops import (
|
|
|
226
246
|
|
|
227
247
|
- `read_backlog_ops_config`, `write_backlog_ops_config`,
|
|
228
248
|
`get_backlog_ops_config`: read, write, and look up the top-level
|
|
229
|
-
`BacklogOpsConfig` (workforce, named input and output presets,
|
|
230
|
-
|
|
249
|
+
`BacklogOpsConfig` (workforce, named input and output presets, the
|
|
250
|
+
status-name map, the guess for unestimated items, the GUI display
|
|
251
|
+
settings, the Jira configuration, and the optional backlog item
|
|
252
|
+
levels).
|
|
231
253
|
|
|
232
254
|
- `read_key_list`, `write_key_list`: read and write a list of keys.
|
|
233
255
|
|
|
@@ -259,6 +281,11 @@ from backlogops import (
|
|
|
259
281
|
- `estimate_ready_date`, `set_plan_from_estimate`: estimate ready dates
|
|
260
282
|
and set planned dates from the estimate.
|
|
261
283
|
|
|
284
|
+
- `DefaultStoryPoints`, `use_story_points`: what a backlog item that
|
|
285
|
+
nobody has estimated counts as, and the story points to work any one
|
|
286
|
+
item with. The estimate uses them, so an unestimated item does not
|
|
287
|
+
count as free.
|
|
288
|
+
|
|
262
289
|
- `estimate_release_dates`, `release_plan_on_estimate`,
|
|
263
290
|
`adjust_release_content`: estimate and plan release dates, and adjust
|
|
264
291
|
release content to fit the planned dates.
|
|
@@ -285,14 +312,21 @@ from backlogops import (
|
|
|
285
312
|
- `JiraIOConfig`, `JiraPreset`: the Jira connection and preset
|
|
286
313
|
configuration.
|
|
287
314
|
|
|
315
|
+
- `format_add_result`, `format_backlog_updates`, `format_release_result`,
|
|
316
|
+
`format_release_updates`, `format_rank_result`, `format_order_result`,
|
|
317
|
+
`format_rename_result`: turn the result of a Jira operation into a
|
|
318
|
+
listing that opens with what Jira refused or what was skipped.
|
|
319
|
+
`report_has_problems` answers whether such a listing reports something
|
|
320
|
+
that did not happen, which is what marks it in a user interface.
|
|
321
|
+
|
|
288
322
|
For the full set of public names see the API documentation linked above.
|
|
289
323
|
|
|
290
324
|
## Test summary
|
|
291
325
|
|
|
292
|
-
- Test result:
|
|
326
|
+
- Test result: 2555 passed, 1 deselected in 58s
|
|
293
327
|
- No flake8 warnings.
|
|
294
328
|
- No mypy errors found.
|
|
295
329
|
- No pylint warnings.
|
|
296
330
|
- No python layout warnings.
|
|
297
|
-
- Built version(s): 1.
|
|
331
|
+
- Built version(s): 1.3
|
|
298
332
|
- Build and test using Python 3.14.7
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: backlogops
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3
|
|
4
4
|
Summary: Library with backlog operations.
|
|
5
5
|
Author: Tom Björkholm
|
|
6
6
|
Author-email: Tom Björkholm <klausuler_linnet0q@icloud.com>
|
|
@@ -21,14 +21,14 @@ Classifier: Typing :: Typed
|
|
|
21
21
|
Requires-Python: >=3.12
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE.txt
|
|
24
|
-
Requires-Dist: config-as-json>=1.
|
|
24
|
+
Requires-Dist: config-as-json>=1.7
|
|
25
25
|
Requires-Dist: cryptography>=50.0.1
|
|
26
26
|
Requires-Dist: jira[cli,opt]>=3.10.5
|
|
27
27
|
Requires-Dist: tableio>=1.1
|
|
28
|
-
Requires-Dist: tableio-cfg-json>=1.
|
|
29
|
-
Requires-Dist: wizard-ui-bridge[textual]>=1.
|
|
28
|
+
Requires-Dist: tableio-cfg-json>=1.4
|
|
29
|
+
Requires-Dist: wizard-ui-bridge[textual]>=1.4
|
|
30
30
|
Requires-Dist: versionreporter>=0.4
|
|
31
|
-
Requires-Dist: edit-cfg-json>=0.
|
|
31
|
+
Requires-Dist: edit-cfg-json>=0.3.0
|
|
32
32
|
Dynamic: author
|
|
33
33
|
Dynamic: license-file
|
|
34
34
|
Dynamic: requires-dist
|
|
@@ -77,6 +77,10 @@ The following functionality is available in all 3 packages:
|
|
|
77
77
|
- Estimate ready date for the backlog items based on available teams, team
|
|
78
78
|
velocity, vacation dates, periods with half time work, etc.
|
|
79
79
|
|
|
80
|
+
- Configure what a backlog item that nobody has estimated counts as, per backlog
|
|
81
|
+
item level, so that an unestimated item does not make the estimated dates too
|
|
82
|
+
optimistic.
|
|
83
|
+
|
|
80
84
|
- Extract backlog keys at given backlog item levels.
|
|
81
85
|
|
|
82
86
|
- Reorder the backlog so that the dependencies are satisfied.
|
|
@@ -111,7 +115,16 @@ The following functionality is available in all 3 packages:
|
|
|
111
115
|
- Migrate an older configuration or preset file to the current file format.
|
|
112
116
|
|
|
113
117
|
- A wizard to create a backlog-ops configuration file with the workforce, named
|
|
114
|
-
input and output presets, level names,
|
|
118
|
+
input and output presets, level names, status name mapping, the guess for
|
|
119
|
+
unestimated items, how the graphical user interface shows the data, and the
|
|
120
|
+
Jira integration.
|
|
121
|
+
|
|
122
|
+
- An editor showing a whole configuration file or a stand-alone preset file at
|
|
123
|
+
once, folded where it is deep, to change a single value without stepping
|
|
124
|
+
through the wizard.
|
|
125
|
+
|
|
126
|
+
- Encrypt the Jira API token to a pass-phrase-protected file, so that no
|
|
127
|
+
configuration file holds the token in clear text.
|
|
115
128
|
|
|
116
129
|
- Read a backlog and releases from Jira into a backlog and release table.
|
|
117
130
|
|
|
@@ -130,6 +143,10 @@ The following functionality is available in all 3 packages:
|
|
|
130
143
|
- Move backlog items to a chosen anchor in the Jira rank order, following a key
|
|
131
144
|
list.
|
|
132
145
|
|
|
146
|
+
- Report what a Jira operation did not do. Every Jira result opens with what
|
|
147
|
+
Jira refused or what was skipped, so a value that was not written is visible
|
|
148
|
+
without reading the whole listing.
|
|
149
|
+
|
|
133
150
|
## The operating model
|
|
134
151
|
|
|
135
152
|
The operating model that most of the functionality is designed for is that the
|
|
@@ -154,7 +171,10 @@ the library:
|
|
|
154
171
|
|
|
155
172
|
- `title` The title of the backlog item. Required.
|
|
156
173
|
|
|
157
|
-
- `story_points` The story points of the backlog item.
|
|
174
|
+
- `story_points` The story points of the backlog item. Optional. An item with no
|
|
175
|
+
story points is one that nobody has estimated yet, and what such an item is
|
|
176
|
+
worked with when a completion date is estimated is configured. May be a
|
|
177
|
+
fraction, such as 0.5.
|
|
158
178
|
|
|
159
179
|
- `status` The status of the backlog item. Required.
|
|
160
180
|
|
|
@@ -262,8 +282,10 @@ from backlogops import (
|
|
|
262
282
|
|
|
263
283
|
- `read_backlog_ops_config`, `write_backlog_ops_config`,
|
|
264
284
|
`get_backlog_ops_config`: read, write, and look up the top-level
|
|
265
|
-
`BacklogOpsConfig` (workforce, named input and output presets,
|
|
266
|
-
|
|
285
|
+
`BacklogOpsConfig` (workforce, named input and output presets, the
|
|
286
|
+
status-name map, the guess for unestimated items, the GUI display
|
|
287
|
+
settings, the Jira configuration, and the optional backlog item
|
|
288
|
+
levels).
|
|
267
289
|
|
|
268
290
|
- `read_key_list`, `write_key_list`: read and write a list of keys.
|
|
269
291
|
|
|
@@ -295,6 +317,11 @@ from backlogops import (
|
|
|
295
317
|
- `estimate_ready_date`, `set_plan_from_estimate`: estimate ready dates
|
|
296
318
|
and set planned dates from the estimate.
|
|
297
319
|
|
|
320
|
+
- `DefaultStoryPoints`, `use_story_points`: what a backlog item that
|
|
321
|
+
nobody has estimated counts as, and the story points to work any one
|
|
322
|
+
item with. The estimate uses them, so an unestimated item does not
|
|
323
|
+
count as free.
|
|
324
|
+
|
|
298
325
|
- `estimate_release_dates`, `release_plan_on_estimate`,
|
|
299
326
|
`adjust_release_content`: estimate and plan release dates, and adjust
|
|
300
327
|
release content to fit the planned dates.
|
|
@@ -321,14 +348,21 @@ from backlogops import (
|
|
|
321
348
|
- `JiraIOConfig`, `JiraPreset`: the Jira connection and preset
|
|
322
349
|
configuration.
|
|
323
350
|
|
|
351
|
+
- `format_add_result`, `format_backlog_updates`, `format_release_result`,
|
|
352
|
+
`format_release_updates`, `format_rank_result`, `format_order_result`,
|
|
353
|
+
`format_rename_result`: turn the result of a Jira operation into a
|
|
354
|
+
listing that opens with what Jira refused or what was skipped.
|
|
355
|
+
`report_has_problems` answers whether such a listing reports something
|
|
356
|
+
that did not happen, which is what marks it in a user interface.
|
|
357
|
+
|
|
324
358
|
For the full set of public names see the API documentation linked above.
|
|
325
359
|
|
|
326
360
|
## Test summary
|
|
327
361
|
|
|
328
|
-
- Test result:
|
|
362
|
+
- Test result: 2555 passed, 1 deselected in 58s
|
|
329
363
|
- No flake8 warnings.
|
|
330
364
|
- No mypy errors found.
|
|
331
365
|
- No pylint warnings.
|
|
332
366
|
- No python layout warnings.
|
|
333
|
-
- Built version(s): 1.
|
|
367
|
+
- Built version(s): 1.3
|
|
334
368
|
- Build and test using Python 3.14.7
|
|
@@ -23,6 +23,7 @@ src/backlogops/config_descriptions.py
|
|
|
23
23
|
src/backlogops/config_editing.py
|
|
24
24
|
src/backlogops/config_file_io.py
|
|
25
25
|
src/backlogops/date_ranges.py
|
|
26
|
+
src/backlogops/default_story_points.py
|
|
26
27
|
src/backlogops/demo_backlog.py
|
|
27
28
|
src/backlogops/estimate_ready_date.py
|
|
28
29
|
src/backlogops/format_rules.py
|
|
@@ -45,6 +46,8 @@ src/backlogops/jira_write.py
|
|
|
45
46
|
src/backlogops/jira_write_fields.py
|
|
46
47
|
src/backlogops/jira_write_format.py
|
|
47
48
|
src/backlogops/jira_write_releases.py
|
|
49
|
+
src/backlogops/jira_write_status.py
|
|
50
|
+
src/backlogops/jira_write_types.py
|
|
48
51
|
src/backlogops/key_list_io.py
|
|
49
52
|
src/backlogops/levels.py
|
|
50
53
|
src/backlogops/move_keys_first.py
|
|
@@ -60,6 +63,7 @@ src/backlogops/rename_list_io.py
|
|
|
60
63
|
src/backlogops/table_create.py
|
|
61
64
|
src/backlogops/table_rows.py
|
|
62
65
|
src/backlogops/team.py
|
|
66
|
+
src/backlogops/use_story_points.py
|
|
63
67
|
src/backlogops/wizard_forms.py
|
|
64
68
|
src/backlogops/wizard_helpers.py
|
|
65
69
|
src/backlogops/wizard_navigator.py
|
|
@@ -5,7 +5,7 @@ from setuptools import setup
|
|
|
5
5
|
|
|
6
6
|
setup(
|
|
7
7
|
name='backlogops',
|
|
8
|
-
version='1.
|
|
8
|
+
version='1.3',
|
|
9
9
|
description='Library with backlog operations.',
|
|
10
10
|
author='Tom Björkholm',
|
|
11
11
|
author_email='klausuler_linnet0q@icloud.com',
|
|
@@ -14,13 +14,13 @@ setup(
|
|
|
14
14
|
package_dir={'backlogops': 'src/backlogops'},
|
|
15
15
|
package_data={'backlogops': ['src/py.typed']},
|
|
16
16
|
install_requires=[
|
|
17
|
-
'config-as-json >= 1.
|
|
17
|
+
'config-as-json >= 1.7',
|
|
18
18
|
'cryptography >= 50.0.1',
|
|
19
19
|
'jira[cli,opt] >= 3.10.5',
|
|
20
20
|
'tableio >= 1.1',
|
|
21
|
-
'tableio-cfg-json >= 1.
|
|
22
|
-
'wizard-ui-bridge[textual] >= 1.
|
|
21
|
+
'tableio-cfg-json >= 1.4',
|
|
22
|
+
'wizard-ui-bridge[textual] >= 1.4',
|
|
23
23
|
'versionreporter >= 0.4',
|
|
24
|
-
'edit-cfg-json >= 0.
|
|
24
|
+
'edit-cfg-json >= 0.3.0',
|
|
25
25
|
]
|
|
26
26
|
)
|
|
@@ -36,6 +36,8 @@ from backlogops.config_editing import EDIT_SETTINGS, descriptions_for
|
|
|
36
36
|
from backlogops.config_file_io import (
|
|
37
37
|
CONFIG_EXTENSION, io_preset_class, read_io_preset, safe_write_config)
|
|
38
38
|
from backlogops.date_ranges import check_date_range, check_no_overlap
|
|
39
|
+
from backlogops.default_story_points import (
|
|
40
|
+
DefaultStoryPointLevel, DefaultStoryPoints)
|
|
39
41
|
from backlogops.demo_backlog import get_demo_backlog
|
|
40
42
|
from backlogops.estimate_ready_date import (
|
|
41
43
|
estimate_ready_date, set_plan_from_estimate)
|
|
@@ -72,11 +74,14 @@ from backlogops.jira_update_releases import (
|
|
|
72
74
|
UpdatedReleasesInJira, format_release_updates, update_releases_in_jira)
|
|
73
75
|
from backlogops.jira_write import (
|
|
74
76
|
AddedToJira, ExistsInJiraError, FailedItem, ItemNotInJiraError,
|
|
75
|
-
OnExistingKey, OnMissingKey,
|
|
77
|
+
OnExistingKey, OnMissingKey,
|
|
76
78
|
add_backlog_to_jira, apply_jira_keys, jira_custom_fields,
|
|
77
79
|
jira_editable_fields)
|
|
78
|
-
from backlogops.jira_write_fields import FailedLink
|
|
79
|
-
from backlogops.
|
|
80
|
+
from backlogops.jira_write_fields import FailedField, FailedLink
|
|
81
|
+
from backlogops.jira_write_status import StatusMismatch
|
|
82
|
+
from backlogops.jira_write_types import UnknownIssueTypeError
|
|
83
|
+
from backlogops.jira_write_format import (
|
|
84
|
+
format_add_result, report_has_problems)
|
|
80
85
|
from backlogops.jira_write_releases import (
|
|
81
86
|
AddedReleasesToJira, FailedRelease, ReleaseExistsError,
|
|
82
87
|
add_releases_to_jira, format_release_result)
|
|
@@ -105,6 +110,8 @@ from backlogops.table_rows import (
|
|
|
105
110
|
display_level_rows, fold_level_name, item_to_row, map_column_order,
|
|
106
111
|
release_to_row, row_to_item, row_to_release)
|
|
107
112
|
from backlogops.team import FteException, Membership, Team
|
|
113
|
+
from backlogops.use_story_points import find_keys_with_children, \
|
|
114
|
+
use_story_points
|
|
108
115
|
from backlogops.work_hours import (
|
|
109
116
|
CompanyWorkHours, DEFAULT_WORK_WEEK, ExceptionWorkHours, ScheduleWorkHours,
|
|
110
117
|
WeekDay)
|
|
@@ -116,9 +123,11 @@ __all__ = [
|
|
|
116
123
|
'CLEAR_TOKEN_WARNING', 'CONFIG_DESCRIPTIONS', 'CONFIG_EXTENSION',
|
|
117
124
|
'CompanyWorkHours', 'DEFAULT_LEVELS',
|
|
118
125
|
'DEFAULT_WORK_WEEK', 'DEF_BACKLOG_COLUMN_MAP', 'DEF_RELEASE_COLUMN_MAP',
|
|
119
|
-
'DEF_STATUS_INPUT_MAP', '
|
|
126
|
+
'DEF_STATUS_INPUT_MAP', 'DefaultStoryPointLevel', 'DefaultStoryPoints',
|
|
127
|
+
'DependencyMode', 'EDIT_SETTINGS',
|
|
120
128
|
'ExceptionWorkHours',
|
|
121
|
-
'ExistsInJiraError', '
|
|
129
|
+
'ExistsInJiraError', 'FailedField', 'FailedItem', 'FailedLink',
|
|
130
|
+
'FailedRelease',
|
|
122
131
|
'FailedRename', 'FileExistsCb', 'FormatRules', 'FteException',
|
|
123
132
|
'GUI_DESCRIPTIONS', 'GuiDisplayConfig', 'INPUT_DESCRIPTIONS',
|
|
124
133
|
'InputFormatConfig', 'ItemNotInJiraError', 'JIRA_DESCRIPTIONS',
|
|
@@ -145,7 +154,8 @@ __all__ = [
|
|
|
145
154
|
'display_level_order', 'display_level_rows',
|
|
146
155
|
'encrypt_token_file',
|
|
147
156
|
'encrypt_token_to_file', 'estimate_ready_date', 'estimate_release_dates',
|
|
148
|
-
'event_finish', 'event_start', 'find_cycle', '
|
|
157
|
+
'event_finish', 'event_start', 'find_cycle', 'find_keys_with_children',
|
|
158
|
+
'fold_level_name',
|
|
149
159
|
'format_add_result', 'format_backlog', 'format_backlog_updates',
|
|
150
160
|
'format_content_changes', 'format_date_changes', 'format_order_result',
|
|
151
161
|
'format_rank_result', 'format_release_result', 'format_release_updates',
|
|
@@ -163,10 +173,11 @@ __all__ = [
|
|
|
163
173
|
'read_backlog_ops_config', 'read_backlog_releases', 'read_io_preset',
|
|
164
174
|
'read_jira_from_config', 'read_key_list', 'read_name_list', 'read_renames',
|
|
165
175
|
'release_plan_on_estimate', 'release_to_row', 'rename_release_in_jira',
|
|
166
|
-
'rename_releases_in_jira', '
|
|
176
|
+
'rename_releases_in_jira', 'report_has_problems',
|
|
177
|
+
'resolve_input_config', 'resolve_jql',
|
|
167
178
|
'resolve_output_config', 'row_to_item', 'row_to_release',
|
|
168
179
|
'safe_write_config', 'set_plan_from_estimate', 'updatable_backlog_fields',
|
|
169
|
-
'update_backlog_in_jira', 'update_releases_in_jira',
|
|
180
|
+
'update_backlog_in_jira', 'update_releases_in_jira', 'use_story_points',
|
|
170
181
|
'write_available_teams', 'write_backlog_ops_config',
|
|
171
182
|
'write_backlog_releases', 'write_content_changes', 'write_date_changes',
|
|
172
183
|
'write_key_list']
|
|
@@ -117,16 +117,20 @@ class _BridgeConfig(Config):
|
|
|
117
117
|
return {}
|
|
118
118
|
|
|
119
119
|
def __init__(self, from_json_data_text: Optional[str],
|
|
120
|
-
from_json_filename: Optional[PathOrStr],
|
|
121
|
-
|
|
120
|
+
from_json_filename: Optional[PathOrStr], stderr_file: TextIO,
|
|
121
|
+
*, member_name: Optional[str] = None) -> None:
|
|
122
122
|
"""Run the Config lifecycle for a bridge instance.
|
|
123
123
|
|
|
124
124
|
Each bridge first creates its data class attributes, then calls
|
|
125
125
|
this constructor to read JSON, apply defaults, and validate.
|
|
126
|
+
``member_name`` is the path for reaching this object from the top
|
|
127
|
+
level configuration, so that a diagnostic about a value inside it
|
|
128
|
+
names the whole path; it is None for a bridge that is a whole
|
|
129
|
+
configuration file of its own.
|
|
126
130
|
"""
|
|
127
131
|
Config.__init__(self, from_json_data_text=from_json_data_text,
|
|
128
132
|
from_json_filename=from_json_filename,
|
|
129
|
-
stderr_file=stderr_file)
|
|
133
|
+
stderr_file=stderr_file, member_name=member_name)
|
|
130
134
|
|
|
131
135
|
@staticmethod
|
|
132
136
|
def _consistency() -> WholeConfigValidationStep:
|
|
@@ -154,12 +158,13 @@ class FteExceptionConfig(FteException, _BridgeConfig):
|
|
|
154
158
|
|
|
155
159
|
def __init__(self, from_json_data_text: Optional[str] = None,
|
|
156
160
|
from_json_filename: Optional[PathOrStr] = None,
|
|
157
|
-
stderr_file: TextIO = sys.stderr
|
|
161
|
+
stderr_file: TextIO = sys.stderr, *,
|
|
162
|
+
member_name: Optional[str] = None) -> None:
|
|
158
163
|
"""Create placeholder defaults, then read one FTE exception."""
|
|
159
164
|
FteException.__init__(self, start_date=date(2000, 1, 1),
|
|
160
165
|
end_date=date(2000, 1, 1), fte=1.0)
|
|
161
166
|
_BridgeConfig.__init__(self, from_json_data_text, from_json_filename,
|
|
162
|
-
stderr_file)
|
|
167
|
+
stderr_file, member_name=member_name)
|
|
163
168
|
|
|
164
169
|
@override
|
|
165
170
|
def get_validation_plan(self, stderr_file: TextIO) -> ValidationPlan:
|
|
@@ -179,13 +184,14 @@ class ExceptionWorkHoursConfig(ExceptionWorkHours, _BridgeConfig):
|
|
|
179
184
|
|
|
180
185
|
def __init__(self, from_json_data_text: Optional[str] = None,
|
|
181
186
|
from_json_filename: Optional[PathOrStr] = None,
|
|
182
|
-
stderr_file: TextIO = sys.stderr
|
|
187
|
+
stderr_file: TextIO = sys.stderr, *,
|
|
188
|
+
member_name: Optional[str] = None) -> None:
|
|
183
189
|
"""Create placeholder defaults, then read one work-hours exception."""
|
|
184
190
|
ExceptionWorkHours.__init__(self, start_date=date(2000, 1, 1),
|
|
185
191
|
end_date=date(2000, 1, 1),
|
|
186
192
|
hours_per_day=0.0)
|
|
187
193
|
_BridgeConfig.__init__(self, from_json_data_text, from_json_filename,
|
|
188
|
-
stderr_file)
|
|
194
|
+
stderr_file, member_name=member_name)
|
|
189
195
|
|
|
190
196
|
@override
|
|
191
197
|
def get_validation_plan(self, stderr_file: TextIO) -> ValidationPlan:
|
|
@@ -205,11 +211,12 @@ class MembershipConfig(Membership, _BridgeConfig):
|
|
|
205
211
|
|
|
206
212
|
def __init__(self, from_json_data_text: Optional[str] = None,
|
|
207
213
|
from_json_filename: Optional[PathOrStr] = None,
|
|
208
|
-
stderr_file: TextIO = sys.stderr
|
|
214
|
+
stderr_file: TextIO = sys.stderr, *,
|
|
215
|
+
member_name: Optional[str] = None) -> None:
|
|
209
216
|
"""Create placeholder defaults, then read one membership."""
|
|
210
217
|
Membership.__init__(self, person_name='person')
|
|
211
218
|
_BridgeConfig.__init__(self, from_json_data_text, from_json_filename,
|
|
212
|
-
stderr_file)
|
|
219
|
+
stderr_file, member_name=member_name)
|
|
213
220
|
|
|
214
221
|
@override
|
|
215
222
|
def nested_configs(self) -> NestedConfigs:
|
|
@@ -241,12 +248,13 @@ class TeamConfig(Team, _BridgeConfig):
|
|
|
241
248
|
|
|
242
249
|
def __init__(self, from_json_data_text: Optional[str] = None,
|
|
243
250
|
from_json_filename: Optional[PathOrStr] = None,
|
|
244
|
-
stderr_file: TextIO = sys.stderr
|
|
251
|
+
stderr_file: TextIO = sys.stderr, *,
|
|
252
|
+
member_name: Optional[str] = None) -> None:
|
|
245
253
|
"""Create placeholder defaults, then read one team."""
|
|
246
254
|
Team.__init__(self, name='team', velocity=0.0, sum_fte_at_velocity=1.0,
|
|
247
255
|
sprint_length=1)
|
|
248
256
|
_BridgeConfig.__init__(self, from_json_data_text, from_json_filename,
|
|
249
|
-
stderr_file)
|
|
257
|
+
stderr_file, member_name=member_name)
|
|
250
258
|
|
|
251
259
|
@override
|
|
252
260
|
def nested_configs(self) -> NestedConfigs:
|
|
@@ -266,11 +274,12 @@ class PersonConfig(Person, _BridgeConfig):
|
|
|
266
274
|
|
|
267
275
|
def __init__(self, from_json_data_text: Optional[str] = None,
|
|
268
276
|
from_json_filename: Optional[PathOrStr] = None,
|
|
269
|
-
stderr_file: TextIO = sys.stderr
|
|
277
|
+
stderr_file: TextIO = sys.stderr, *,
|
|
278
|
+
member_name: Optional[str] = None) -> None:
|
|
270
279
|
"""Create placeholder defaults, then read one person."""
|
|
271
280
|
Person.__init__(self, name='person')
|
|
272
281
|
_BridgeConfig.__init__(self, from_json_data_text, from_json_filename,
|
|
273
|
-
stderr_file)
|
|
282
|
+
stderr_file, member_name=member_name)
|
|
274
283
|
|
|
275
284
|
@override
|
|
276
285
|
def nested_configs(self) -> NestedConfigs:
|
|
@@ -291,12 +300,13 @@ class CompanyWorkHoursConfig(CompanyWorkHours, _BridgeConfig):
|
|
|
291
300
|
|
|
292
301
|
def __init__(self, from_json_data_text: Optional[str] = None,
|
|
293
302
|
from_json_filename: Optional[PathOrStr] = None,
|
|
294
|
-
stderr_file: TextIO = sys.stderr
|
|
303
|
+
stderr_file: TextIO = sys.stderr, *,
|
|
304
|
+
member_name: Optional[str] = None) -> None:
|
|
295
305
|
"""Create defaults, then read the company work hours."""
|
|
296
306
|
CompanyWorkHours.__init__(self)
|
|
297
307
|
self._unchecked_dicts = ['work_hours']
|
|
298
308
|
_BridgeConfig.__init__(self, from_json_data_text, from_json_filename,
|
|
299
|
-
stderr_file)
|
|
309
|
+
stderr_file, member_name=member_name)
|
|
300
310
|
|
|
301
311
|
@override
|
|
302
312
|
def nested_configs(self) -> NestedConfigs:
|
|
@@ -328,7 +338,8 @@ class AvailableTeamsConfig(AvailableTeams, _BridgeConfig):
|
|
|
328
338
|
def __init__(self, *, neutral: Optional[AvailableTeams] = None,
|
|
329
339
|
from_json_data_text: Optional[str] = None,
|
|
330
340
|
from_json_filename: Optional[PathOrStr] = None,
|
|
331
|
-
stderr_file: TextIO = sys.stderr
|
|
341
|
+
stderr_file: TextIO = sys.stderr,
|
|
342
|
+
member_name: Optional[str] = None) -> None:
|
|
332
343
|
"""Create the bridge from a neutral workforce or from JSON.
|
|
333
344
|
|
|
334
345
|
``AvailableTeams.__init__`` is intentionally not invoked because
|
|
@@ -340,7 +351,7 @@ class AvailableTeamsConfig(AvailableTeams, _BridgeConfig):
|
|
|
340
351
|
neutral = AvailableTeams(persons={}, teams=[])
|
|
341
352
|
Config.copy_initial_data(neutral, self)
|
|
342
353
|
_BridgeConfig.__init__(self, from_json_data_text, from_json_filename,
|
|
343
|
-
stderr_file)
|
|
354
|
+
stderr_file, member_name=member_name)
|
|
344
355
|
|
|
345
356
|
@override
|
|
346
357
|
def nested_configs(self) -> NestedConfigs:
|
|
@@ -61,7 +61,12 @@ class BacklogItem: # pylint: disable=too-many-instance-attributes
|
|
|
61
61
|
not contain any of the characters , . ; : ( ) [ ] { }.
|
|
62
62
|
level: The level of the backlog item. Required. Must be an integer.
|
|
63
63
|
title: The title of the backlog item. Required.
|
|
64
|
-
story_points: The story points of the backlog item
|
|
64
|
+
story_points: The story points of the backlog item, or None
|
|
65
|
+
when nobody has estimated it yet. May be a
|
|
66
|
+
fraction, such as 0.5. What the work on the
|
|
67
|
+
item is counted as, which is another matter,
|
|
68
|
+
is answered by
|
|
69
|
+
:func:`backlogops.use_story_points`.
|
|
65
70
|
status: The status of the backlog item.
|
|
66
71
|
parent_key: The key of the parent backlog item. Optional.
|
|
67
72
|
Must exist as a key in the backlog.
|
|
@@ -100,7 +105,7 @@ class BacklogItem: # pylint: disable=too-many-instance-attributes
|
|
|
100
105
|
key: str
|
|
101
106
|
level: int
|
|
102
107
|
title: str
|
|
103
|
-
story_points:
|
|
108
|
+
story_points: Optional[float]
|
|
104
109
|
status: Status
|
|
105
110
|
parent_key: Optional[str] = None
|
|
106
111
|
release: Optional[str] = None
|