Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/cfengine_cli/docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
from cfengine_cli.lint import lint_policy_file
from cfengine_cli.utils import UserError


IGNORED_DIRS = [".git"]


Expand Down
33 changes: 33 additions & 0 deletions src/cfengine_cli/masterfiles/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,36 @@ def finalize_vcf(versions_dict, checksums_dict, files_dict):
)

return versions_dict, checksums_dict, files_dict


def filter_unstable_releases(data):
Copy link
Contributor

Choose a reason for hiding this comment

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

The function name says "filter unstable" but it's actually returning stable releases. Worth considering a name like get_stable_releases or filter_out_unstable_releases for clarity.

# Filter the data to only include stable releases (not debug, alpha, or beta releases):
filtered_data = []

for release_data in data.get("releases", []):
if release_data.get("debug") is True:
continue
if release_data.get("alpha") is True:
continue
if release_data.get("beta") is True:
continue

filtered_data.append(release_data)

return filtered_data
Comment on lines +97 to +110
Copy link
Contributor

Choose a reason for hiding this comment

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

The logic is correct but the three if/continue blocks are redundant. They can be collapsed into a single condition. You could also consider using list comprehension which is an idiomatic pattern in Python.

    return [
        r for r in data.get("releases", [])
        if not (r.get("debug") or r.get("alpha") or r.get("beta"))
    ]



def sort_release_data(file_checksums_dict):
# Newest versions first, and files sorted alphabetically within each version
for v in file_checksums_dict.keys():
file_checksums_dict[v] = dict_sorted_by_key(file_checksums_dict[v])
Copy link
Contributor

Choose a reason for hiding this comment

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

This function mutates its input (file_checksums_dict[v] = ...) before building the sorted copy below. The caller may not expect their dict to be modified as a side effect of this function. Consider creating the copy first.


sorted_dict = OrderedDict(
sorted(
file_checksums_dict.items(),
key=lambda p: version_as_comparable_list(p[0]),
reverse=True,
)
)

return sorted_dict
99 changes: 97 additions & 2 deletions src/cfengine_cli/masterfiles/generate_release_information.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
from cfengine_cli.masterfiles.download import download_all_versions
from cfengine_cli.masterfiles.download import (
ENTERPRISE_RELEASES_URL,
download_all_versions,
)
from cfengine_cli.masterfiles.generate_vcf_download import generate_vcf_download
from cfengine_cli.masterfiles.analyze import filter_unstable_releases, sort_release_data
from cfengine_cli.masterfiles.generate_vcf_git_checkout import generate_vcf_git_checkout
from cfengine_cli.masterfiles.check_download_matches_git import (
check_download_matches_git,
)
from cfbs.utils import immediate_subdirectories, version_is_at_least
from cfbs.utils import (
get_json,
immediate_subdirectories,
version_is_at_least,
write_json,
CFBSNetworkError,
CFBSExitError,
)

DOWNLOAD_PATH = "downloaded_masterfiles"

Expand Down Expand Up @@ -33,6 +44,8 @@ def generate_release_information_impl(
)
generate_vcf_download(DOWNLOAD_PATH, downloaded_versions)

generate_release_history()

if check:
print(
"Downloading releases of masterfiles from git (github.com) and generating "
Expand All @@ -52,3 +65,85 @@ def generate_release_information_impl(
"(Run again with --check-against-git to download and compare with files "
+ "from git, and generate -git.json files)"
)


def generate_release_history():
print("Generating release history information...")

releases_data = download_releasedata()

stable_releases = filter_unstable_releases(releases_data)

file_checksums_dict = build_release_history(stable_releases)

sorted_releases = sort_release_data(file_checksums_dict)

write_json("./cfengine-enterprise/checksums.json", sorted_releases)


def download_releasedata():
# Downloading releases.json:
try:
releases_data = get_json(ENTERPRISE_RELEASES_URL)

except CFBSNetworkError:
raise CFBSExitError(
"Downloading CFEngine release data failed - check your Wi-Fi / network settings."
)

return releases_data


def build_release_history(filtered_releases):
release_history = {}

for release_data in filtered_releases:
if not release_data.get("version") or not release_data.get("URL"):
continue

subdata, version = download_release_version_data(release_data)
version_files = extract_version_files(subdata)

if version_files:
release_history[version] = version_files

return release_history


def download_release_version_data(release_data):
# Downloads each versionnumber.json in releases.json
version = release_data.get("version")
url = release_data.get("URL")

try:
return get_json(url), version
except CFBSNetworkError:
raise CFBSExitError(
f"Downloading CFEngine release data for version {version} failed - check your Wi-Fi / network settings."
)


def extract_version_files(subdata):
# Gets filenames and checksums for each file in the subdata of releases.json:
artifacts = subdata.get("artifacts", {})
version_files = {}

for asset_list in artifacts.values():
for asset_data in asset_list:
filename, checksum = extract_file_info(asset_data)

if filename and checksum:
version_files[filename] = checksum

return version_files


def extract_file_info(asset_data):
url = asset_data.get("URL")
checksum = asset_data.get("SHA256")

if url and checksum:
filename = url.split("/")[-1]
return filename, checksum

return None, None
Loading