name: Update set implementation lists on: # push: # branches: [master] workflow_dispatch: concurrency: group: set-impl cancel-in-progress: true jobs: update-set-impl-issues: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: 16 - run: npm install mustache shell: bash - uses: actions/github-script@v6.4.1 id: updateissues with: script: | const mustache = require('mustache') const path = require('path') const fs = require('fs') // Disable mustache html-escape mustache.escape = function(str) { return str; }; // https://stackoverflow.com/a/2970667 function toCamelCase(str) { return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function(word, index) { return index === 0 ? word.toLowerCase() : word.toUpperCase(); }).replace(/\s+/g, '') } const setsData = fs.readFileSync(path.join('Utils', 'mtg-sets-data.txt'), 'utf8') .split('\n') .map(line => line.split('|')); const cardsData = fs.readFileSync(path.join('Utils', 'mtg-cards-data.txt'), 'utf8') .split('\n') .map(line => line.split('|')) .filter(card => !(card[0].toLowerCase() === "plains" || card[0].toLowerCase() === "swamp" || card[0].toLowerCase() === "island" || card[0].toLowerCase() === "mountain" || card[0].toLowerCase() === "forest")); const cardIssueTemplate = fs.readFileSync(path.join('.github', 'templates', 'set-tracking-issue.md'), 'utf8'); const issues = await github.paginate(github.rest.issues.listForRepo, { owner: context.repo.owner, repo: context.repo.repo, labels: 'tracking set' }); console.log("Found list of existing issues:", issues); const issuesToUpdate = []; const issuesToCreate = []; setsData.forEach(set => { let foundIssue = undefined; issues.every(issue => { if(issue && issue.title && issue.title.startsWith(set[1])) { console.log(`Found tracking issue for ${set[0]} with issue number: ${issue.number}`); foundIssue = issue; return false; } return true; }); const cards = cardsData.filter(card => card[1] === set[0]); const unimplemented = []; const implemented = []; cards.forEach(cardData => { const className = toCamelCase(cardData[0].replace(/[+]/g, ' Plus ').replace(/[_]+/g, ' Blank ').replace(/[']/g, '').replace(/[-+,.!?`@#$%^&*()_=<>:";~\\|/]/g, ' ')); const cleanCardName = cardData[0].replace(/[-,'.!?`@#$%^&*()_=<>:";~\\|/\s]/g, '').toLowerCase(); const cardPath = path.join('Mage.Sets', 'src', 'mage', 'cards', className.substring(0, 1), `${className.charAt(0).toUpperCase()+className.slice(1)}.java`); if (fs.existsSync(cardPath)) { implemented.push({ pr: true, //TODO: check to see if there is a PR for this card name: cardData[0], cleanName: cleanCardName, scryfall: `https://scryfall.com/search?q=!"${cleanCardName}"+e:${set[1]}` }); } else { unimplemented.push({ pr: false, //TODO: check to see if there is a PR for this card name: cardData[0], cleanName: cleanCardName, scryfall: `https://scryfall.com/search?q=!"${cleanCardName}"+e:${set[1]}` }); } }); const cleanCards = cards.map(card => card[0].replace(/[-,'.!?`@#$%^&*()_=<>:";~\\|/\s]/g, '').toLowerCase()); if (foundIssue !== undefined) { foundIssue.body = mustache.render(cardIssueTemplate, { hasUnimplementedCards: unimplemented.length > 0, hasImplementedCards: implemented.length > 0, unimplementedCards: unimplemented, implementedCards: implemented, unimplementedScryfallLink: `https://scryfall.com/search?q=!"${unimplemented.map(e => e.cleanName).join('"OR!"')}"+e:${set[1]}` }); issuesToUpdate.push(foundIssue); } else { issuesToCreate.push({ title: `${set[1]}: ${set[0]} Set Card Implementation Tracking`, body: mustache.render(cardIssueTemplate, { hasUnimplementedCards: unimplemented.length > 0, hasImplementedCards: implemented.length > 0, unimplementedCards: unimplemented, implementedCards: implemented, unimplementedScryfallLink: `https://scryfall.com/search?q=!"${unimplemented.map(e => e.cleanName).join('"OR!"')}"+e:${set[1]}` }) }); } }); console.log("Issues to update: ", issuesToUpdate); console.log("Issues to create: ", issuesToCreate); - uses: actions/github-script@v6.4.1 id: updatewiki with: script: | const mustache = require('mustache') const path = require('path') const fs = require('fs') // Disable mustache html-escape mustache.escape = function(str) { return str; }; // https://stackoverflow.com/a/2970667 function toCamelCase(str) { return str.replace(/(?:^\w|[A-Z]|\b\w)/g, function(word, index) { return index === 0 ? word.toLowerCase() : word.toUpperCase(); }).replace(/\s+/g, '') } const setImplementationTemplate = fs.readFileSync(path.join('.github', 'templates', 'set-tracking-wiki.md'), 'utf8'); const setsData = fs.readFileSync(path.join('Utils', 'mtg-sets-data.txt'), 'utf8') .split('\n') .map(line => line.split('|')); const cardsData = fs.readFileSync(path.join('Utils', 'mtg-cards-data.txt'), 'utf8') .split('\n') .map(line => line.split('|')) .filter(card => !(card[0].toLowerCase() === "plains" || card[0].toLowerCase() === "swamp" || card[0].toLowerCase() === "island" || card[0].toLowerCase() === "mountain" || card[0].toLowerCase() === "forest")) const issues = await github.paginate(github.rest.issues.listForRepo, { owner: context.repo.owner, repo: context.repo.repo, labels: 'tracking set' }); const sets = []; setsData.forEach(set => { let foundIssue = undefined; issues.every(issue => { if(issue && issue.title && issue.title.startsWith(set[1])) { console.log(`Found tracking issue for ${set[0]} with issue number: ${issue.number}`); foundIssue = issue; return false; } return true; }); const cards = cardsData.filter(card => card[1] === set[0]); let implementedCount = 0; cards.forEach(cardData => { const className = toCamelCase(cardData[0].replace(/[+]/g, ' Plus ').replace(/[_]+/g, ' Blank ').replace(/[']/g, '').replace(/[-+,.!?`@#$%^&*()_=<>:";~\\|/]/g, ' ')); const cleanCardName = cardData[0].replace(/[-,'.!?`@#$%^&*()_=<>:";~\\|/\s]/g, '').toLowerCase(); const cardPath = path.join('Mage.Sets', 'src', 'mage', 'cards', className.substring(0, 1), `${className.charAt(0).toUpperCase()+className.slice(1)}.java`); if (fs.existsSync(cardPath)) { implementedCount++; } }); sets.push({ name: set[0], issueLink: foundIssue === undefined ? "https://www.github.com/mage/magefree" : foundIssue.url, total: cards.length, missing: cards.length - implementedCount }); }); const content = mustache.render(setImplementationTemplate, { sets: sets }); console.log(content); try { fs.writeFileSync(path.join('wiki', 'Set-implementation-list.md'), content); } catch (err) { console.error(err); }