httpie / cli

🥧 HTTPie CLI — modern, user-friendly command-line HTTP client for the API era. JSON support, colors, sessions, downloads, plugins & more.
https://httpie.io
BSD 3-Clause "New" or "Revised" License
33.56k stars 3.67k forks source link

Inconsistent BUILD_CHANNEL value #1404

Open hroncok opened 2 years ago

hroncok commented 2 years ago

Checklist


Hey, sorry for deleting your template, but this is a request from your Fedora packager and not from a user.

I've figured out that httpie 3.2.0+ now includes an update notification https://httpie.io/blog/httpie-3.2.0#update-warnings

It points the users to https://httpie.io/docs/cli/pypi -- so I though, well, maybe I can point them to https://httpie.io/docs/cli/fedora instead? Maybe there could be a file marker that contains the last bit of this URl and I could just echo fedora > httpie/internal/update_method.marker right?

So I looked and apparently, this is all being handled already, wow :tada:

https://github.com/httpie/httpie/blob/d9e1dc08c9b4eb0d6021360118daca87fa248400/httpie/internal/update_warnings.py#L23

Where is this installation_method coming from, I asked? It is coming from

https://github.com/httpie/httpie/blob/d9e1dc08c9b4eb0d6021360118daca87fa248400/httpie/internal/__build_channel__.py#L1-L5

This is so awesome, let me just replace that unknown with fedora, and everything will work! Thanks

I however see that this BUILD_CHANNEL thing is also used to search keys in https://packages.httpie.io/latest.json but that includes fedora_rawhide. Now I have a problem:

What do I do with this? How can I help you populate the data for fedora-XY and make all fedora-XY links point to the Fedora build instructions? (XY is the Fedora version.)

Thanks.

isidentical commented 2 years ago

Thanks a lot for deep diving into the use case!

@hroncok In the generic sense, I think we need to separate the installation_method from BUILD_CHANNEL for fedora. What I mean by that is, all of the possible combinations should work:

# __build_channel__.py, build channel = installation method.
BUILD_CHANNEL = "brew"
# __build_channel__.py, build channel is fedora's rawhide (might include a newer version of HTTPie) but the installation method should point to the docs version.
BUILD_CHANNEL = "fedora_rawhide"
INSTALLATION_METHOD = "fedora"
# __build_channel__.py, build channel is fedora 34's package repository and the installation method is still pointing to the fedora's docs.
BUILD_CHANNEL = "fedora_34"
INSTALLATION_METHOD = "fedora"

If we handle that, we can add more channels to the https://packages.httpie.io/latest.json (which is a very simple mirror from repology).

hroncok commented 2 years ago

To construct the data, I'd use something like:

import requests

httpie_versions = {}

# Start with the last known non-EOLed Fedora version
# It doesn't really matter if this gates slightly out of date
release = 34

while True:
    key = f'fedora-{release}'
    response = requests.get(f'https://mdapi.fedoraproject.org/f{release}/pkg/httpie')
    if response.ok:
        httpie_versions[key] = response.json()['version']
    else:
        response = requests.get('https://mdapi.fedoraproject.org/rawhide/pkg/httpie')
        httpie_versions[key] = response.json()['version']
        break
    release += 1

import pprint
pprint.pprint(httpie_versions)

Or alternatively, get the data from repology, but it seems to include multiple versions, so we would need to find the latest.

isidentical commented 2 years ago

This is the part where we collect data from multiple providers (GH API, Repology), we can extend it with your script as well if need to be.

hroncok commented 2 years ago

This is the part where we collect data from multiple providers (GH API, Repology), we can extend it with your script as well if need to be.

This is a proof of concept of what I'd need:

FEDORA_OLDEST = 34
fedora_newest = 0

def is_active_fedora(repo):
    global fedora_newest

    with suppress(ValueError):
        name, version = repo.split('_')
        if name == 'fedora':
            version = int(version)
            fedora_newest = max(version, fedora_newest)
            return version >= FEDORA_OLDEST
    return False

def fetch_repology() -> Tuple[str, str]:
    response = requests.get(REPOLOGY_API_BASE + f'/project/{PROJECT_NAME}')
    response.raise_for_status()

    for channel_info in response.json():
        if channel_info['repo'] in REPOLOGY_CHANNELS or is_active_fedora(channel_info['repo']):
            yield (channel_info['repo'], channel_info['version'])
    for channel_info in response.json():
        if channel_info['repo'] == 'fedora_rawhide':
            yield (f'fedora_{fedora_newest+1}', channel_info['version'])