conventional-changelog v1.0.0が出てcliのapiが変わった

tl;dr

ふえー

他にもショートハンドのオプションは変わってるのかも。自分はこれだけでひとまず行けた。
https://github.com/dogwalk/firefox-page-for-hatena-bookmark/pull/19/files

これをnpm moduleとgem packageぶんやるのか… やらない…

広告

conventional-changelog(npm)をRuby pruductから使う

conventional-changelogにactiveなメンテナーが増えて、v0.1.0に上がって以降(2015-09-25 時点でv0.4.3)だいぶ使いやすくなっている。
Ruby productから使う時の使い方をまとめた。

下記エントリーの続き。

bin/changelogを作って使う、と以前書いていたけど、設定ファイルだけ書いて、あとはコマンドラインのconventional-changelogから使えるようになった。実際に使っている例 parse_gemspec-cli

具体的にはこんなpackage.json書いて、npm run changelogする。

{
  "devDependencies": {
    "conventional-changelog": "0.4.3",
    "urijs": "^1.16.1"
  },
  "scripts": {
    "changelog": "conventional-changelog -i changelog.md --overwrite --preset angular --context .conventional-changelog.context.js"
  }
}

contextの指定で、無指定だとpackage.json読んでバージョンやリポジトリのurl取得するところを、Rubyプロダクト用に書き換えてやれば良い。
設定すべき値はconventional-changelog-writer のオプション。これを.conventional-changelog.context.jsにかく。ファイル名はどうでもいい。

'use strict';
var execSync = require('child_process').execSync;
var URI = require('urijs');

var gemspec = JSON.parse(execSync('bundle exec parse-gemspec-cli parse_gemspec-cli.gemspec'));
var homepageUrl = gemspec.homepage;
var url = new URI(homepageUrl);
var host = url.protocol() + '://' + url.authority();
var owner = url.pathname().split('/')[1];
var repository = url.pathname().split('/')[2];

module.exports = {
  version: gemspec.version,
  host: host,
  owner: owner,
  repository: repository
};

gemspec を読んで json を吐き出す parse_gemspec-cli gemを作った。パッケージはparse_gemspec-cli、コマンドは parse-gemspec-cli。今のところ name, version, homepage しか取り出せないけど、changelogの用途にはこれで良い。

これでgemを書くときにもchangelog環境が快適になった。

$ conventional-changelog --help
Options
(snip)
    -c, --context             A filepath of a javascript that is used to define template variables
    --git-raw-commits-opts    A filepath of a javascript that is used to define git-raw-commits options
    --parser-opts             A filepath of a javascript that is used to define conventional-commits-parser options
    --writer-opts             A filepath of a javascript that is used to define conventional-changelog-writer options

conventional-changelogのコマンドが、細かくmoduleに分割したあとにも、使うmoduleの設定書いたうえでCLIツールからそのまま使えるの、よく出来ている。

conventional-changelogがrubyから使いづらいのでどうにかしたい

TL;DR

いくつかこのリストのchangelog generatorを使い比べた結果、やはりconventional-changelogがいいとおもったんだが、Rubyからは使いづらい。
試行錯誤してる。

短い比較

skywinder/github-changelog-generator

CHANGELOG.mdの表示が一番きれい
リンクもわかりやすい。タグとタグの間で表示を作るので、タグを打ったあとにしか更新できない。
載せる載せないはgithubのissueのtagでfilter出来る。

lalitkapoor/github-changes

まあまあきれい
コミットにすると細かすぎるので、pull requestにするとよさそう。タグとタグの間で表示を作るので、タグを打ったあとにしか更新できない。

ajoslin/conventional-changelog

angularjsである
特長はangularjsのcommit comment conventionで縛って、changelogに載せる載せないをfilterしている。
覚えるのがはじめはツライ。他人のcommit messageをいじるのはツライ。自分でもとくにgithub上で編集してそのままコミットすると Update readme とかになっててツライ。
バージョンやリポジトリ情報はpackage.jsonからデフォルトでは読み取る。
縛りメンドイけど、それがいいのでは?という気がしている。

前提

changelog書きたい時って、一番いいのはmergeしたとき、一番遅くて changelog変更ー>tag 打つ-> releaseでしょ?
tagとtagの間を検出するchangelog generatorはtag打ってからでないと検出しないので、github表示上はそれでいいんだけど、gemやnpmのpackageに入れるには間に合わない。githubのrelase pageはそれでいいのかもしれない。
もちろんtagから最新バージョンを取らなくすると、バージョンチェンジしたことにして生成するか、changelog generatorに次のバージョン渡して生成するか、なんらかversion読み取って生成しなくてはいけなくて、package managerに渡してるバージョンを取るので言語ごとに考えなければいけなくなってしまう。

というissueを各changelog generatorにあげればいいのか。うーむ。

conventional changelog

自分はconventional changelogが好きなので、使っている。ただしRubyのproductに適用しようとすると、一手間必要。

試行錯誤1 version.json

rubyスクリプトの中からYourApp::VERSION で取れるのは維持したい。
すると、version.rbと別にversion.jsonをつくって、version.rbではversion.jsonから読み取るようにする。

# version.rb
module PullRequest
  module Create
    VERSION = "0.1.1.beta"
  end
end

これを

# version.json
{
  "version": "0.1.1.beta"
}

# version.rb
require 'json'
module PullRequest
  module Create
    VERSION = ::JSON.parse(File.read('./lib/pull_request/create/version.json'))['version']
  end
end

こんな感じ

こうすると、jsonなので、conventional-changelogから簡単に読める。
これで行こうと思ったけど、なんというかぎょっとするので却下。

試行錯誤2 parse ruby

これをbin/conventional-changelog に置いて、あとpackage.jsonをリポジトリに置きつつgemのfilesからは外してる。

#!/usr/bin/env node

var fs = require('fs');
var execSync = require('child_process').execSync;
var conventionalChangelog = require('conventional-changelog');

var version = "" + execSync('ruby -e \'require "./lib/pull_request/create/version"; print PullRequest::Create::VERSION\'');

conventionalChangelog({
  repository: 'https://github.com/packsaddle/ruby-pull_request-create',
  version: version,
  file: 'CHANGELOG.md'
}, function(err, log) {
  fs.writeFile('CHANGELOG.md', log, function(err){
    console.log(err);
  });
  console.log('Here is your changelog!', log);
});

jsからruby実行するのかよ! というのはあるけど、ここで閉じてるのでjson読み込むのよりはぎょっとしない。
ただだるいのは、いちいちrepositoryとかversionのprintする中身とか、いちいち書き換えること。

現状jsからrubyを呼び出すほうで回してみている。