Skip to content
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
4 changes: 2 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ insert_final_newline = false
trim_trailing_whitespace = true
charset = utf-8

[*.js]
insert_final_newline = true
[*.{js,md}]
insert_final_newline = true
18 changes: 0 additions & 18 deletions .eleventy.js

This file was deleted.

11 changes: 0 additions & 11 deletions .eslintrc.js

This file was deleted.

26 changes: 26 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
on:
push:
branches-ignore:
- "gh-pages"
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: ["ubuntu-latest", "macos-latest", "windows-latest"]
node: ["18", "22"]
name: Node.js ${{ matrix.node }} on ${{ matrix.os }}
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup node
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- run: npm install
- run: npm run lint
- run: npm test
env:
YARN_GPG: no
1 change: 0 additions & 1 deletion .husky/.gitignore

This file was deleted.

5 changes: 0 additions & 5 deletions .husky/pre-commit

This file was deleted.

9 changes: 5 additions & 4 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
.editorconfig
.eslintcache
.eslintrc.js
.github/
.husky/pre-commit
.nyc_output
.gitattributes
eslint.config.js
tests
.travis.yml
.gitattributes
prettier.config.js
lefthook.yml
ava.config.js
16 changes: 0 additions & 16 deletions .travis.yml

This file was deleted.

10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This Eleventy plugin provides two [template filters](https://www.11ty.dev/docs/f

🌏 This plugin is made primarily to populate `<updated>` fields in an RSS feed. Here is [a blog post on how to use this plugin](https://saneef.com/tutorials/fix-dates-on-eleventy-rss-feeds/) with [`eleventy-plugin-rss`](https://www.11ty.dev/docs/plugins/rss/).

⚠️ Getting Git commit date is a bit slow (\~50ms for each path). So, use it sparingly. It's recommended to call this filter within a production flag.
⚠️ Git commit date is a bit slow. So, it's recommended to call this filter within a production flag.

## Usage

Expand All @@ -22,13 +22,13 @@ npm install eleventy-plugin-git-commit-date
### 2. Add to Eleventy config

```js
// .eleventy.js
// eleventy.config.js

const pluginGitCommitDate = require("eleventy-plugin-git-commit-date");
import pluginGitCommitDate from "eleventy-plugin-git-commit-date";

module.exports = function (eleventyConfig) {
export default function (eleventyConfig) {
eleventyConfig.addPlugin(pluginGitCommitDate);
};
}
```

### 3. Use in templates
Expand Down
6 changes: 6 additions & 0 deletions ava.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
files: ["tests/**/*", "!tests/utils.js"],
watchMode: {
ignoreChanges: ["tests/output/**"],
},
};
38 changes: 38 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// @ts-check
import { FlatCompat } from "@eslint/eslintrc";
import js from "@eslint/js";
import prettier from "eslint-plugin-prettier";
import { defineConfig } from "eslint/config";
import globals from "globals";
import path from "path";
import { fileURLToPath } from "url";

// Mimic CommonJS variables -- not needed if using CommonJS
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});

export default defineConfig([
{
extends: compat.extends("xo-space", "plugin:prettier/recommended"),

plugins: {
prettier,
},

rules: {
"prettier/prettier": "error",
},

languageOptions: {
globals: {
...globals.browser,
},
},
},
]);
16 changes: 16 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// @ts-check
import getCollectionNewestGitCommitDate from "./src/getCollectionNewestGitCommitDate.js";
import getGitCommitDateFromPath from "./src/getGitCommitDateFromPath.js";

export default function (eleventyConfig) {
eleventyConfig.addAsyncFilter(
"getGitCommitDateFromPath",
getGitCommitDateFromPath,
);
eleventyConfig.addAsyncFilter(
"getCollectionNewestGitCommitDate",
getCollectionNewestGitCommitDate,
);
}

export { getCollectionNewestGitCommitDate, getGitCommitDateFromPath };
15 changes: 15 additions & 0 deletions lefthook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
pre-commit:
commands:
prettier:
glob: "*.{js,md,json}"
run: npx prettier --write {staged_files}
stage_fixed: true

eslint:
glob: "*.{js}"
run: npx eslint --fix {staged_files}
stage_fixed: true

tests:
glob: "*.{js}"
run: npm run test
41 changes: 15 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
"name": "eleventy-plugin-git-commit-date",
"version": "0.1.3",
"description": "Eleventy plugin to get Git commit time of a file, or a Eleventy collection.",
"main": ".eleventy.js",
"main": "index.js",
"type": "module",
"repository": {
"type": "git",
"url": "git+https://github.com:saneef/eleventy-plugin-git-commit-date.git"
},
"scripts": {
"lint": "eslint src/**.js tests/**.js",
"test": "nyc ava --timeout=1m -v --color",
"prepare": "husky install"
"test": "ava"
},
"keywords": [
"last-updated",
Expand All @@ -26,28 +26,17 @@
"cross-spawn": "^7.0.3"
},
"devDependencies": {
"ava": "^3.15.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-xo-space": "^0.29.0",
"eslint-plugin-prettier": "^3.4.0",
"husky": "^7.0.1",
"lint-staged": "^11.1.2",
"nyc": "^15.1.0",
"prettier": "^2.3.2",
"rimraf": "^3.0.2"
},
"lint-staged": {
"*.js": "eslint --cache --fix",
"*.{js,md,json}": "prettier --write"
},
"ava": {
"files": [
"tests/**/*",
"!tests/utils.js"
],
"ignoredByWatcher": [
"tests/output/**"
]
"@eslint/eslintrc": "^3.3.3",
"@eslint/js": "^9.39.2",
"ava": "^6.4.1",
"eslint": "^9.39.2",
"eslint-config-prettier": "^10.1.8",
"eslint-config-xo-space": "^0.35.0",
"eslint-plugin-prettier": "^5.5.4",
"globals": "^16.5.0",
"lefthook": "^2.0.13",
"prettier": "^3.7.4",
"prettier-plugin-jsdoc": "^1.8.0",
"rimraf": "^5.0.9"
}
}
7 changes: 7 additions & 0 deletions prettier.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// @ts-check
/** @type {import("prettier").Config} */
const config = {
plugins: ["prettier-plugin-jsdoc"],
};

export default config;
26 changes: 16 additions & 10 deletions src/getCollectionNewestGitCommitDate.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
// @ts-check
const getGitCommitDateFromPath = require("./getGitCommitDateFromPath");
import getGitCommitDateFromPath from "./getGitCommitDateFromPath.js";
import memoize from "./utils/memoize.js";

/**
* Gets the collection's newest Git commit date.
*
* @param {Array<object>} collection The collection
*
* @return {Date} The collection newest git commit date.
* @param {object[]} collection Collection
* @returns {Promise<Date | undefined>} Newest git commit date among the items
* in the collection
*/
module.exports = function (collection) {
async function getCollectionNewestGitCommitDate(collection) {
if (!collection || !collection.length) {
return;
}

const timestamps = collection
.map((item) => getGitCommitDateFromPath(item.inputPath))
const timestamps = await Promise.all(
collection.map((item) => getGitCommitDateFromPath(item.inputPath)),
);

const dates = timestamps
// Timestamps will be undefined for the paths not
// yet commited to Git. So weeding them out.
.filter((ts) => Boolean(ts))
.map((ts) => ts.getTime());

if (timestamps.length) {
return new Date(Math.max(...timestamps));
if (dates.length) {
return new Date(Math.max(...dates));
}
};
}

export default memoize(getCollectionNewestGitCommitDate);
37 changes: 17 additions & 20 deletions src/getGitCommitDateFromPath.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,34 @@
// @ts-check
const path = require("path");
const spawn = require("cross-spawn");
import memoize from "./utils/memoize.js";
import { spawnAsync } from "./utils/spawn.js";

/**
* Gets the Git commit date from path.
*
* The code is based on @vuepress/plugin-last-updated,
* https://github.com/vuejs/vuepress/blob/master/packages/%40vuepress/plugin-last-updated/
*
* @param {string} filePath The file path
*
* @return {Date} The git commit date if path is commited to Git.
* @param {string} filePath The file path
* @returns {Promise<Date | undefined>} Commit date if path is commited to Git,
* otherwise `undefined`
*/
module.exports = function (filePath) {
async function getGitCommitDateFromPath(filePath) {
let output;

try {
output = spawn.sync(
"git",
["log", "-1", "--format=%at", path.basename(filePath)],
{ cwd: path.dirname(filePath) }
);
} catch {
output = await spawnAsync("git", ["log", "-1", "--format=%at", filePath]);
} catch (e) {
console.log(e);
throw new Error("Fail to run 'git log'");
}

if (output && output.stdout) {
const ts = parseInt(output.stdout.toString("utf-8"), 10) * 1000;
const ts = parseInt(output, 10) * 1000;

// Paths not commited to Git returns empty timestamps, resulting in NaN.
// So, convert only valid timestamps.
if (!isNaN(ts)) {
return new Date(ts);
}
// Paths not commited to Git returns empty timestamps, resulting in NaN.
// So, convert only valid timestamps.
if (!isNaN(ts)) {
return new Date(ts);
}
};
}

export default memoize(getGitCommitDateFromPath);
Loading