Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow fetching Git metadata from submodules #19

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
node_modules
/gatsby-node.js
coverage
89 changes: 89 additions & 0 deletions gatsby-node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"use strict";

const git = require(`simple-git/promise`);

const path = require('path');

const fs = require('fs');

async function getLogWithRetry(gitRepo, node, retry = 2) {
// Need retry, see https://github.com/steveukx/git-js/issues/302
// Check again after v2 is released?
const filePath = fs.realpathSync.native(node.absolutePath, (error, resolvedPath) => {
if (error) {
console.log(error);
return;
} else {
return resolvedPath;
}
});
const logOptions = {
file: filePath,
n: 1,
format: {
date: `%ai`,
authorName: `%an`,
authorEmail: "%ae"
}
};
const log = await gitRepo.log(logOptions);

if (!log.latest && retry > 0) {
return getLogWithRetry(gitRepo, node, retry - 1);
}

return log;
}

async function onCreateNode({
node,
actions
}, pluginOptions) {
const {
createNodeField
} = actions;

if (node.internal.type !== `File`) {
return;
}

if (pluginOptions.include && !pluginOptions.include.test(node.absolutePath)) {
return;
}

if (pluginOptions.ignore && pluginOptions.ignore.test(node.absolutePath)) {
return;
}

const gitRepo = git(pluginOptions.dir || fs.realpathSync.native(path.dirname(node.absolutePath), (error, resolvedPath) => {
if (error) {
console.log(error);
return;
} else {
return resolvedPath;
}
}));
const log = await getLogWithRetry(gitRepo, node);

if (!log.latest) {
return;
}

createNodeField({
node,
name: `gitLogLatestAuthorName`,
value: log.latest.authorName
});
createNodeField({
node,
name: `gitLogLatestAuthorEmail`,
value: log.latest.authorEmail
});
createNodeField({
node,
name: `gitLogLatestDate`,
value: log.latest.date
});
}

exports.onCreateNode = onCreateNode;
79 changes: 71 additions & 8 deletions src/__tests__/gatsby_node.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ let actions;
let node;
let createNodeSpec;
let dummyRepoPath;
let dummyRepoSubmodulePath;

beforeEach(() => {
createNodeField = jest.fn();
Expand All @@ -33,6 +34,17 @@ beforeEach(() => {
};
});

const initGitRepo = async (path, username, useremail, remote) => {
const gitRepo = git(path);

await gitRepo.init();
await gitRepo.addConfig("user.name", username);
await gitRepo.addConfig("user.email", useremail);
await gitRepo.addRemote("origin", remote);

return gitRepo;
}

describe(`Processing nodes not matching initial filtering`, () => {
it(`should not add any field when internal type is not 'File'`, async () => {
node.internal.type = "Other";
Expand Down Expand Up @@ -69,19 +81,45 @@ describe(`Processing File nodes matching filter regex`, () => {
path.join(os.tmpdir(), "gatsby-transform-gitinfo-")
);

const gitRepo = git(dummyRepoPath);
await gitRepo.init();
await gitRepo.addConfig("user.name", "Some One");
await gitRepo.addConfig("user.email", "[email protected]");
await gitRepo.addRemote("origin", "https://some.git.repo");
const gitRepo = await initGitRepo(
dummyRepoPath,
"Some One",
"[email protected]",
"https://some.git.repo",
);

fs.writeFileSync(`${dummyRepoPath}/README.md`, "Hello");
await gitRepo.add("README.md");
await gitRepo.commit("Add README", "README.md", {
"--date": '"Mon 20 Aug 2018 20:19:19 UTC"'
});
await gitRepo.commit(
"Add README",
"README.md", {
"--date": '"Mon 20 Aug 2018 20:19:19 UTC"'
}
);

fs.writeFileSync(`${dummyRepoPath}/unversionned`, "World");

dummyRepoSubmodulePath = fs.mkdtempSync(
path.join(os.tmpdir(), "gatsby-transform-gitinfo-submodule-")
);

const gitRepoSubmodule = await initGitRepo(
dummyRepoSubmodulePath,
"Some One Else",
"[email protected]",
"https://some.other.git.repo",
);

fs.writeFileSync(`${dummyRepoSubmodulePath}/CONTENT.md`, "Hello");
await gitRepoSubmodule.add("CONTENT.md");
await gitRepoSubmodule.commit(
"Add CONTENT",
"CONTENT.md", {
"--date": '"Mon 20 Aug 2018 20:19:19 UTC"'
}
);

await gitRepo.submoduleAdd(dummyRepoSubmodulePath, "submodule")
});

it("should add log and remote git info to commited File node", async () => {
Expand Down Expand Up @@ -109,6 +147,31 @@ describe(`Processing File nodes matching filter regex`, () => {
});
});

it("should add log and remote git info to file in submodule", async () => {
node.absolutePath = `${dummyRepoPath}/submodule/CONTENT.md`;
node.dir = dummyRepoPath;
await onCreateNode(createNodeSpec, {
include: /md/,
dir: dummyRepoPath
});
expect(createNodeField).toHaveBeenCalledTimes(3);
expect(createNodeField).toHaveBeenCalledWith({
node,
name: `gitLogLatestAuthorName`,
value: `Some One Else`
});
expect(createNodeField).toHaveBeenCalledWith({
node,
name: `gitLogLatestAuthorEmail`,
value: `[email protected]`
});
expect(createNodeField).toHaveBeenCalledWith({
node,
name: `gitLogLatestDate`,
value: `2018-08-20 20:19:19 +0000`
});
});

it("should not add log or remote git info to unversionned File node", async () => {
node.absolutePath = `${dummyRepoPath}/unversionned`;
node.dir = dummyRepoPath;
Expand Down
24 changes: 22 additions & 2 deletions src/gatsby-node.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
const git = require(`simple-git/promise`);
const path = require('path');
const fs = require('fs')

async function getLogWithRetry(gitRepo, node, retry = 2) {
// Need retry, see https://github.com/steveukx/git-js/issues/302
// Check again after v2 is released?

const filePath = fs.realpathSync.native(node.absolutePath, (error, resolvedPath) => {
if (error) {
console.log(error)
return
}
else {
return resolvedPath
}
});

const logOptions = {
file: node.absolutePath,
file: filePath,
n: 1,
format: {
date: `%ai`,
Expand Down Expand Up @@ -36,7 +48,15 @@ async function onCreateNode({ node, actions }, pluginOptions) {
return;
}

const gitRepo = git(pluginOptions.dir);
const gitRepo = git(pluginOptions.dir || fs.realpathSync.native(path.dirname(node.absolutePath), (error, resolvedPath) => {
if (error) {
console.log(error)
return
}
else {
return resolvedPath
}
}));
const log = await getLogWithRetry(gitRepo, node);

if (!log.latest) {
Expand Down