18

より複雑な bash スクリプトの最初の作業バージョンを完成させたばかりで、スクリプトのバージョンを維持する方法について頭を悩ませています。

なぜこれが必要なのですか?コマンドライン インターフェイスの GNU コーディング標準に従います。ライセンスと著作権のヘッダーの間に現在のバージョンを表示するバージョン オプションを追加しました。

それでも、バージョンを「最新」に保つ方法がわかりません。

これまでの私の考えは、メジャー | に git タグを使用することです。マイナー | パッチをリリースし、スクリプトに含まれる変数を何らかの形で置き換えます。

という名前のタグがある場合1.1.0

$ myscript --version

次のような出力が必要です。

myscript 1.1.0

スクリプトには、このためのシェル変数が含まれています。

version=1.1.0

それでも、バージョンを最新のタグと同期させる方法がわかりませんか?

4

4 に答える 4

14

私が知る限り、あなたが望んでいることは不可能です。バージョン番号をバージョン管理ソフトウェアにコミットするには、バージョン番号を編集し、コミットしてからタグを付ける必要があります。その逆ではありません。ただし、プロセスをもう少し合理化することができます。

これを行うには、スクリプトのバージョン番号を読み取り、前回から変更されている場合は新しいタグを書き出すポストコミット フックを作成します。これを行うには.git/hooks、プロジェクト ディレクトリからcd して、 post-commit(または move post-commit.sample) というファイルを作成し、実行可能にします。次に、次のように編集します。

#!/bin/bash

NEWEST_TAG=$(git describe --abbrev=0 --tags)

SCRIPT_VERSION=$(grep "^version=" myscript | awk -F= '{print $2}')

if [ x$NEWEST_TAG != x$SCRIPT_VERSION ]; then
    git tag -a $SCRIPT_VERSION -m "version $SCRIPT_VERSION"
fi

次にスクリプトのバージョン番号を上げて変更をコミットすると、最新のコミットに新しいタグが追加されていることがわかります。

于 2012-08-13T14:41:49.723 に答える
8

git commit以前に与えられたフックベースの回答は、バージョン文字列の同期を;と緊密に結合します。ただし、逆の方法で機能させたいようです。つまり、バージョンは手動で作成されたgit tagメタデータから抽出されます。実際、これはgitソースコード自体が使用するアプローチとほぼ同じであることがわかったので、そのアプローチを調べて、同様の方法を採用する方法を学びましょう。

  • 現在のバージョンをインテリジェントに判別しようとするGIT-VERSION-GENシェルスクリプトがあります。基本的に、を介してバージョン文字列を抽出しようとしgit describeますが、それが機能しない場合は、ハードコードされたデフォルトにフォールバックします。バージョンはGIT-VERSION-FILEソースツリーの一番上に書き込まれます。
  • はこのMakefileスクリプトを呼び出しinclude、生成されたファイルを次のように呼び出します。

    GIT-VERSION-FILE: FORCE
            @$(SHELL_PATH) ./GIT-VERSION-GEN
    -include GIT-VERSION-FILE
    

    Makefileこれで、 viaの残りの部分からバージョンにアクセスできるようになりました$(GIT_VERSION)

  • 次に、さまざまなMakeルールがこれを使用して、さまざまなPerlスクリプトなど、ハードコードされたバージョン文字列を必要とするファイルの置換を実行します。

    $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl GIT-VERSION-FILE
            $(QUIET_GEN)$(RM) $@ $@+ && \
            INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C perl -s --no-print-directory instlibdir` && \
            sed -e '1{' \
                [... snipped other substitutions ...]
                -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
                $@.perl >$@+ && \
            chmod +x $@+ && \
            mv $@+ $@
    

    たとえば、の先頭近くを見ると、次のように表示されgit-svn.perlます。

    $VERSION = '@@GIT_VERSION@@';
    

私のソースツリーでは、このルールはgit-svn次の行を含むファイルにコンパイルされています。

    $VERSION = '1.7.11.rc0.55.gb2478aa';

したがって、ローカルでコンパイルされたバージョンを確認すると、次のようになりgit-svnます。

    $ git svn --version
    git-svn version 1.7.11.rc0.55.gb2478aa (svn 1.6.17)

一方、rpmベースのインストールを実行すると、次のように表示されます。

    $ /usr/bin/git svn --version
    git-svn version 1.7.6.5 (svn 1.6.17)

この最後の出力は、サブディレクトリにバージョン管理メタデータが含まれていないリリースされたtarballからソースコードがコンパイルされた場合でも、このアプローチが機能することを示しています.git/。これは、バージョン文字列が安定したリリースと開発スナップショットをうまく区別することを意味します。

Perlスクリプトですがgit-svn、明らかに同じ置換アプローチがシェルスクリプトに対して適切に機能します。

于 2012-08-15T17:13:45.467 に答える
3

自分でタグを作成する代わりに、コミット後のフックを使用します。HEADにバージョン割り当てを変更する行が含まれているかどうかを確認し、含まれている場合は、新しいタグを作成するという考え方です。これは大まかな例です。それはバグがあるかもしれません、そしてそれは確かにそれができるほど効率的ではありません。

#!/bin/bash

before=$( git log HEAD | awk -F= '/-version=/ {print $1}' )
after=$( git log HEAD | awk -F= '/+version=/ {print $1}' )

if [[ $before != $after ]]; then
    git tag myscript-$after
fi
于 2012-08-13T14:24:49.340 に答える
2

それでも、バージョンを「最新」に保つ方法がわかりません。

私はポストフックの推奨事項が好きです。ただし、別のアプローチとして、ビルド システムが既に利用可能な場合は、それを使用することもできます。自動ビルドシステムはありますか? ジェンキンスかバンブーか?私たちのビルド システムは、すべての単体テストに合格した成功したビルドごとに新しいタグを作成します。確かにこれはスクリプトなので、ユニット テストがある場合は実行するだけで済みます。ビルド ジョブにタスクを追加して、成功したビルドまたはテストを実行して合格した最新のコミットのタグを使用してバージョンをインクリメントまたは一致させることができます。

于 2012-08-15T15:36:31.593 に答える