From d59136cc3353c6ce6b9c575c74cbbcd778c344e1 Mon Sep 17 00:00:00 2001 From: jmlundeen Date: Fri, 29 Aug 2025 14:55:56 -0500 Subject: [PATCH] update gen-list-unimplemented-cards-for-set to match current GitHub template --- Utils/gen-list-unimplemented-cards-for-set.pl | 129 +++++++++++------- Utils/issue_tracker.tmpl | 18 +++ 2 files changed, 96 insertions(+), 51 deletions(-) create mode 100644 Utils/issue_tracker.tmpl diff --git a/Utils/gen-list-unimplemented-cards-for-set.pl b/Utils/gen-list-unimplemented-cards-for-set.pl index 3d8d2849a3c..fbf345bf31d 100755 --- a/Utils/gen-list-unimplemented-cards-for-set.pl +++ b/Utils/gen-list-unimplemented-cards-for-set.pl @@ -1,13 +1,14 @@ #!/usr/bin/perl -w #author: North - +use Text::Template; use strict; use Scalar::Util qw(looks_like_number); my $dataFile = "mtg-cards-data.txt"; my $setsFile = "mtg-sets-data.txt"; my $knownSetsFile = "known-sets.txt"; +my $templateFile = "issue_tracker.tmpl"; my %sets; my %knownSets; @@ -16,12 +17,13 @@ my @setCards; open (DATA, $knownSetsFile) || die "can't open $knownSetsFile"; while(my $line = ) { + chomp $line; my @data = split('\\|', $line); $knownSets{$data[0]} = $data[1]; - #print ("$data[0] ===> $data[1]\n"); } close(DATA); +my @basicLands = ("Plains", "Island", "Swamp", "Mountain", "Forest"); # gets the set name my $setName = $ARGV[0]; @@ -29,7 +31,6 @@ if(!$setName) { print 'Enter a set name: '; $setName = ; chomp $setName; - $setName = $setName; } while (!defined ($knownSets{$setName})) @@ -49,13 +50,12 @@ while (!defined ($knownSets{$setName})) print 'Enter a set name: '; $setName = ; - $setName = $setName; chomp $setName; } - open (DATA, $dataFile) || die "can't open $dataFile"; while(my $line = ) { + chomp $line; my @data = split('\\|', $line); if ($data[1] eq $setName) { push(@setCards, \@data); @@ -65,70 +65,97 @@ close(DATA); open (DATA, $setsFile) || die "can't open $setsFile"; while(my $line = ) { + chomp $line; my @data = split('\\|', $line); $sets{$data[0]}= $data[1]; } close(DATA); - sub cardSort { - if (!looks_like_number(@{$a}[2])) { return -1; } - if (!looks_like_number(@{$b}[2])) { return 1; } - if (@{$a}[2] < @{$b}[2]) { return -1; } - elsif (@{$a}[2] == @{$b}[2]) { return 0;} - elsif (@{$a}[2] > @{$b}[2]) { return 1; } + if (!looks_like_number(@{$a}[2])) { return -1; } + if (!looks_like_number(@{$b}[2])) { return 1; } + if (@{$a}[2] < @{$b}[2]) { return -1; } + elsif (@{$a}[2] == @{$b}[2]) { return 0;} + elsif (@{$a}[2] > @{$b}[2]) { return 1; } } sub toCamelCase { my $string = $_[0]; $string =~ s/\b([\w']+)\b/ucfirst($1)/ge; - $string =~ s/[-,\s\']//g; + $string =~ s/[-,\s\'!@#*\(\)]//g; $string; } -# TODO: check for basic lands with ending 1,2,3,4,5 ... +# Check which cards are implemented my %cardNames; -my $toPrint = ''; -my $setAbbr = $sets{$setName}; -foreach my $card (sort cardSort @setCards) { - my $className = toCamelCase(@{$card}[0]); +my %seenCards; # Track which card names we've already processed +my @implementedCards; +my @unimplementedCards; +my $previousCollectorNumber = -1; +my %vars; - $cardNames {@{$card}[0]} = 1; +my $setAbbr = $sets{$setName}; + +foreach my $card (sort cardSort @setCards) { + my $className = toCamelCase(@{$card}[0]); + if ($className ~~ @basicLands) { + next; + } + + my $cardName = @{$card}[0]; + my $collectorNumber = @{$card}[2]; + + # Skip if we've already processed this card name or is the back face of a card + if (exists $seenCards{$cardName} or $previousCollectorNumber == $collectorNumber) { + $seenCards{$cardName} = 1; + next; + } + $seenCards{$cardName} = 1; + $previousCollectorNumber = $collectorNumber; my $currentFileName = "../Mage.Sets/src/mage/cards/" . lc(substr($className, 0, 1)) . "/" . $className . ".java"; - if(! -e $currentFileName) { - $cardNames {@{$card}[0]} = 0; - if ($toPrint) { - $toPrint .= "\n"; - } - my $cardName = @{$card}[0]; - $cardName =~ s/ /+/g; - $toPrint .= "@{$card}[2]|[@{$card}[0]](https://scryfall.com/search?q=!\"$cardName\" e:$setAbbr)"; - } -} + my $cardNameForUrl = $cardName; + $cardNameForUrl =~ s/ //g; + my $cardEntry = "- [ ] In progress -- [$cardName](https://scryfall.com/search?q=!\"$cardNameForUrl\" e:$setAbbr)"; -open CARD, "> " . lc($sets{$setName}) ."_unimplemented.txt"; -print CARD $toPrint; -close CARD; - - -print ("Unimplemented cards are here: " . lc($sets{$setName}) ."_unimplemented.txt\n"); - -open ISSUE_TRACKER, "> " . lc($sets{$setName}) ."_issue_tracker.txt"; -print ISSUE_TRACKER "# Cards in set:\n"; - - -my $cn; -foreach $cn (sort keys (%cardNames)) -{ - my $x_or_not = "[ ]"; - if ($cardNames {$cn} == 1) - { - $x_or_not = "[x]"; + if(-e $currentFileName) { + # Card is implemented + $cardNames{$cardName} = 1; + my $implementedEntry = "- [x] Done -- [$cardName](https://scryfall.com/search?q=!\"$cardNameForUrl\" e:$setAbbr)"; + push(@implementedCards, $implementedEntry); + } else { + # Card is not implemented + $cardNames{$cardName} = 0; + push(@unimplementedCards, $cardEntry); } - my $cn2 = $cn; - $cn2 =~ s/ /+/g; - print ISSUE_TRACKER "- $x_or_not [$cn](https://scryfall.com/search?q=!\"$cn2\" e:$setAbbr)\n"; } -close ISSUE_TRACKER; -print ("Tracking Issue text for a new Github issue (similar to https://github.com/magefree/mage/issues/2215): " . lc($setAbbr) ."_issue_tracker.txt\n"); + +# Build the unimplemented URL for Scryfall +my $unimplementedUrl = "https://scryfall.com/search?q="; +my @unimplementedNames; +foreach my $cardName (sort keys %cardNames) { + if ($cardNames{$cardName} == 0) { + my $urlCardName = $cardName; + $urlCardName =~ s/ //g; + $urlCardName =~ s/"/\\"/g; # Escape quotes + push(@unimplementedNames, "!\"$urlCardName\""); + } +} +$unimplementedUrl .= join("or", @unimplementedNames) . "&unique=cards"; + +# Read template file +my $template = Text::Template->new(TYPE => 'FILE', SOURCE => $templateFile, DELIMITERS => [ '[=', '=]' ]); +$vars{'unimplemented'} = join("\n", @unimplementedCards); +$vars{'implemented'} = join("\n", @implementedCards); +$vars{'setName'} = $setName; +$vars{'unimplementedUrl'} = $unimplementedUrl; +my $result = $template->fill_in(HASH => \%vars); +# Write the final issue tracker file +my $outputFile = lc($sets{$setName}) . "_issue_tracker.txt"; +open(OUTPUT, "> $outputFile") || die "can't open $outputFile for writing"; +print OUTPUT $result; +close(OUTPUT); + +print "Issue tracker generated: $outputFile\n"; +print "Implemented cards: " . scalar(@implementedCards) . "\n"; +print "Unimplemented cards: " . scalar(@unimplementedCards) . "\n"; \ No newline at end of file diff --git a/Utils/issue_tracker.tmpl b/Utils/issue_tracker.tmpl new file mode 100644 index 00000000000..17b7b196da2 --- /dev/null +++ b/Utils/issue_tracker.tmpl @@ -0,0 +1,18 @@ +This checklist is here to help manage the implementation of [=$setName=]. If a card is marked as being in progress then someone is working on it. + +If you're new to implementing cards then you likely don't have permission to check things off. This is totally fine! We still appreciate your contributions so just leave a comment to let us know that you're working on it. + +Don't worry about moving things from in progress to completed either, there's a script that handles that, and don't worry about fixing text issues as those are usually handled when the set is done. + +[All Sets](https://github.com/magefree/mage/wiki/Set-implementation-list) + +# Unimplemented Cards + +[=$unimplemented=] + +[Scryfall gallery of everything currently unimplemented]([=$unimplementedUrl=]) +# Implemented Cards +
Click to expand + +[=$implemented=] +