UNPKG

3.71 kBJavaScriptView Raw
1/*
2 * chg
3 * https://github.com/heff/chg
4 *
5 * Copyright (c) 2014 heff
6 * Licensed under the Apache license.
7 */
8
9'use strict';
10
11var chg = module.exports = {};
12
13var fs = require('fs');
14var shell = require('shelljs');
15var moment = require('moment');
16var semver = require('semver');
17
18var changeLogFile = 'CHANGELOG.md';
19var unreleasedTitle = '## HEAD (Unreleased)\n';
20var noItems = '_(none)_';
21var divider = '--------------------\n\n';
22
23var ERR_NO_CHANGELOG = changeLogFile+' does not exist. Change to the directory where it does exist, or run `init` to create one in the current directory.';
24
25function defCallback(){}
26
27function getChangeLog(){
28 if (!fs.existsSync(changeLogFile)) {
29 return null;
30 }
31 return fs.readFileSync(changeLogFile, 'utf8');
32}
33
34chg.init = function(options, callback){
35 options = options || {};
36 callback = callback || defCallback;
37
38 if (fs.existsSync(changeLogFile)){
39 return callback(changeLogFile + ' already exists');
40 }
41
42 var contents = 'CHANGELOG\n=========\n\n';
43 contents += unreleasedTitle + noItems + '\n\n' + divider;
44
45 fs.writeFileSync(changeLogFile, contents, 'utf8');
46
47 callback(null, changeLogFile+' created');
48};
49
50chg.delete = function(options, callback){
51 options = options || {};
52 callback = callback || defCallback;
53
54 if (fs.existsSync(changeLogFile)){
55 shell.rm(changeLogFile);
56 callback(null, changeLogFile+' deleted');
57 } else {
58 callback(changeLogFile+' does not exist');
59 }
60};
61
62chg.add = function(line, options, callback){
63 var contents, sections, top;
64
65 options = options || {};
66 callback = callback || defCallback;
67
68 // get existing contents
69 contents = getChangeLog();
70 if (!contents) {
71 return callback(ERR_NO_CHANGELOG);
72 }
73
74 // if 'noItems' is there, remove it
75 contents = contents.replace(unreleasedTitle + noItems + '\n', unreleasedTitle);
76
77 // split on the divider including preceding newline
78 sections = contents.split('\n'+divider);
79 // add new line to the unreleased section
80 top = sections[0] + '* ' + line + '\n\n';
81
82 // combine new contents and write file
83 contents = top + divider + sections[1];
84 fs.writeFileSync(changeLogFile, contents, 'utf8');
85
86 callback(null, 'Change added');
87};
88
89chg.release = function(version, options, callback){
90 var date, contents, changes, title, pkgVersion;
91
92 callback = callback || defCallback;
93 options = options || {};
94 date = options.date || moment().format('YYYY-MM-DD');
95 version = version || options.version || null;
96
97 if (!version) {
98 return callback('Version required');
99 }
100
101 // allow incrementing version for a release type
102 if (['major','minor','patch'].indexOf(version) != -1) {
103 if (fs.existsSync('./package.json')) {
104 pkgVersion = require(process.cwd()+'/package.json').version;
105 version = semver.inc(pkgVersion, version);
106 } else {
107 callback('No package.json was found');
108 }
109 }
110
111 // get existing contents
112 contents = getChangeLog();
113 if (!contents) {
114 return callback(ERR_NO_CHANGELOG);
115 }
116
117 // get everything after the unreleased title
118 changes = contents.split(unreleasedTitle)[1];
119 // get only the unreleased changes
120 changes = changes.split('\n\n')[0];
121 // replace unreleased changes with noItems
122 contents = contents.replace(changes, noItems);
123
124 // build new release title
125 title = '##' + ' ' + version + ' ('+ date +')\n';
126 // add title at the top of the release section
127 contents = contents.replace(divider, divider + title + changes + '\n\n');
128
129 fs.writeFileSync(changeLogFile, contents, 'utf8');
130
131 callback(null, 'Changelog updated with new release');
132};
\No newline at end of file