Skip to content

Hybrid edit (FIELD_SPECS map + --set + --list-fields), link --list, and bjira show#17

Open
wiliam wants to merge 24 commits into
bokshitsky:masterfrom
wiliam:feature/edit-hybrid
Open

Hybrid edit (FIELD_SPECS map + --set + --list-fields), link --list, and bjira show#17
wiliam wants to merge 24 commits into
bokshitsky:masterfrom
wiliam:feature/edit-hybrid

Conversation

@wiliam

@wiliam wiliam commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

Builds on top of merged #16 (project-ops commands). The actual delta vs current master is 10 files, +609/-58 lines — listed below. The PR's commit list visually duplicates some of #16's commits because upstream rebase-merged that PR, giving the same patches different SHAs; only the content listed below is the new contribution.

What's new

1. Hybrid edit — map-driven fields + --set escape hatch

FIELD_SPECS in bjira/_fields.py maps each named flag to a Jira field id + payload transform. Adding a common field is one dict entry — no changes to edit.py. Currently shipped:

Flag Jira field
--summary / --description / --description-file system fields
--due (YYYY-MM-DD or none) duedate
--assignee (login or none) assignee
--priority (name) priority
--version (name or none) fixVersions
--team (value or none) customfield_34238 (Delivery Team)
--sp (float) customfield_11212 (Story Points)

--set KEY=VALUE covers anything not in the map, guarded by SET_DENY (status, resolution, issuetype, project, created, updated, creator, reporter, issuelinks, subtasks — with pointers to the right tool, e.g. "status/resolution → use 'bjira status'").

All previous behaviour preserved: --force gate on summary/description, --description-file, label merge/clear, no-op skip, exit codes (0/2/3).

2. bjira edit KEY --list-fields [--json]

Uses Jira's editmeta endpoint to show what's editable on the issue right now: field name, id, type, allowed operations, and allowed enum values (e.g. fixVersions → list of versions, priority → 5 levels, Delivery Team → 100+ teams). Truncates each enum to first 10 + total count; --json emits full JSON for piping.

3. bjira link --list

Enumerates all link types via jira.issue_link_types(). Useful because some Jira instances rename link types (e.g. on jira.hh.ru the standard "Relates" is named Relation).

4. bjira show KEY [--fields LIST] [--json]

Symmetric read counterpart to hybrid edit. Reads any subset of issue fields. Field labels accepted in any form:

  • field id (customfield_11210, summary)

  • human name in any language (Flagged, Дата блокировки) — resolved via /rest/api/2/field

  • fieldset alias from ~/.bjira_config:

    {
      \"fieldsets\": {
        \"default\": [\"summary\", \"status\", \"assignee\", \"labels\", \"duedate\"],
        \"blocker\": [\"Flagged\", \"is_blocked\", \"Дата блокировки\", \"Дата разблокировки\"]
      }
    }

Aliases compose: --fields blocker,timing,summary → expanded list, dedup, order preserved. If the config defines default, it's used when no --fields is passed.

Output: YAML-like text by default (label-aligned, multi-line values indented), or full JSON with --json.

Files changed

README.md                   |  27 +++
bjira/_fields.py            |  53 +++++  (FIELD_SPECS, SET_DENY, build_fields_payload, parse_set_arg)
bjira/_show.py              | 111 +++++  (parse_fields_request, resolve_field_id, format_field_value)
bjira/operations/__init__.py|   8 +++  (get_fieldsets helper)
bjira/operations/edit.py    | 160/-63   (rewrite to map-driven + --set + --list-fields)
bjira/operations/link.py    |  19 +++   (--list flag)
bjira/operations/show.py    | 141 +++++  (new command)
tests/smoke.py              |  12 +++   (live --list-fields, link --list checks)
tests/test_fields.py        |  63 +++++  (FIELD_SPECS / build_fields_payload / parse_set_arg / SET_DENY)
tests/test_show.py          |  73 +++++  (parse_fields_request / resolve_field_id / format_field_value)
                            -----------
                              +609 / -58 lines, 10 files

Test plan

  • pytest tests/ --ignore=tests/smoke.py58 unit tests pass on Python 3.14 (+21 new this PR: 8 for FIELD_SPECS-layer, 13 for show-layer)
  • python tests/smoke.py — all sections pass on jira.hh.ru, including --list-fields and link --list
  • Real edit: bjira edit PORTFOLIO-XXX --version 2026Q2 --team Конверсы applied cleanly
  • Real show with mixed labels: bjira show PORTFOLIO-XXX --fields \"summary,Flagged,Дата блокировки,customfield_11210\" resolves all four (id, English name, Russian name, id again)
  • Deny gate: bjira edit ... --set status=Done → exit 2 with actionable message
  • No-op detection: bjira edit KEY --summary <same> → "no changes", exit 0, no API write
  • Regression: existing edit gate (--force on non-empty summary/description), --description-file, labels merge/clear — all unchanged

Backwards compatibility

All commands from #16 untouched. bjira/operations/edit.py was rewritten in place but every prior CLI invocation produces the same payload and exit code; the rewrite is internal (loop over map instead of hand-coded per-field branches).

@wiliam wiliam changed the title Hybrid edit (field map + --set) and --list helpers Project-ops commands: edit (hybrid map+--set), show, comment, status, link, +helpers Apr 27, 2026
@wiliam wiliam changed the title Project-ops commands: edit (hybrid map+--set), show, comment, status, link, +helpers Hybrid edit (FIELD_SPECS map + --set + --list-fields), link --list, and bjira show Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant