Skip to content

feat(list-versions): show cooldown status and upload timestamps#1127

Open
shifa-khan wants to merge 1 commit into
python-wheel-build:mainfrom
shifa-khan:list-versions-1078
Open

feat(list-versions): show cooldown status and upload timestamps#1127
shifa-khan wants to merge 1 commit into
python-wheel-build:mainfrom
shifa-khan:list-versions-1078

Conversation

@shifa-khan
Copy link
Copy Markdown
Contributor

@shifa-khan shifa-khan commented May 7, 2026

package list-versions now shows upload_time, age in days, and cooldown status for each version.

--format controls the output: versions (default) and requirements print a filtered list excluding blocked entries; table, csv, and json include the full detail columns. This replaces the previous --format-as-requirements flag.

--ignore-per-package-overrides shows what the global --min-release-age would block without per-package exemptions.

Closes: #1078

@shifa-khan shifa-khan requested a review from a team as a code owner May 7, 2026 17:52
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 7, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR implements the cooldown details phase of the release-age cooldown feature (#1078). The package list-versions command gains a --details flag that outputs per-version metadata: upload timestamp, computed age in days, and cooldown status (blocked/allowed/skipped/blank). When --details is enabled, output formats as table, CSV, or JSON via --format/--output; plain mode preserves backward compatibility, listing only versions as before. A new --ignore-per-package-overrides flag lets operators check what global cooldown rules would enforce without per-package exemptions. Internally, versions are deduplicated and sorted, then routed through helpers that resolve effective cooldown policy, compute per-version metadata by grouping candidates, and classify each version based on cooldown settings and upload availability. Exporters render JSON, CSV, or Rich tables with an optional Cooldown column. Tests cover plain mode, formats, file output, override bypass behavior, CLI warnings, and unit tests for the cooldown classifier.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title concisely describes the primary change: adding cooldown status and upload timestamp display to list-versions command.
Linked Issues check ✅ Passed The PR implementation fully satisfies issue #1078 requirements: displays upload_time and age_days, marks cooldown status (blocked/allowed/skipped), and implements --ignore-per-package-overrides flag with per-package override configuration.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #1078 objectives: cooldown display enhancements, filtering, and export options. The deprecated list-versions shim is intentionally left unmodified as documented.
Description check ✅ Passed The PR description clearly relates to the changeset: it describes the new --details flag, --format options, and --ignore-per-package-overrides functionality for the package list-versions command, all of which are implemented in the provided changes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mergify mergify Bot added the ci label May 7, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/fromager/commands/package.py (1)

196-245: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Add per-requirement logging context in list_versions

list_versions logs requirement-specific messages but does not use log.req_ctxvar_context(req), so contextual logging is inconsistent with other command paths.

Suggested fix
-    logger.info(f"Looking up versions for {req.name}")
-    if req.specifier:
-        logger.info(f"Filtering versions with specifier: {req.specifier}")
+    with log.req_ctxvar_context(req):
+        logger.info(f"Looking up versions for {req.name}")
+        if req.specifier:
+            logger.info(f"Filtering versions with specifier: {req.specifier}")
 
-    pbi = wkctx.package_build_info(req)
-    override_sdist_server_url = pbi.resolver_sdist_server_url(sdist_server_url)
+        pbi = wkctx.package_build_info(req)
+        override_sdist_server_url = pbi.resolver_sdist_server_url(sdist_server_url)
 
-    include_sdists, include_wheels = parse_distribution_option(
-        distribution_type,
-        pbi,
-    )
+        include_sdists, include_wheels = parse_distribution_option(
+            distribution_type,
+            pbi,
+        )
 
-    provider = overrides.find_and_invoke(
+        provider = overrides.find_and_invoke(
         ...
-    )
+        )
+        ...

As per coding guidelines: src/fromager/**/*.py: “Use req_ctxvar_context() for per-requirement logging”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/fromager/commands/package.py` around lines 196 - 245, The
requirement-specific logs in this block should be executed inside the
per-requirement logging context; wrap the code that starts after
Requirement(requirement_spec) (the logger.info calls, pbi =
wkctx.package_build_info(req), parse_distribution_option,
overrides.find_and_invoke(...), provider.find_matches(...) and the
candidates/versions handling) in the context manager returned by
log.req_ctxvar_context(req) so that all requirement-scoped log messages use the
req context; locate the code around Requirement(...) and wrap the subsequent
logic (up through computing versions) with with log.req_ctxvar_context(req): to
ensure consistent contextual logging.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/fromager/commands/package.py`:
- Around line 263-270: The table branch ignores the requested output
destination: in the match on output_format you call
_export_versions_table(version_rows, req.name, cooldown) which always prints to
stdout, so update the call and the function to accept an output file/stream
(e.g. add an output parameter) and forward the provided output handle used by
the json/csv branches; modify _export_versions_table signature and all call
sites (including the other occurrence around lines 402-422) to accept and write
to the passed output instead of writing directly to stdout.

---

Outside diff comments:
In `@src/fromager/commands/package.py`:
- Around line 196-245: The requirement-specific logs in this block should be
executed inside the per-requirement logging context; wrap the code that starts
after Requirement(requirement_spec) (the logger.info calls, pbi =
wkctx.package_build_info(req), parse_distribution_option,
overrides.find_and_invoke(...), provider.find_matches(...) and the
candidates/versions handling) in the context manager returned by
log.req_ctxvar_context(req) so that all requirement-scoped log messages use the
req context; locate the code around Requirement(...) and wrap the subsequent
logic (up through computing versions) with with log.req_ctxvar_context(req): to
ensure consistent contextual logging.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 028ca9d6-ba8a-480e-8b7a-b9666d871f34

📥 Commits

Reviewing files that changed from the base of the PR and between 5fd5d20 and 88f414f.

📒 Files selected for processing (2)
  • src/fromager/commands/package.py
  • tests/test_list_versions.py

Comment thread src/fromager/commands/package.py
@shifa-khan
Copy link
Copy Markdown
Contributor Author

Tested the changes locally:

$ fromager --min-release-age 20 package list-versions --details --format json click
13:52:27 INFO Looking up versions for click
13:52:27 INFO Found 57 version(s)
    },
    {
        "package": "click",
        "version": "8.3.0",
        "upload_time": "2025-09-18T17:32:23.696258+00:00",
        "age_days": "231",
        "cooldown": "allowed"
    },
    {
        "package": "click",
        "version": "8.3.1",
        "upload_time": "2025-11-15T20:45:42.706404+00:00",
        "age_days": "172",
        "cooldown": "allowed"
    },
    {
        "package": "click",
        "version": "8.3.2",
        "upload_time": "2026-04-03T19:14:45.118083+00:00",
        "age_days": "33",
        "cooldown": "allowed"
    },
    {
        "package": "click",
        "version": "8.3.3",
        "upload_time": "2026-04-22T15:11:27.506141+00:00",
        "age_days": "15",
        "cooldown": "blocked"
    }
]

With a 20-day cooldown, click 8.3.3 (15 days old) is correctly marked as blocked while 8.3.2 (33 days old) is allowed.

Comment thread src/fromager/commands/package.py Outdated
@shifa-khan shifa-khan force-pushed the list-versions-1078 branch 5 times, most recently from ba62e44 to 22685c7 Compare May 8, 2026 16:53
Comment thread src/fromager/commands/package.py Outdated
@shifa-khan shifa-khan force-pushed the list-versions-1078 branch 2 times, most recently from 39e1053 to 650cd2b Compare May 8, 2026 18:24
@dhellmann
Copy link
Copy Markdown
Member

We need to add some e2e tests, it looks like. The version-only listing works properly, but the table formatter does not filter by age.

$ .tox/cli/bin/fromager --min-release-age 800 package list-versions torch
18:12:55 INFO loading settings from /home/dhellmann/devel/aipcc/builder/overrides/settings.yaml
18:12:55 INFO Looking up versions for torch
18:12:55 INFO Found 17 version(s)
2.2.0
2.2.1

$ .tox/cli/bin/fromager --min-release-age 800 package list-versions --format table torch
18:13:07 INFO loading settings from /home/dhellmann/devel/aipcc/builder/overrides/settings.yaml
18:13:07 INFO Looking up versions for torch
18:13:07 INFO Found 17 version(s)
                          Versions for torch
┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Version ┃ Upload Time                      ┃ Age (days) ┃ Cooldown ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━┩
│ 2.2.0   │ 2024-01-30T17:31:54.836329+00:00 │        829 │ allowed  │
│ 2.2.1   │ 2024-02-22T19:17:39.398581+00:00 │        806 │ allowed  │
│ 2.2.2   │ 2024-03-27T21:09:07.247742+00:00 │        772 │ blocked  │
│ 2.3.0   │ 2024-04-24T15:47:07.772402+00:00 │        744 │ blocked  │
│ 2.3.1   │ 2024-06-05T16:42:05.146656+00:00 │        702 │ blocked  │
│ 2.4.0   │ 2024-07-24T15:29:48.218784+00:00 │        653 │ blocked  │
│ 2.4.1   │ 2024-09-04T19:13:19.273720+00:00 │        611 │ blocked  │
│ 2.5.0   │ 2024-10-17T14:47:22.380657+00:00 │        568 │ blocked  │
│ 2.5.1   │ 2024-10-29T17:32:42.789246+00:00 │        556 │ blocked  │
│ 2.6.0   │ 2025-01-29T16:25:55.649425+00:00 │        464 │ blocked  │
│ 2.7.0   │ 2025-04-23T14:35:15.589323+00:00 │        380 │ blocked  │
│ 2.7.1   │ 2025-06-04T17:39:12.852763+00:00 │        338 │ blocked  │
│ 2.8.0   │ 2025-08-06T14:53:52.631799+00:00 │        275 │ blocked  │
│ 2.9.0   │ 2025-10-15T15:46:20.883880+00:00 │        205 │ blocked  │
│ 2.9.1   │ 2025-11-12T15:20:41.620358+00:00 │        177 │ blocked  │
│ 2.10.0  │ 2026-01-21T16:24:44.171477+00:00 │        107 │ blocked  │
│ 2.11.0  │ 2026-03-23T18:11:06.944421+00:00 │         46 │ blocked  │
└─────────┴──────────────────────────────────┴────────────┴──────────┘

@tiran
Copy link
Copy Markdown
Collaborator

tiran commented May 10, 2026

  • Can you please get rid microseconds and TZ offset? They are noise.
  • The words allowed and blocked are hard to distinguish. They have the same character count, same ed suffix, and look kinda similar. How about different words or no entry when a package is not blocked by cooldown?
  • does the table show yanked release?

Comment thread src/fromager/commands/package.py Outdated
) -> None:
"""Export version details as CSV."""
if output:
with open(output, "w", newline="") as outfile:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This duplicates the full DictWriter block across if - else branches.

If we determine the output stream earlier we can avoid the duplication.

outfile = open(output, "w") if output else sys.stdout
try:
    writer = csv.DictWriter(.....)
    writer.writeheader()
    writer.writerows(data)
finally:
    if output:
        outfile.close()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or simpler: use click.File in the argument and pass io.TextIO type around.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smoparth @tiran The initial version matches the pattern in list_overrides._export_csv to stay consistent. If both commands need further cleanup (e.g., click.File or try/finally), I can address that in a follow-up PR. Note that click.File has drawbacks, such as not supporting the newline="" requirement for CSV files.

@shifa-khan
Copy link
Copy Markdown
Contributor Author

We need to add some e2e tests, it looks like. The version-only listing works properly, but the table formatter does not filter by age.

$ .tox/cli/bin/fromager --min-release-age 800 package list-versions torch
18:12:55 INFO loading settings from /home/dhellmann/devel/aipcc/builder/overrides/settings.yaml
18:12:55 INFO Looking up versions for torch
18:12:55 INFO Found 17 version(s)
2.2.0
2.2.1

$ .tox/cli/bin/fromager --min-release-age 800 package list-versions --format table torch
18:13:07 INFO loading settings from /home/dhellmann/devel/aipcc/builder/overrides/settings.yaml
18:13:07 INFO Looking up versions for torch
18:13:07 INFO Found 17 version(s)
                          Versions for torch
┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Version ┃ Upload Time                      ┃ Age (days) ┃ Cooldown ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━┩
│ 2.2.0   │ 2024-01-30T17:31:54.836329+00:00 │        829 │ allowed  │
│ 2.2.1   │ 2024-02-22T19:17:39.398581+00:00 │        806 │ allowed  │
│ 2.2.2   │ 2024-03-27T21:09:07.247742+00:00 │        772 │ blocked  │
│ 2.3.0   │ 2024-04-24T15:47:07.772402+00:00 │        744 │ blocked  │
│ 2.3.1   │ 2024-06-05T16:42:05.146656+00:00 │        702 │ blocked  │
│ 2.4.0   │ 2024-07-24T15:29:48.218784+00:00 │        653 │ blocked  │
│ 2.4.1   │ 2024-09-04T19:13:19.273720+00:00 │        611 │ blocked  │
│ 2.5.0   │ 2024-10-17T14:47:22.380657+00:00 │        568 │ blocked  │
│ 2.5.1   │ 2024-10-29T17:32:42.789246+00:00 │        556 │ blocked  │
│ 2.6.0   │ 2025-01-29T16:25:55.649425+00:00 │        464 │ blocked  │
│ 2.7.0   │ 2025-04-23T14:35:15.589323+00:00 │        380 │ blocked  │
│ 2.7.1   │ 2025-06-04T17:39:12.852763+00:00 │        338 │ blocked  │
│ 2.8.0   │ 2025-08-06T14:53:52.631799+00:00 │        275 │ blocked  │
│ 2.9.0   │ 2025-10-15T15:46:20.883880+00:00 │        205 │ blocked  │
│ 2.9.1   │ 2025-11-12T15:20:41.620358+00:00 │        177 │ blocked  │
│ 2.10.0  │ 2026-01-21T16:24:44.171477+00:00 │        107 │ blocked  │
│ 2.11.0  │ 2026-03-23T18:11:06.944421+00:00 │         46 │ blocked  │
└─────────┴──────────────────────────────────┴────────────┴──────────┘

@dhellmann Thanks for pointing that out. Question on scope - the issue says "list-versions should display upload timestamps and indicate which candidates are blocked by the cooldown policy." Should the detail formats (table/csv/json) still show blocked versions with a "blocked" label so the command can serve as a diagnostic tool? With a short cooldown like 3-7 days there could be versions available on PyPI but blocked by the policy, and it'd be useful to see those rather than have them silently filtered.

@dhellmann
Copy link
Copy Markdown
Member

We need to add some e2e tests, it looks like. The version-only listing works properly, but the table formatter does not filter by age.

$ .tox/cli/bin/fromager --min-release-age 800 package list-versions torch
18:12:55 INFO loading settings from /home/dhellmann/devel/aipcc/builder/overrides/settings.yaml
18:12:55 INFO Looking up versions for torch
18:12:55 INFO Found 17 version(s)
2.2.0
2.2.1

$ .tox/cli/bin/fromager --min-release-age 800 package list-versions --format table torch
18:13:07 INFO loading settings from /home/dhellmann/devel/aipcc/builder/overrides/settings.yaml
18:13:07 INFO Looking up versions for torch
18:13:07 INFO Found 17 version(s)
                          Versions for torch
┏━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Version ┃ Upload Time                      ┃ Age (days) ┃ Cooldown ┃
┡━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━┩
│ 2.2.0   │ 2024-01-30T17:31:54.836329+00:00 │        829 │ allowed  │
│ 2.2.1   │ 2024-02-22T19:17:39.398581+00:00 │        806 │ allowed  │
│ 2.2.2   │ 2024-03-27T21:09:07.247742+00:00 │        772 │ blocked  │
│ 2.3.0   │ 2024-04-24T15:47:07.772402+00:00 │        744 │ blocked  │
│ 2.3.1   │ 2024-06-05T16:42:05.146656+00:00 │        702 │ blocked  │
│ 2.4.0   │ 2024-07-24T15:29:48.218784+00:00 │        653 │ blocked  │
│ 2.4.1   │ 2024-09-04T19:13:19.273720+00:00 │        611 │ blocked  │
│ 2.5.0   │ 2024-10-17T14:47:22.380657+00:00 │        568 │ blocked  │
│ 2.5.1   │ 2024-10-29T17:32:42.789246+00:00 │        556 │ blocked  │
│ 2.6.0   │ 2025-01-29T16:25:55.649425+00:00 │        464 │ blocked  │
│ 2.7.0   │ 2025-04-23T14:35:15.589323+00:00 │        380 │ blocked  │
│ 2.7.1   │ 2025-06-04T17:39:12.852763+00:00 │        338 │ blocked  │
│ 2.8.0   │ 2025-08-06T14:53:52.631799+00:00 │        275 │ blocked  │
│ 2.9.0   │ 2025-10-15T15:46:20.883880+00:00 │        205 │ blocked  │
│ 2.9.1   │ 2025-11-12T15:20:41.620358+00:00 │        177 │ blocked  │
│ 2.10.0  │ 2026-01-21T16:24:44.171477+00:00 │        107 │ blocked  │
│ 2.11.0  │ 2026-03-23T18:11:06.944421+00:00 │         46 │ blocked  │
└─────────┴──────────────────────────────────┴────────────┴──────────┘

@dhellmann Thanks for pointing that out. Question on scope - the issue says "list-versions should display upload timestamps and indicate which candidates are blocked by the cooldown policy." Should the detail formats (table/csv/json) still show blocked versions with a "blocked" label so the command can serve as a diagnostic tool? With a short cooldown like 3-7 days there could be versions available on PyPI but blocked by the policy, and it'd be useful to see those rather than have them silently filtered.

Ah, that's a great point. I was focused on making it work the same as the default view, but you're right, it shows that the package would not be included so that's actually a better UX. Ignore my comment.

@shifa-khan
Copy link
Copy Markdown
Contributor Author

  • Can you please get rid microseconds and TZ offset? They are noise.
  • The words allowed and blocked are hard to distinguish. They have the same character count, same ed suffix, and look kinda similar. How about different words or no entry when a package is not blocked by cooldown?
  • does the table show yanked release?

@tiran
Agreed on trimming microseconds and TZ offset — will clean that up.

How about "blocked" for blocked entries and "available" for allowed? Leaving the column blank could confuse users.

Yanked versions are already filtered out by the resolver. I verified this with the click package — version 8.2.2 is yanked on PyPI and doesn't appear in the output.

@shifa-khan
Copy link
Copy Markdown
Contributor Author

shifa-khan commented May 11, 2026

@dhellmann
So to confirm the current behavior, the plain format (fromager --min-release-age 77 package list-versions click) filters out blocked versions, while detail formats (--format table/csv/json) show all versions with a "blocked"/"available" label. Also, the default resolver searches for sdists only, meaning the results from the list-versions command depend on whether sdists are available on PyPI?

@dhellmann
Copy link
Copy Markdown
Member

@dhellmann So to confirm the current behavior, the plain format (fromager --min-release-age 77 package list-versions click) filters out blocked versions, while detail formats (--format table/csv/json) show all versions with a "blocked"/"available" label.

Yes, I think the plain version list and the requirements.txt formatter should filter and the others that provide more details should not filter.

Also, the default resolver searches for sdists only, meaning the results from the list-versions command depend on whether sdists are available on PyPI?

There's an option to look for both types: https://github.com/python-wheel-build/fromager/blob/main/src/fromager/commands/package.py#L37

And the command uses the plugin to get a resolver, if there is a custom one: https://github.com/python-wheel-build/fromager/blob/main/src/fromager/commands/package.py#L146

So I think it's possible to do the full range of querying we expect?

@shifa-khan
Copy link
Copy Markdown
Contributor Author

@dhellmann So to confirm the current behavior, the plain format (fromager --min-release-age 77 package list-versions click) filters out blocked versions, while detail formats (--format table/csv/json) show all versions with a "blocked"/"available" label.

Yes, I think the plain version list and the requirements.txt formatter should filter and the others that provide more details should not filter.

Also, the default resolver searches for sdists only, meaning the results from the list-versions command depend on whether sdists are available on PyPI?

There's an option to look for both types: https://github.com/python-wheel-build/fromager/blob/main/src/fromager/commands/package.py#L37

And the command uses the plugin to get a resolver, if there is a custom one: https://github.com/python-wheel-build/fromager/blob/main/src/fromager/commands/package.py#L146

So I think it's possible to do the full range of querying we expect?

Right, that's what I figured. list-versions already has --distribution-type and goes through get_resolver_provider, so the full querying range is covered. I ran into this with torch (which only publishes wheels) and --distribution-type wheel handled it as expected.

@shifa-khan shifa-khan force-pushed the list-versions-1078 branch 2 times, most recently from 3c8cd81 to bf88758 Compare May 11, 2026 20:30
Comment thread src/fromager/commands/package.py
package list-versions now shows upload_time, age in days, and cooldown status for each version.

--format controls the output: versions (default) and requirements print a filtered list excluding blocked entries; table, csv, and json include the full detail columns. This replaces the previous --format-as-requirements flag.

--ignore-per-package-overrides shows what the global --min-release-age would block without per-package exemptions.

Co-authored-by: Cursor <cursoragent@cursor.com>
@shifa-khan shifa-khan force-pushed the list-versions-1078 branch from bf88758 to cb41274 Compare May 14, 2026 19:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

list-versions: show cooldown status and upload timestamps

4 participants