diff --git a/.gitignore b/.gitignore index 1cd9c7a0..5e00711c 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,4 @@ bundle-stats.json # Generated JSON src/generated/ plugins/source-terasology-modules/data.json +plugins/source-terasology-engine/data.json diff --git a/gatsby-config.js b/gatsby-config.js index 8a699b64..9222a445 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -94,6 +94,12 @@ module.exports = { accessToken: process.env.GITHUB_TOKEN, }, }, + { + resolve: "source-terasology-engine", + options: { + accessToken: process.env.GITHUB_TOKEN, + }, + }, { resolve: "gatsby-plugin-nprogress", options: { diff --git a/package.json b/package.json index 5e50f18a..7d6a6260 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,8 @@ "private": "true", "workspaces": [ ".", - "plugins/source-terasology-modules" + "plugins/source-terasology-modules", + "plugins/source-terasology-engine" ], "author": "The Terasology Foundation", "dependencies": { diff --git a/plugins/source-terasology-engine/README.md b/plugins/source-terasology-engine/README.md new file mode 100644 index 00000000..ed2252c5 --- /dev/null +++ b/plugins/source-terasology-engine/README.md @@ -0,0 +1,51 @@ +# source-terasology-engine + +Custom [Gatsby Source Plugin](https://www.gatsbyjs.com/docs/how-to/plugins-and-themes/creating-a-source-plugin/) to fetch enriched information for the [Terasology Engine](https://github.com/MovingBlocks/Terasology) from GitHub. + +## Install + +This is a local plugin that is automatically loaded from the `plugins/` folder. + +## Configuration + +```js +// in gatsby-config.js +module.exports = { + plugins: [ + //... + { + resolve: "source-terasology-engine", + options: { + accessToken: `` + } + } + ] +} +``` + +Use [Environment Variables](https://www.gatsbyjs.com/docs/how-to/local-development/environment-variables/) to avoid exposing secrets. + +## Usage + +```graphql +query Engine { + allTerasologyEngine { + issues{ + nodes { + id + title + author { + login + } + labels { + nodes { + name + } + } + updatedAt + url + } + } + } +} +``` diff --git a/plugins/source-terasology-engine/gatsby-node.js b/plugins/source-terasology-engine/gatsby-node.js new file mode 100644 index 00000000..0266121c --- /dev/null +++ b/plugins/source-terasology-engine/gatsby-node.js @@ -0,0 +1,103 @@ +const { graphql } = require("@octokit/graphql"); +const { DateTime } = require("luxon"); +const fs = require("fs"); + +const PLUGIN_NAME = "source-terasology-engine"; + +const query = ` +query Engine { + organization(login: "MovingBlocks") { + repository(name: "Terasology") { + issues(first: 10, filterBy: {labels: "Good First Issue", states: OPEN}, orderBy: {field: UPDATED_AT, direction: DESC}) { + nodes { + id + title + author { + login + } + labels(first: 10) { + nodes { + name + } + } + updatedAt + url + } + } + } + } +} +`; + +exports.onPreInit = ({ reporter }) => + reporter.verbose("Loaded source-terasology-engine"); + +exports.sourceNodes = async ( + { + actions: { createNode }, + createContentDigest, + createNodeId, + reporter, + cache, + }, + { accessToken } +) => { + const gql = graphql.defaults({ + headers: { + authorization: `token ${accessToken}`, + }, + }); + + const lastFetchedKey = "terasology-engine-last-fetched"; + const dataKey = "terasology-engine-data"; + + const now = DateTime.utc(); + const lastFetched = DateTime.fromISO(await cache.get(lastFetchedKey), { + zone: "utc", + }); + + let engine = {}; + + // Temporary hack to avoid fetching data from GitHub during local testing. + // Un-/comment as needed after changing the query. + if (fs.existsSync(`${__dirname}/data.json`)) { + // engine = JSON.parse(fs.readFileSync(`${__dirname}/data.json`)); + } + + if (lastFetched.plus({ hours: 12 }) > now) { + reporter.info( + `[${PLUGIN_NAME}] Loading Terasology engine info from cache ...` + ); + engine = JSON.parse(await cache.get(dataKey)); + } else { + reporter.info( + `[${PLUGIN_NAME}] Fetching Terasology engine info from GitHub ...` + ); + + const { organization } = await gql(query); + engine = organization.repository; + + await cache.set(dataKey, JSON.stringify(engine)); + await cache.set(lastFetchedKey, now.toISO()); + + fs.writeFileSync(`${__dirname}/data.json`, JSON.stringify(engine, null, 2)); + } + + reporter.success(`[${PLUGIN_NAME}] Loaded Terasology engine info.`); + + const node = { + id: createNodeId(`TerasologyEngine`), + issues: engine.issues, + parent: "__SOURCE__", + children: [], + internal: { + type: "TerasologyEngine", + }, + }; + + node.internal.contentDigest = createContentDigest(node); + + createNode(node); + + reporter.success(`[${PLUGIN_NAME}] Created node for Terasology engine.`); +}; diff --git a/plugins/source-terasology-engine/index.js b/plugins/source-terasology-engine/index.js new file mode 100644 index 00000000..172f1ae6 --- /dev/null +++ b/plugins/source-terasology-engine/index.js @@ -0,0 +1 @@ +// noop diff --git a/plugins/source-terasology-engine/package.json b/plugins/source-terasology-engine/package.json new file mode 100644 index 00000000..148f64c3 --- /dev/null +++ b/plugins/source-terasology-engine/package.json @@ -0,0 +1,21 @@ +{ + "name": "source-terasology-engine", + "version": "0.0.1", + "private": true, + "description": "A Gatsby source plugin to fetch Terasology engine information.", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "echo \"No build script setup\"" + }, + "keywords": [ + "gatsby", + "gatsby-plugin" + ], + "author": "The Terasology Foundation ", + "dependencies": { + "@octokit/graphql": "^5.0.4", + "gatsby-source-filesystem": "^5.3.1", + "luxon": "^3.2.0" + } +}