1.26.2015

C++/Python: Running Travis CI with Boost.Python and Python 3.2/3.3/3.4

C++/Python: Python3.2, 3.3, 3.4 の全てで Boost.Python プロジェクトの Travis CI を回す

 

前回(mog project: C++/Python: Travis CI with Boost.Python and Python3)の続き。

Boost をソースからインストールすることで、Python 3.2, 3.3, 3.4 に対応した
Boost.Python のテストを Travis CI 上で回すことができるようになった。

 

.travis.yml

mog-cli/.travis.yml at master · mogproject/mog-cli

---
language: python

os:
  - linux
  - osx

python:
  - "3.2"
  - "3.3"
  - "3.4"

env:
  global:
    - BOOST_VERSION=1.57.0
  matrix:
    - CC=gcc-4.8 CXX=g++-4.8

before_install:
  # LINUX
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq update; fi
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq install ${CXX}; fi

install:
  # LINUX
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then scripts/install_boost_python.sh; fi
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo ln -s /tmp/boost_${BOOST_VERSION//[.]/_}/boost /usr/local/include/boost; fi
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo ln -s /tmp/boost_${BOOST_VERSION//[.]/_}/stage-python${TRAVIS_PYTHON_VERSION}/lib/* /usr/local/lib/; fi
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo ldconfig; fi

  # OSX
  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install boost-python --with-python3; fi

  - pip install coveralls

script:
  - python3 setup.py build
  - coverage run --source=src setup.py test

after_success:
  - coveralls
  • before_install タスクで g++-4.8 をインストールするのは前回と同じ
  • Linux(Ubuntu)向けのBoostインストール処理は別のシェルスクリプトに切り出した
    • Travis CI の制限により、シェルの実行に sudo を付けることはできない
    • /tmp 配下でビルドを実行し、/usr/local へのリンクは sudo を付けて実行
    • 環境変数 TRAVIS_PYTHON_VERSION で Python のバージョンを取得可能
  • ライブラリをリンクしたら、root 権限での ldconfig 実行が必須
    • これを行わないと boost_python3 ライブラリが not found 状態となり、
      Python 実行時にロードエラーが発生する

ldconfig 実行前に ldd を実行した例。

# ldd ./cmogcore.cpytho-32mu.so
        linux-vdso.so.1 =>  (0x00007fff3b1fd000)
        libboost_python3.so.1.57.0 => not found
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff4ca726000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff4ca50e000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff4ca2f1000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff4c9f32000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff4c9c35000)
        /lib64/ld-linux-x86-64.so.2 (0x00007ff4cac5f000)

 

Boost インストール スクリプト

mog-cli/install_boost_python.sh at master · mogproject/mog-cli

  • sourceforge から対象バージョンの Boost のソースをダウンロードし、/tmp 配下に展開
  • user-config.jam ファイルの作成
    • g++-4.8 をここで指定する
  • bootstrap.sh を実行し、Boost.Python のみをビルド対象とする
    • ここで Python のバージョンを --with-python に指定するのが重要
  • b2 スクリプトを実行
    • 時間短縮のため、threading=single  link=shared のみに限定している
      (フルセットは threading=single,multi  link=shared,static) 
    • 余計なメッセージを抑制するため、-Wno-unused-local-typedefs オプションを追加
    • HomeBrew の boost-python Formula を参考にした
  • /tmp/boost_1_57_0/boost 配下にヘッダーファイルが存在し、
    /tmp/boost_1_57_0/stage-python3.x/lib 配下に共有ライブラリが生成される

 

Related Posts

References

1.25.2015

C++/Python: Travis CI with Boost.Python and Python3

Travis CI で Boost.Python+Python3 のテストを行う

 

やはりネット上にあまり情報がなく、険しい道のりとなってしまったのでここにメモしておく。

.travis.yml

mog-cli/.travis.yml at master · mogproject/mog-cli

---
language: python

os:
  - linux
  - osx

python:
  - "3.2"
#  - "3.3"
#  - "3.4"

env:
  - CC=gcc-4.8 CXX=g++-4.8

before_install:
  # LINUX
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq update; fi
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq install g++-4.8; fi

install:
  # LINUX
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get -qq install libboost-python-dev; fi
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo rm -f /usr/lib/libboost_python.so; fi
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo ln -s libboost_python-py32.so /usr/lib/libboost_python.so; fi
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo rm -f /usr/lib/libboost_python.a; fi
  - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo ln -s libboost_python-py32.a /usr/lib/libboost_python.a; fi

  # OSX
  - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install boost-python --with-python3; fi

  - pip install coveralls

script:
  - coverage run --source=src setup.py test

after_success:
  - coveralls
  • Python 3.2 でのみ動作確認。3.3, 3.4 についてはまだ実現できていない。
  • 環境変数 TRAVIS_OS_NAME を使ってマシンOSによって動作を分岐させる。
    ここでは以下の理由から、ショートサーキット([ "$foo" = "bar" ] && something)を避けた。
    • 正しいYAMLのフォーマットに従うためにクオートまたはエスケープが必要。
    • リターンコードが 0 以外だと処理が止まってしまうので、最初の判定が偽だった場合にリターンコードを 0 で上書きしないといけない。
  • OSX の場合の動作は未検証。
  • before_install のタスクで g++-4.8 をインストール。これは std=c++11 オプションに対応するため。
    環境変数 CC, CXX も併せて定義。
  • install タスクで boost_python ライブラリをインストール。
    Linux (Ubuntu ベース?) の場合、ライブラリはデフォルトで libboost_python-py27.so, libboost_python-27.a にリンクされているので、手動でリンクを張り直す。

 

setup.py

mog-cli/setup.py at master · mogproject/mog-cli

from setuptools import setup, find_packages, Extension
import sys
import platform

SRC_DIR = 'src'


def get_version():
    sys.path[:0] = [SRC_DIR]
    return __import__('mogcli').__version__


source_files = ['src/cmogcore/%s.cpp' % s for s in ['cmogcore']]

if sys.version_info.major == 3 and platform.dist()[0] == 'fedora':
    boost_library = 'boost_python3'
else:
    boost_library = 'boost_python'

setup(
    name='mog-cli',
    version=get_version(),
    description='Command Line Interface for Playing Shogi Games',
    author='mogproject',
    author_email='mogproj@gmail.com',
    url='https://github.com/mogproject/mog-cli',
    install_requires=[
    ],
    tests_require=[
    ],
    package_dir={'': SRC_DIR},
    packages=find_packages(SRC_DIR),
    include_package_data=True,
    test_suite='tests',
    entry_points="""
    [console_scripts]
    mog-cli = mogcli.mogcli:main
    """,
    ext_modules=[
        Extension(
            name='cmogcore',
            sources=source_files,
            include_dirs=['/usr/local/include/boost'],
            library_dirs=['/usr/lib', '/usr/local/lib'],
            libraries=[boost_library],
            extra_compile_args=['-std=c++11', '-pthread', '-Wall'],
            extra_link_args=['-pthread'],
        )
    ],
)
  • プラットフォームによって、ライブラリの名前を boost_python, boost_python3 と使い分ける点だけ注意。

 

 

References

Related Posts

1.18.2015

C++/Python: How to run Boost.Python module using setup.py with Python3.4 on Mac

C++/Python: Mac上の Python3.4 で setup.py を使って Boost.Python を動かす方法

バージョン

  • Mac: OS X Yosemite Version 10.10.1
  • Homebrew: 0.9.5
  • pyenv: 20141211
  • Python: 3.4.2
  • gcc: Apple LLVM version 6.0 (clang-600.0.56)
  • Boost: 1.57

 

環境構築

 

1. Homebrew最新化
$ sudo brew update
2. pyenv環境整理
$ brew install pyenv

.bashrc/.bash_profile/.zshrc などに追記し実行。

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
$ pyenv install 2.7.9
$ pyenv install 3.4.2
$ pyenv global 3.4.2 2.7.9
$ pyenv rehash
$ pyenv versions
  system
* 2.7.9 (set by PYENV_VERSION environment variable)
* 3.4.2 (set by PYENV_VERSION environment variable)
3. boost インストール

そのままインストールすると以下のようなエラーが出る。

$ brew install boost-python --with-python3
(snip)
==> Installing boost-python
==> Downloading https://downloads.sourceforge.net/project/boost/boost/1.57.0/boost_1_57_0.tar.bz2
Already downloaded: /Library/Caches/Homebrew/boost-python-1.57.0.tar.bz2
==> Patching
==> ./bootstrap.sh --prefix=/usr/local/Cellar/boost-python/1.57.0 --libdir=/usr/local/Cellar/boost-python/1.57.0/lib --with-l
==> ./b2 --build-dir=build-python --stagedir=stage-python python=3.4 --prefix=/usr/local/Cellar/boost-python/1.57.0 --libdir=
...skipped <pstage-python/lib>libboost_python3.dylib for lack of <pbuild-python/boost/bin.v2/libs/python/build/darwin-4.2.1/release>libboost_python3.dylib...
...skipped <pstage-python/lib>libboost_python.dylib for lack of <pbuild-python/boost/bin.v2/libs/python/build/darwin-4.2.1/release>libboost_python.dylib...
...failed updating 4 targets...
...skipped 4 targets...
...updated 145 targets...

READ THIS: http://git.io/brew-troubleshooting

Homebrew のログは ~/Library/Logs/Homebrew/boost-python 配下に出ている。
今回のエラーの原因は、python3.4 ライブラリが見つからなかったためのようだ。

$ grep 'not found' ~/Library/Logs/Homebrew/boost-python/02.b2
ld: library not found for -lpython3.4
ld: library not found for -lpython3.4
ld: library not found for -lpython3.4
ld: library not found for -lpython3.4

暫定策として、libpython3.4m.a を参照する libpython3.4.a を作ったら解決した。

$ ln -s ~/.pyenv/versions/3.4.2/lib/libpython3.4m.a ~/.pyenv/versions/3.4.2/lib/libpython3.4.a
$ brew install boost-python --with-python3
==> Downloading https://downloads.sourceforge.net/project/boost/boost/1.57.0/boost_1_57_0.tar.bz2
Already downloaded: /Library/Caches/Homebrew/boost-python-1.57.0.tar.bz2
==> Patching
==> ./bootstrap.sh --prefix=/usr/local/Cellar/boost-python/1.57.0 --libdir=/usr/local/Cellar/boost-python/1.57.0/lib --with-libraries=python -
==> ./b2 --build-dir=build-python --stagedir=stage-python python=3.4 --prefix=/usr/local/Cellar/boost-python/1.57.0 --libdir=/usr/local/Cellar
==> ./bootstrap.sh --prefix=/usr/local/Cellar/boost-python/1.57.0 --libdir=/usr/local/Cellar/boost-python/1.57.0/lib --with-libraries=python -
==> ./b2 --build-dir=build-python3 --stagedir=stage-python3 python=3.4 --prefix=/usr/local/Cellar/boost-python/1.57.0 --libdir=/usr/local/Cell
    /usr/local/Cellar/boost-python/1.57.0: 9 files, 31M, built in 3.3 minutes

ちなみに、system の Python を使うように設定してからインストールすると、今度は python3 が見つからないなどの別のエラーが発生するので注意。

$ pyenv shell system
$ brew install boost-python --with-python3
pyenv: python3: command not found

The `python3' command exists in these Python versions:
  3.4.2
(snip)
==> Downloading https://downloads.sourceforge.net/project/boost/boost/1.57.0/boost_1_57_0.tar.bz2
Already downloaded: /Library/Caches/Homebrew/boost-python-1.57.0.tar.bz2
==> Patching
==> ./bootstrap.sh --prefix=/usr/local/Cellar/boost-python/1.57.0 --libdir=/usr/local/Cellar/boost-python/1.57.0/lib --with-l
==> ./b2 --build-dir=build-python --stagedir=stage-python python=2.7 --prefix=/usr/local/Cellar/boost-python/1.57.0 --libdir=
sh: python3: command not found
sh: python3: command not found
==> ./bootstrap.sh --prefix=/usr/local/Cellar/boost-python/1.57.0 --libdir=/usr/local/Cellar/boost-python/1.57.0/lib --with-l
==> ./b2 --build-dir=build-python3 --stagedir=stage-python3 python= --prefix=/usr/local/Cellar/boost-python/1.57.0 --libdir=/
/private/tmp/boost-python-QMqTxe/boost_1_57_0/tools/build/src/build-system.jam:583: in load from module build-system
(snip)

 

ディレクトリ構造

ファイルの配置は以下のようにした。

.
├── setup.py
├── src
│   └── chello
│       └── chello.cpp
└── tests
    ├── __init__.py        # 空ファイル
    └── chello
        ├── __init__.py    # 空ファイル
        └── test_chello.py

トライ & エラー

最初のバージョンのコードはこのような感じ。

#include <boost/python.hpp>

std::string hello() {
    return "hello world";
}

BOOST_PYTHON_MODULE(hello) {
    using namespace boost::python;
    def("hello", &hello);
}
import unittest
from chello import hello


class TestCHello(unittest.TestCase):
    def test_hello(self):
        self.assertEqual(hello(), 'hello world')
from setuptools import setup, find_packages, Extension


setup(
    name='example-boost-python',
    version='0.0.1',
    description='Example for Boost.Python',
    author='your-name',
    author_email='your-name@example.com',
    url='https://example.com/your-repo',
    install_requires=[],
    tests_require=[],
    package_dir={'': 'src'},
    packages=find_packages('src'),
    include_package_data=True,
    test_suite='tests',
    entry_points='',
    ext_modules=[
        Extension(
            name='chello',
            sources=['src/chello/chello.cpp'],
            include_dirs=['/usr/local/include/boost'],
            library_dirs=['/usr/lib', '/usr/local/lib'],
            libraries=['boost_python3'],
            extra_compile_args=['-std=c++11', '-Wall'],
            extra_link_args=[],
        )
    ],
)

実行すると、ビルドは問題ないが、テスト実行時に以下のエラーを得る。

$ python3 ./setup.py build
(snip)
$ python3 ./setup.py test
(snip)
running build_ext
copying build/lib.macosx-10.10-x86_64-3.4/chello.so -> src
Traceback (most recent call last):
(snip)
AttributeError: 'module' object has no attribute 'test_chello'

手で実行すると、モジュールインポート時のエラーであることがわかる。

$ python
>>> import src.chello
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (PyInit_chello)
モジュールの名前を一致させる

最初の修正は、モジュールの名前を一致させること。hello を chello に修正。

#include <boost/python.hpp>

using namespace std;

std::string hello() {
    return "hello world";
}

BOOST_PYTHON_MODULE(chello) {
      using namespace boost::python;
        def("hello", &hello);
}

すると、今度は異なるエラーを得る。

$ python3 ./setup.py test
running test
running egg_info
writing dependency_links to src/example_boost_python.egg-info/dependency_links.txt
writing top-level names to src/example_boost_python.egg-info/top_level.txt
writing src/example_boost_python.egg-info/PKG-INFO
reading manifest file 'src/example_boost_python.egg-info/SOURCES.txt'
writing manifest file 'src/example_boost_python.egg-info/SOURCES.txt'
running build_ext
copying build/lib.macosx-10.10-x86_64-3.4/chello.so -> src
Fatal Python error: PyThreadState_Get: no current thread
zsh: abort      python3 ./setup.py test

ビルドされたファイルの中身を見る。

$ otool -L ./src/chello.so
./src/chello.so:
        /usr/local/lib/libboost_python.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)

 

pyenv を system に戻して boost を再インストール

色々試行錯誤したが、結局 system の Python を指定した状態で boost (boost-python ではない) をインストールし直したら動作するようになった。

$ pyenv global system
$ brew install python3  # 必要に応じて 
$ brew rm boost
$ brew install boost --build-from-source
$ rm -rf ./build && python3 ./setup.py test
(snip)
clang -Wno-unused-result -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/usr/local/include -I/usr/local/opt/sqlite/include -I/usr/local/include/boost -I/usr/local/Cellar/python3/3.4.2_1/Frameworks/Python.framework/Versions/3.4/include/python3.4m -c src/chello/chello.cpp -o build/temp.macosx-10.10-x86_64-3.4/src/chello/chello.o -std=c++11 -Wall
creating build/lib.macosx-10.10-x86_64-3.4
clang++ -bundle -undefined dynamic_lookup -L/usr/local/lib -L/usr/local/opt/sqlite/lib build/temp.macosx-10.10-x86_64-3.4/src/chello/chello.o -L/usr/lib -L/usr/local/lib -lboost_python3 -o build/lib.macosx-10.10-x86_64-3.4/chello.so
copying build/lib.macosx-10.10-x86_64-3.4/chello.so -> src
test_hello (tests.chello.test_chello.TestCHello) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

この時、動作する環境は system の python3 のみ。
python2 で動かないのはもちろん、pyenv 経由だと先ほどと同じエラーが発生してしまう。

$ python
Python 2.7.9 (default, Jan  7 2015, 11:49:12)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.56)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import src.chello
Traceback (most recent call last):
  File "<stdin>", line 1, in 
ImportError: No module named src.chello
$ python3
Python 3.4.2 (default, Jan  7 2015, 11:54:58)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.56)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import src.chello
>>> src.chello.hello()
'hello world'
$ pyenv global 3.4.2 2.7.9
$ python3
Python 3.4.2 (default, Jan 18 2015, 02:00:19)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.56)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import src.chello
Fatal Python error: PyThreadState_Get: no current thread
zsh: abort      python3

 

コード

まとめ

$ sudo brew update
$ brew [install | upgrade] python3
$ brew install pyenv

$ pyenv shell system
$ brew install boost --from-source
$ brew install boost-python --with-python3

$ python3 ./setup.py build
$ python3 ./setup.py test

Boost.Python を利用するプロジェクトでは、pyenv は system を指定する。

 

References

Related Posts

1.14.2015

C++/Python: Diving Into Boost.Python

Boost.Python ことはじめ

 

Mac環境での動作を目指す。

インストール

Homebrew で簡単にインストールできる……

$ brew install boost

と、思ったら後の手順でリンクエラー。

$ g++ -I`python -c 'from distutils.sysconfig import *; print get_python_inc()'` \
-DPIC -bundle -fPIC -o hello.so hello.cpp -lboost_python -framework Python
ld: library not found for -lboost_python
clang: error: linker command failed with exit code 1 (use -v to see invocation)

boost-python というパッケージに分離していた模様。こちらもインストールする必要があった。

$ brew install boost-python

 

2015-01-18追記: Python3 に対応するためには、インストール時に以下のオプションを付けなければならない。

$ brew install boost-python --with-python3

 

2015-01-18追記2: pyenv を使っている場合は、global な Python を使用するように設定した状態でインストールしないとエラーになる。

$ pyenv global system
$ pyenv rehash
$ pyenv versions

 

コード例

boost のおかげで、とてもスッキリとしたコードになる。

#include <boost/python.hpp>
#include <iostream>

using namespace std;

void hello() {
  cout << "hello world" << endl;
}

BOOST_PYTHON_MODULE(hello) {
  using namespace boost::python;
  def("hello", &hello);
}

 

ビルド

hello.cpp から hello.so を作る。

$ g++ -I`python -c 'from distutils.sysconfig import *; print get_python_inc()'` \
-DPIC -bundle -fPIC -o hello.so hello.cpp -lboost_python -framework Python

 

動作確認

REPL で動かしてみる。

>>> import hello
>>> hello.hello()
hello world
>>>

本当に簡単だった。

 

References

1.12.2015

Python: Printing Progress Bar with 'threading' Module

Python: threading モジュールを使ってプログレスバーを表示する

 

目的

Python コード中に、実行に時間のかかる処理がある。

処理がハングアップしていないことを知らせるため、1秒おきに『.』を画面に出力したい。

 

コード

プログレスバーと実処理は別のスレッドまたはプロセスで実行しなければならない。

threading モジュールを利用して実装してみた。

 

実行例

import time

print('start')
with ProgressBar():
    time.sleep(3)
print('end')

出力例は以下

start
...
end

 

テストコード

 

 

References

1.11.2015

pep8: Extending Max Line Length

pep8: 行あたりの最大文字数の拡張

 

pep8 を流した時、E501がうるさい。

$ pep8 src tests
tests/test_xxx.py:30:80: E501 line too long (112 > 79 characters)
...

--max-line-length オプションを使えばスッキリ。

$ pep8 --max-line-length 120 src tests

~/.config/pep8 ファイルにあらかじめ書いておけば、オプション指定を省略できるので便利。

[pep8]
max-line-length = 120

 

 

References

1.07.2015

artifact-cli - Private Artifact Manager

artifact-cli - プライベートなアーティファクト管理ツール

 

モチベーション

  • 元々は Scala の all-in-one バイナリの世代管理が目的
    • play dist とか sbt one-jar とか sbt assembly で作られる 1個の zip/jar ファイルが対象
    • ゴールはデプロイ/リカバリ運用の可視化と効率化
  • リッチなデータベースに依存せず、極力シンプルな、どこでもすぐに使えるツール
    • Artifactory のようなツールで実現可能なのかもしれないが未調査
  • Amazon S3 をデータストアとして使いたい

 

コード

Python で書いた。

PyPI にも登録済み。

 

インストール

  • Python 2.6/2.7 で動作確認済み
  • Python のパッケージ管理ツール pip が未導入であれば、まずインストール
  • 以下のコマンドを実行すれば、art コマンドが利用可能となる
    pip install artifact-cli
    環境によっては sudo を付ける必要あり。アップグレードは --upgrade オプションを付ければOK。

 

セットアップ

 

AWS 環境の準備 (必須)

手順の詳細は割愛。

  • AWS アカウント作成
  • 適切な権限を持った IAM ユーザの作成と API アクセスキー・シークレットキーの取得
  • Amazon S3 バケット作成

 

設定ファイルの記述 (任意)

設定ファイルのデフォルトパスは ~/.artifact-cli。以下は記述例。

[default]
aws_access_key_id = XXXXXXXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
bucket = your-bucket-name
region = your-region (e.g. ap-northeast-1, us-east-1)

 

使用例

 

バージョン確認
$ art --version
artifact-cli 0.0.5

 

ヘルプ表示
$ art -h
Usage:
  art [options] list     GROUP
  art [options] upload   GROUP LOCAL_PATH
  art [options] download GROUP LOCAL_PATH [REVISION | latest]
  art [options] info     GROUP FILE_NAME  [REVISION | latest]
  art [options] delete   GROUP FILE_NAME   REVISION

  e.g.
   GROUP     : your.company
   LOCAL_PATH: /path/to/awesome/target/scala-2.11/awesome-assembly-1.2.3.jar
   FILE_NAME : awesome-assembly-1.2.3.jar
   REVISION  : 10

Options:
  --version            show program's version number and exit
  -h, --help           show this help message and exit
  --config=CONFIG      path to the config file
  --check              prints only the information to upload, download or
                       delete
  --force              upload file even when it is already registered to the
                       repository
  --output=OUTPUT      specify output format, "text" or "json" (default: text)
  --access=ACCESS_KEY  AWS access key id
  --secret=SECRET_KEY  AWS secret access key
  --bucket=BUCKET      Amazon S3 bucket name
  --region=REGION      Amazon S3 region name (default: us-east-1)

 

ビルド済みアーティファクトのアップロード
$ art upload your-group-id /path/to/your/project/target/scala-2.11/your-project-assembly-0.1.0-SNAPSHOT.jar
[INFO] Reading index: s3://bucket-name/your-group-id/artifact-cli-index.json
[INFO] Uploading artifact:
Basic Info:
  Group ID   : your-group-id
  Artifact ID: your-project-assembly
  Version    : 0.1.0-SNAPSHOT
  Packaging  : jar
  Revision   : 1
File Info:
  User    : user@hostname
  Modified: 2014-11-19 02:57:50
  Size    : 29689482 (28.3MiB)
  MD5     : 1afdc6c1b7aaad744a72696c33bd55eb
Git Info:
  Branch             : master
  Tags               : release_xxxxxx
  Last Commit Author : Your Name <mail@example.com>
  Last Commit Date   : 2014-12-03 22:15:09
  Last Commit Summary: implement awesome feature
  Last Commit SHA    : 825637d5dfe119ef624cc9b02b027d9cf9aa1a33

[INFO] Uploading file: s3://bucket-name/your-group-id/your-project-assembly/0.1.0-SNAPSHOT/1/your-project-assembly-0.1.0-SNAPSHOT.jar
[INFO] Writing index: s3://bucket-name/your-group-id/artifact-cli-index.json

任意の「グループID」(文字列)の指定が必要。
ファイルのパスを指定するだけで Git の情報も自動的に収集。
リビジョン番号は 1から順に自動採番。

 

アーティファクト一覧表示
$ art list your-group-id
FILE                                         #    SIZE      BUILD                 TAGS             SUMMARY
------------------------------------------------------------------------------------------------------------------------------
your-project-assembly-0.1.0-SNAPSHOT.jar      1   28.3MiB   2014-11-19 02:57:50   release_xxxxxx   implement awesome feature

 

最新版アーティファクトのダウンロード
$ art download your-group-id /tmp/your-project-assembly-0.1.0-SNAPSHOT.jar latest
[INFO] Reading index: s3://bucket-name/your-group-id/artifact-cli-index.json
[INFO] Downloading artifact:
Basic Info:
  Group ID   : your-group-id
  Artifact ID: your-project-assembly
  Version    : 0.1.0-SNAPSHOT
  Packaging  : jar
  Revision   : 1
File Info:
  User    : user@hostname
  Modified: 2014-11-19 02:57:50
  Size    : 29689482 (28.3MiB)
  MD5     : 1afdc6c1b7aaad744a72696c33bd55eb
Git Info:
  Branch             : master
  Tags               : release_xxxxxx
  Last Commit Author : Your Name <mail@example.com>
  Last Commit Date   : 2014-12-03 22:15:09
  Last Commit Summary: implement awesome feature
  Last Commit SHA    : 825637d5dfe119ef624cc9b02b027d9cf9aa1a33

[INFO] Downloaded: /tmp/your-project-assembly-0.1.0-SNAPSHOT.jar

 

CI 関連

カバレッジ 100% は気持ちいい。