From 32fcd43b441cc4f4c3af289d4560211e02e5ba1e Mon Sep 17 00:00:00 2001
From: Giovanni Garufi <g.garufi@students.uu.nl>
Date: Mon, 27 Aug 2018 10:54:45 +0200
Subject: [PATCH] versionist.conf.js: Add versionist config file

Also adds package.json to include the dependencies required in
versionist.conf.js

Changelog-entry: Add versionist support
Signed-off-by: Giovanni Garufi <giovanni@resin.io>
---
 .gitignore         |   3 +-
 package.json       |   8 ++++
 versionist.conf.js | 102 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 112 insertions(+), 1 deletion(-)
 create mode 100644 package.json
 create mode 100644 versionist.conf.js

diff --git a/.gitignore b/.gitignore
index 89c0ed1..05eee0b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,7 @@ shared-*/
 # device type manifest stuff
 /node_modules
 *.json
+!package.json
 
 # dynamically created by the build script
-conf-notes.txt
+conf-notes.txt
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..29f7e5d
--- /dev/null
+++ b/package.json
@@ -0,0 +1,8 @@
+{
+  "private": true,
+  "devDependencies": {
+    "lodash": "^4.17.10",
+    "semver": "^5.5.1",
+    "shelljs": "^0.8.2"
+  }
+}
diff --git a/versionist.conf.js b/versionist.conf.js
new file mode 100644
index 0000000..82959ba
--- /dev/null
+++ b/versionist.conf.js
@@ -0,0 +1,102 @@
+'use strict';
+
+const _ = require('lodash')
+const fs = require('fs')
+const path = require('path')
+const semver = require('semver')
+const shell = require('shelljs')
+
+const getAuthor = (commitHash) => {
+  const authorCmd = shell.exec(`git show --quiet --format="%an" ${commitHash}`)
+  if (authorCmd.code !== 0) {
+    throw new Error(authorCmd.stderr)
+  }
+  return authorCmd.stdout.replace('\n', '')
+}
+
+const compareExtendedSemver = (a, b) => {
+  const semverCompare = semver.compare(a, b)
+  if (semverCompare !== 0) {
+    return semverCompare
+  }
+  return a.localeCompare(b)
+}
+
+const getMetaResinFromSubmodule = (documentedVersions, history, callback) => {
+  shell.exec('git submodule status layers/meta-resin', (code, stdout, stderr) => {
+    if (code != 0) {
+      return callback(new Error('Could not find meta-resin submodule'))
+    }
+    const match = /.{40} .* \(v(.+)\)/.exec(stdout)
+
+    if (!match) {
+      return callback(new Error(`Could not determine meta-resin version from version ${stdout}`))
+    }
+
+    const metaVersion = `${match[1]}+rev0`
+    const latestDocumented = _.trim(_.last(documentedVersions.sort(compareExtendedSemver)))
+
+    // semver.gt will ignore the revision numbers but still compare the version
+    // If metaVersion <= latestDocumented then the latestDocumented version is a revision of the current metaVersion
+    const latestVersion = semver.gt(metaVersion, latestDocumented) ? metaVersion : latestDocumented
+
+    return callback(null, latestVersion)
+  })
+}
+
+const updateVersionFile = (cwd, version, callback) => {
+  const versionFile = path.join(cwd, 'VERSION')
+
+  fs.writeFile(versionFile, version, callback)
+}
+
+module.exports = {
+  addEntryToChangelog: {
+    preset: 'prepend',
+    fromLine: 3
+  },
+  getChangelogDocumentedVersions: {
+    preset: 'changelog-headers',
+    clean: /^v/
+  },
+  getGitReferenceFromVersion: 'v-prefix',
+  includeCommitWhen: (commit) => {
+    return commit.footer['changelog-entry']
+  },
+  getIncrementLevelFromCommit: (commit) => {
+    return 'patch'
+  },
+  incrementVersion: (currentVersion, incrementLevel) => {
+    const revision = Number(currentVersion[currentVersion.length - 1])
+    if (!_.isFinite(revision)) {
+      throw new Error(`Could not extract revision number from ${currentVersion}`)
+    }
+    return currentVersion.slice(0, currentVersion.length - 1) + (revision + 1)
+  },
+  getCurrentBaseVersion: getMetaResinFromSubmodule,
+  updateVersion: updateVersionFile,
+  // If a 'changelog-entry' tag is found, use this as the subject rather than the
+  // first line of the commit.
+  transformTemplateData: (data) => {
+    data.commits.forEach((commit) => {
+      commit.subject = commit.footer['changelog-entry'] || commit.subject
+      commit.author = getAuthor(commit.hash)
+    });
+    if (_.isEmpty(data.commits)) {
+      throw new Error('At least one commit must be annotated with a Changelog-entry tag')
+    }
+    return data;
+  },
+  template: [
+    '# v{{version}}',
+    '## ({{moment date "Y-MM-DD"}})',
+    '',
+    '{{#each commits}}',
+    '{{#if this.author}}',
+    '* {{capitalize this.subject}} [{{this.author}}]',
+    '{{else}}',
+    '* {{capitalize this.subject}}',
+    '{{/if}}',
+    '{{/each}}'
+  ].join('\n')
+}