Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: TheMagoo73/gatsby-source-gcp-storage
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.0.1-alpha0
Choose a base ref
...
head repository: TheMagoo73/gatsby-source-gcp-storage
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
  • 13 commits
  • 5 files changed
  • 1 contributor

Commits on Sep 23, 2019

  1. Copy the full SHA
    460d7c5 View commit details
  2. More tests

    TheMagoo73 committed Sep 23, 2019
    Copy the full SHA
    adf3e3e View commit details
  3. Merge

    TheMagoo73 committed Sep 23, 2019
    Copy the full SHA
    ddfa93a View commit details
  4. CircleCi integration

    TheMagoo73 committed Sep 23, 2019
    Copy the full SHA
    7a5bd64 View commit details
  5. Bump version for build

    TheMagoo73 committed Sep 23, 2019
    Copy the full SHA
    b80dc4a View commit details
  6. Copy the full SHA
    bb2d524 View commit details
  7. Merge pull request #1 from TheMagoo73/v1.0.1-beta.1

    V1.0.1 beta.1
    TheMagoo73 authored Sep 23, 2019
    Copy the full SHA
    50fdd11 View commit details
  8. Bump version

    TheMagoo73 committed Sep 23, 2019
    Copy the full SHA
    f20fc92 View commit details
  9. Merge

    TheMagoo73 committed Sep 23, 2019
    Copy the full SHA
    eb029f4 View commit details

Commits on Oct 23, 2019

  1. Copy the full SHA
    678c6c7 View commit details
  2. Fix the build!

    TheMagoo73 committed Oct 23, 2019
    Copy the full SHA
    bbaba16 View commit details
  3. Fix package.json

    TheMagoo73 committed Oct 23, 2019
    Copy the full SHA
    cdd898c View commit details
  4. One more time...

    TheMagoo73 committed Oct 23, 2019
    Copy the full SHA
    650a27c View commit details
Showing with 220 additions and 5 deletions.
  1. +81 −0 .circleci/config.yml
  2. +2 −2 package.json
  3. +6 −0 readme.md
  4. +19 −3 src/gatsby-node.js
  5. +112 −0 test/gatsby-node.spec.js
81 changes: 81 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
version: 2.1
orbs:
codecov: codecov/codecov@1.0.2
jobs:
build:
docker:
- image: circleci/node:10.15

working_directory: ~/repo

steps:
- checkout

- restore_cache:
keys:
- v1-dependencies-{{ checksum "package.json" }}
- v1-dependencies-

- run: npm install

- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}

# run tests!
- run: npm run test-report
- run: npm run coverage-report
- run: npm run codecov

# store test results
- store_test_results:
path: test_results

# store code coverage
- store_artifacts:
path: .nyc_output

# upload coverage to codecov
- codecov/upload:
file: coverage.lcov

- persist_to_workspace:
root: ~/repo
paths: .

deploy:
docker:
- image: circleci/node:latest

working_directory: ~/repo

steps:
- attach_workspace:
at: ~/repo
- run:
name: Build the source
command: npm run prepare
- run:
name: Authenticate with NPM
command: echo "//registry.npmjs.org/:_authToken=$npm_TOKEN" > ~/repo/.npmrc
- run:
name: Publish package
command: npm publish --access public

workflows:
version: 2
test-deploy-beta:
jobs:
- build:
filters:
tags:
only: /.*/
- deploy:
requires:
- build
filters:
branches:
ignore: /.*/
tags:
only: /^v.*/
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "gatsby-source-gcp-storage",
"version": "0.0.1-alpha.0",
"version": "1.0.6",
"description": "Gatsby source for reading files from GCP storage buckets",
"main": "index.js",
"main": "gatsby-node.js",
"scripts": {
"test": "nyc mocha",
"test-report": "nyc mocha test --reporter mocha-junit-reporter --reporter-options mochaFile=./test_results/junit/results.xml",
6 changes: 6 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# gatsby-source-gcp-storage
A Gatsby source plugin for sourcing data into your Gatsby application from file in a GCP Storage bucket.

[![](https://img.shields.io/npm/v/gatsby-source-gcp-storage.svg)](https://www.npmjs.com/package/gatsby-source-gcp-storage)
[![](https://img.shields.io/npm/dm/gatsby-source-gcp-storage.svg)](https://www.npmjs.com/package/gatsby-source-gcp-storage)
[![CircleCI](https://circleci.com/gh/TheMagoo73/gatsby-source-gcp-storage/tree/master.svg?style=svg)](https://circleci.com/gh/TheMagoo73/gatsby-source-gcp-storage/tree/master)
[![codecov](https://codecov.io/gh/TheMagoo73/gatsby-source-gcp-storage/branch/master/graph/badge.svg)](https://codecov.io/gh/TheMagoo73/gatsby-source-gcp-storage)
[![david](https://david-dm.org/themagoo73/gatsby-source-gcp-storage.svg)]()

The plugin creates `GCPFile` nodes from files in GCP Storage. It then uses the `gatsby-source-filesystem` to download a local copy of the files from GCP, and generate `File` nodes. The various "transformer" plugins can transform the File nodes into various other types of data e.g. `gatsby-transformer-json` transforms JSON files into JSON data nodes and `gatsby-transform-remark` transforms markdown files into `MarkdownRemark` nodes from which you can query and HTML representation of the markdown.

## Warnings!
22 changes: 19 additions & 3 deletions src/gatsby-node.js
Original file line number Diff line number Diff line change
@@ -26,6 +26,8 @@ exports.sourceNodes = async (api, pluginOptions) => {
A GCP JSON token file is required to authenticate with the GCP storage API
`)

return
}

if(!gcpBucketName) {
@@ -36,12 +38,26 @@ exports.sourceNodes = async (api, pluginOptions) => {
The GCP storage bucket name is required
`)

return
}

const storage = new Storage({keyFilename: gcpTokenFile})
const gcpBucket = storage.bucket(gcpBucketName)
let files

try{
const storage = new Storage({keyFilename: gcpTokenFile})
const gcpBucket = storage.bucket(gcpBucketName)

let files = await gcpBucket.getFiles({directory: storageDirectory || `/`})
files = await gcpBucket.getFiles({directory: storageDirectory || `/`})
} catch(err) {
reporter.panic(`
gatsby-source-gcp-storage: unable to access storage.
The GCP storage bucket/folder could not be accessed. Ensure that the bucker and path properties are correct, and the supplied SA account token has access
`)
}

if(files[0].length < 1) {
reporter.warn(`gatsby-source-gcp-storage: no files to process in ${gcpBucketName}/${storageDirectory}`)
112 changes: 112 additions & 0 deletions test/gatsby-node.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
const chai = require("chai")
const chaiAsPromised = require("chai-as-promised")
const sinonChai = require("sinon-chai")
const sinon = require("sinon")

chai.use(sinonChai)
chai.use(chaiAsPromised)
chai.should()

const rewire = require('rewire')

const {Storage, Bucket, File} = require('@google-cloud/storage')
const {Readable} = require('stream')
const sourceNodes = rewire('../src/gatsby-node')

// Mock the Gatsby API
const apiMock = {
actions: {
createNode: sinon.spy()
},
reporter: {
panic: sinon.stub(),
warn: sinon.stub(),
info: sinon.stub()
},
createNodeId: sinon.stub(),
store: sinon.stub(),
cache: sinon.stub()
}

// Mock gatsby-source-filesystem helper function
const createFileNodeFromBufferStub = sinon.stub().resolves({id: '9876'})

// Mock the @Google Storage API
class FileStub {
constructor() {}

getMetadata() { return Promise.resolve([
{
mediaLink: 'https://foo.com/files/bar.md',
name: 'files/bar.md',
bucket: 'fooBucket',
md5hash: 'ABC123'
}
])}
createReadStream() { return Promise.resolve(new Readable())}
}

class BucketStub {
constructor() {}

getFiles(options) {
if(options.directory !== '/')
return Promise.resolve([[new FileStub()],[]])
else
return Promise.resolve([[],[]])
}
}

class StorageStub {
constructor() {}

bucket() { return new BucketStub()}
}

// Arrange stubs
sourceNodes.__set__("createFileNodeFromBuffer", createFileNodeFromBufferStub)
sourceNodes.__set__("Storage", StorageStub)

describe('gatsby-source-gcp-storage', ()=> {

beforeEach(() => {
apiMock.reporter.panic.resetHistory()
apiMock.reporter.warn.resetHistory()
apiMock.actions.createNode.resetHistory()
createFileNodeFromBufferStub.resetHistory()
})

it('validates required options', async () => {

const params = [
{gcpTokenFile: null, gcpBucketName: "bucket"},
{gcpTokenFile: "token", gcpBucketName: null}
]

for(let i=0; i< params.length; i++){
apiMock.reporter.panic.resetHistory()
await sourceNodes.sourceNodes(apiMock, params[i])
apiMock.reporter.panic.should.be.calledOnce
}
})

it('works', async () => {
await sourceNodes.sourceNodes(apiMock, {gcpTokenFile: "token", gcpBucketName: "bucket", storageDirectory: "/foo"})
apiMock.reporter.panic.should.not.be.called
apiMock.actions.createNode.should.be.calledOnce
apiMock.actions.createNode.args[0][0].internal.type.should.deep.equals('GcpStorage')
apiMock.actions.createNode.args[0][0].internal.mediaType.should.deep.equals('application/gcpfile')
apiMock.actions.createNode.args[0][0].localFile___NODE.should.deep.equals('9876')
})

it("defaults to the root directory", async () => {
await sourceNodes.sourceNodes(apiMock, {gcpTokenFile: "token", gcpBucketName: "bucket"})
apiMock.reporter.warn.should.be.calledOnce
})

it('type can be renamed', async () => {
await sourceNodes.sourceNodes(apiMock, {gcpTokenFile: "token", gcpBucketName: "bucket", storageDirectory: "/foo", name: "FooDocs"})
apiMock.actions.createNode.args[0][0].internal.type.should.deep.equals('FooDocs')
})

})