filter to only releases in the last year
This commit is contained in:
parent
7b555e2162
commit
6edaa25cc5
1 changed files with 113 additions and 13 deletions
126
src/main.zig
126
src/main.zig
|
@ -18,6 +18,9 @@ const zeit = @import("zeit");
|
|||
|
||||
const Provider = @import("Provider.zig");
|
||||
|
||||
// Configuration: Only include releases from the last year in the output
|
||||
const RELEASE_AGE_LIMIT_SECONDS: i64 = 365 * 24 * 60 * 60; // 1 year in seconds
|
||||
|
||||
pub const Release = struct {
|
||||
repo_name: []const u8,
|
||||
tag_name: []const u8,
|
||||
|
@ -147,27 +150,38 @@ pub fn main() !u8 {
|
|||
print("Found {} new releases from {s}\n", .{ result.releases.items.len, result.provider_name });
|
||||
}
|
||||
|
||||
// Combine existing and new releases
|
||||
// Combine all releases (existing and new)
|
||||
var all_releases = ArrayList(Release).init(allocator);
|
||||
defer all_releases.deinit();
|
||||
|
||||
// Add new releases first (they'll appear at the top of the Atom feed)
|
||||
// Add new releases
|
||||
try all_releases.appendSlice(new_releases.items);
|
||||
|
||||
// Add existing releases (up to a reasonable limit to prevent Atom feed from growing indefinitely)
|
||||
const max_total_releases = 1000;
|
||||
const remaining_slots = if (new_releases.items.len < max_total_releases)
|
||||
max_total_releases - new_releases.items.len
|
||||
else
|
||||
0;
|
||||
|
||||
const existing_to_add = @min(existing_releases.items.len, remaining_slots);
|
||||
try all_releases.appendSlice(existing_releases.items[0..existing_to_add]);
|
||||
// Add all existing releases
|
||||
try all_releases.appendSlice(existing_releases.items);
|
||||
|
||||
// Sort all releases by published date (most recent first)
|
||||
std.mem.sort(Release, all_releases.items, {}, compareReleasesByDate);
|
||||
|
||||
// Generate Atom feed
|
||||
// Filter releases by age in-place - zero extra allocations
|
||||
const now = std.time.timestamp();
|
||||
const cutoff_time = now - RELEASE_AGE_LIMIT_SECONDS;
|
||||
|
||||
var write_index: usize = 0;
|
||||
const original_count = all_releases.items.len;
|
||||
|
||||
for (all_releases.items) |release| {
|
||||
const release_time = parseReleaseTimestamp(release.published_at) catch 0;
|
||||
if (release_time >= cutoff_time) {
|
||||
all_releases.items[write_index] = release;
|
||||
write_index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Shrink the array to only include filtered items
|
||||
all_releases.shrinkRetainingCapacity(write_index);
|
||||
|
||||
// Generate Atom feed from filtered releases
|
||||
const atom_content = try atom.generateFeed(allocator, all_releases.items);
|
||||
defer allocator.free(atom_content);
|
||||
|
||||
|
@ -178,7 +192,7 @@ pub fn main() !u8 {
|
|||
|
||||
// Log to stderr for user feedback
|
||||
std.debug.print("Found {} new releases\n", .{new_releases.items.len});
|
||||
std.debug.print("Total releases in feed: {}\n", .{all_releases.items.len});
|
||||
std.debug.print("Total releases in feed: {} (filtered from {} total, showing last {} days)\n", .{ all_releases.items.len, original_count, @divTrunc(RELEASE_AGE_LIMIT_SECONDS, 24 * 60 * 60) });
|
||||
std.debug.print("Updated feed written to: {s}\n", .{output_file});
|
||||
|
||||
return 0;
|
||||
|
@ -761,6 +775,92 @@ test {
|
|||
std.testing.refAllDecls(@import("xml_parser_tests.zig"));
|
||||
}
|
||||
|
||||
test "Age-based release filtering" {
|
||||
const allocator = std.testing.allocator;
|
||||
|
||||
const now = std.time.timestamp();
|
||||
const one_year_ago = now - RELEASE_AGE_LIMIT_SECONDS;
|
||||
const two_years_ago = now - (2 * RELEASE_AGE_LIMIT_SECONDS);
|
||||
|
||||
// Create releases with different ages
|
||||
const recent_release = Release{
|
||||
.repo_name = "test/recent",
|
||||
.tag_name = "v1.0.0",
|
||||
.published_at = try std.fmt.allocPrint(allocator, "{}", .{now - 86400}), // 1 day ago
|
||||
.html_url = "https://github.com/test/recent/releases/tag/v1.0.0",
|
||||
.description = "Recent release",
|
||||
.provider = "github",
|
||||
};
|
||||
defer allocator.free(recent_release.published_at);
|
||||
|
||||
const old_release = Release{
|
||||
.repo_name = "test/old",
|
||||
.tag_name = "v0.1.0",
|
||||
.published_at = try std.fmt.allocPrint(allocator, "{}", .{two_years_ago}),
|
||||
.html_url = "https://github.com/test/old/releases/tag/v0.1.0",
|
||||
.description = "Old release",
|
||||
.provider = "github",
|
||||
};
|
||||
defer allocator.free(old_release.published_at);
|
||||
|
||||
const borderline_release = Release{
|
||||
.repo_name = "test/borderline",
|
||||
.tag_name = "v0.5.0",
|
||||
.published_at = try std.fmt.allocPrint(allocator, "{}", .{one_year_ago + 3600}), // 1 hour within limit
|
||||
.html_url = "https://github.com/test/borderline/releases/tag/v0.5.0",
|
||||
.description = "Borderline release",
|
||||
.provider = "github",
|
||||
};
|
||||
defer allocator.free(borderline_release.published_at);
|
||||
|
||||
const releases = [_]Release{ recent_release, old_release, borderline_release };
|
||||
|
||||
// Test filtering logic
|
||||
var filtered = ArrayList(Release).init(allocator);
|
||||
defer filtered.deinit();
|
||||
|
||||
const cutoff_time = now - RELEASE_AGE_LIMIT_SECONDS;
|
||||
|
||||
for (releases) |release| {
|
||||
const release_time = parseReleaseTimestamp(release.published_at) catch 0;
|
||||
if (release_time >= cutoff_time) {
|
||||
try filtered.append(release);
|
||||
}
|
||||
}
|
||||
|
||||
// Should include recent and borderline, but not old
|
||||
try std.testing.expectEqual(@as(usize, 2), filtered.items.len);
|
||||
|
||||
// Verify the correct releases were included
|
||||
var found_recent = false;
|
||||
var found_borderline = false;
|
||||
var found_old = false;
|
||||
|
||||
for (filtered.items) |release| {
|
||||
if (std.mem.eql(u8, release.repo_name, "test/recent")) {
|
||||
found_recent = true;
|
||||
} else if (std.mem.eql(u8, release.repo_name, "test/borderline")) {
|
||||
found_borderline = true;
|
||||
} else if (std.mem.eql(u8, release.repo_name, "test/old")) {
|
||||
found_old = true;
|
||||
}
|
||||
}
|
||||
|
||||
try std.testing.expect(found_recent);
|
||||
try std.testing.expect(found_borderline);
|
||||
try std.testing.expect(!found_old);
|
||||
}
|
||||
|
||||
test "RELEASE_AGE_LIMIT_SECONDS constant verification" {
|
||||
// Verify the constant is set to 1 year in seconds
|
||||
const expected_year_in_seconds = 365 * 24 * 60 * 60;
|
||||
try std.testing.expectEqual(expected_year_in_seconds, RELEASE_AGE_LIMIT_SECONDS);
|
||||
|
||||
// Verify it's approximately 31.5 million seconds (1 year)
|
||||
try std.testing.expect(RELEASE_AGE_LIMIT_SECONDS > 31_000_000);
|
||||
try std.testing.expect(RELEASE_AGE_LIMIT_SECONDS < 32_000_000);
|
||||
}
|
||||
|
||||
// Import timestamp tests
|
||||
test {
|
||||
std.testing.refAllDecls(@import("timestamp_tests.zig"));
|
||||
|
|
Loading…
Add table
Reference in a new issue