既存リポジトリを取り込むとき、リポジトリ名に大文字小文字がある場合にGitlabは勝手にに大文字も小文字にしてしまう。
これは困ったと思っていたら、実は直す方法が書いてあった。
Allow camelCase / PascalCase repo names
Settings→Rename repositoryで好きな名称に変更出来る。(ただし、危険な変更ではある旨が書いてあるので念のため、実行前にはリポジトリのバックアップなどしておくと良いと思います。)
既存リポジトリを取り込むとき、リポジトリ名に大文字小文字がある場合にGitlabは勝手にに大文字も小文字にしてしまう。
これは困ったと思っていたら、実は直す方法が書いてあった。
Allow camelCase / PascalCase repo names
Settings→Rename repositoryで好きな名称に変更出来る。(ただし、危険な変更ではある旨が書いてあるので念のため、実行前にはリポジトリのバックアップなどしておくと良いと思います。)
仕事で過去のリビジョンに戻る方法はどうすれば良いのか?という質問があったのだが、git checkoutとgit reset –hardを使う場合の違いについてよく分かってなかったので調べてみた。
既に記載の通り、2つやり方がある。
$git checkout <commit>
もしくは
$git reset --hard <commit>
である。
ただし、二つは大きな違いがある。
指定されたコミットIDのリビジョンに作業ディレクトリ内のファイルが変更される。ブランチは detached HEAD状態となり、この状態ではコミットなどを行ってもリポジトリに保存されない。(厳密には少し違うが) つまり、read only状態で指定リビジョンの状態確認が出来る。
元のブランチに戻る場合、以下のように元々のブランチ名を指定すれば良い。
$git checkout master
基本的にread onlyであるが、別途ブランチを作成する事で、リポジトリへの追記も可能。
現在のブランチのまま、指定されたリビジョンに作業ディレクトリ、ステージング環境、HEADが変わる。もし作業ディレクトリに編集中のファイルがあったという場合にもその情報は失われてしまうので、実行の際には注意が必要。
また、元々のHEADの状態に戻る場合、git reflogを使うかORGI_HEADを使う必要がある。
$git reset --hard ORIG_HEAD
もしくは
$git reflog
$git reset --hard <commit>
大半の場合、checkoutによる操作で事足りそう。そして、checkoutの方が安全。
detached HEAD状態から元に戻すコマンド (git, checkout, fix a detached HEAD, .git/HEAD, refs/heads/master)
masterブランチのリモートリポジトリで行われた変更のみをdevブランチに反映したい。 ただし、masterブランチでのローカルで行われたコミット内容はdevブランチに反映したくない。
$git fetch $git checkout dev $git merge origin/master
fetchでorigin/masterリモートブランチを最新化し、devブランチにorigin/masterをmergeする。
本作業と同時にmasterブランチにリモートリブランチ(origin/master)のコミットを反映しても良い場合には以下でもOK。
$git pull $git checkout dev $git merge origin/master
git pullはgit fetchとgit mergeを実行するので、上記だとmasterブランチも変更される。 単純にやりたいことだけやるのであれば、git fetchの方が合っていると思われる。
追記(11/23) トピックブランチにマスターの変更を反映することを2回以上行うと大量のコンフリクトが発生する。
gitで双方向にmergeしているとひどいはまり方をすることがある件
上記より、トピックブランチへマスターの変更を反映するのはマスターへマージする直前のみとし、それ以外の場合にはマスターからブランチを再作成し、cherry-pickなどを利用するのが良いと思われる。
$git pull $git checkout dev $git merge master
これを実行するとローカルのコミットもdevブランチに反映されてしまうのでNG。
最近のAndroid開発環境はAndroidStudioがデファクトスタンダードっぽいのですが、関わっているプロジェクトがNDKを利用しており、まだAndroidStudioでは未対応なので、Eclipseを使っております。
そんなプロジェクトなのですが、Robolectricを使ってテストしており、Jenkinsで実行させる為にコマンドラインで実行するまでにした事をメモしておきます。
Antでやる方法もあると思うのですが、Gradleだとそれ用のプラグインがあるのでGradleを使いました。
とりあえず使える状態のサンプルをGithubにおいてあります。
READMEに書いてあるような状態であれば以下で実行出来るかと思います。
$gradle clean test
以下の公式サイトに丁寧に記載があるのでこちらを参照。
Eclipseから簡単にGradleでビルドする時に必要なファイルを出力する事が出来るので、利用します。Eclipseを起動し、以下で完了です。
File→Export→Android→Generate Gradle build files
完了すると色々ファイルが出来ていると思うので、バージョン管理に登録しておきます。
AndroidSDKをサーバーにインストールします。自分の場合、Linuxだったので対応するSDKをダウンロードして、後は自分のビルドしたいAndoridバージョンのSDKをインストールしておきます。
この時、 AndroidSDK Build-toolsとAndroid Support Repositoryもインストールしておいてください。
AndoridSDK Build-toolsはGradleのビルド時にバージョンの指定が必要なので、インストールしたバージョンも確認しておいて下さい。
なお、CUIでAndoridSDKなどのインストール方法はこちらを参照。
サーバーにGradleをインストールしますが、普通にインストールするとGradleのバージョン切り替えが面倒なのでGVMを使います。
インストールします。
$curl -s get.gvmtool.net | bash
現在、利用可能なGradleのバージョンを確認します。
$gvm list gradle
1.12をインストールして利用します。(Androidをビルドするためのプラグインが1.1x系を要求するため)
$gvm install gradle 1.12 $gvm use gradle 1.12
GradleのAndroidプラグインにて環境変数のANDROID_HOMEを指定する必要があるので、設定します。
$vi ~/.bashrc
追加します。
# Andorid_HOME $export ANDROID_HOME=/Applications/adt-bundle-mac-x86_64-20140624/sdk/
適用させます。
$source ~/.bashrc
Jenkinsで実行する場合、Jenkinsの環境変数を設定する箇所で上記を設定してください。
Eclipseでプロジェクトを新規作成するとappcompat_v7とかもコンパイルしなければいけなかったり、lib配下にandroid-support-v4.jarとかが存在します。
Eclipseでビルドする時は良いのですが、サーバーでビルドする時に上記も用意したりするのは面倒なので、Gradleを使って依存を解決します。
という事で作成されたbuild.gradleを一部編集します。 自分の場合、以下のようにしました。
// Gradle自身の環境を設定 buildscript { // mavenCentralリポジトリを利用する repositories { mavenCentral() } // 利用するGradleプラグインは0.13を利用 dependencies { classpath 'com.android.tools.build:gradle:0.13.0' } } // すべてでmavenCentralのリポジトリを追加 allprojects { repositories { mavenCentral() } } apply plugin: 'android' dependencies { compile fileTree(dir: 'libs', include: '*.jar') // 削除。下記のように記載することでGradleより取得 //compile project(':appcompat_v7') // 追加。Gradleによってappcompatの依存関係を解決。 // excludeの記述によってlib配下のsupport-v4との競合を避ける。 compile ('com.android.support:appcompat-v7:18.0+') { exclude module: 'support-v4' } } android { compileSdkVersion 20 buildToolsVersion "20.0.0" compileOptions { sourceCompatibility JavaVersion.VERSION_1_7 targetCompatibility JavaVersion.VERSION_1_7 } sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } // Move the tests to tests/java, tests/res, etc... instrumentTest.setRoot('tests') // Move the build types to build-types/<type> // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ... // This moves them out of them default location under src/<type>/... which would // conflict with src/ being used by the main source set. // Adding new build types or product flavors should be accompanied // by a similar customization. debug.setRoot('build-types/debug') release.setRoot('build-types/release') } }
変更点は以下の通りです。
buildscriptと記述されている場所はGradle自身の依存関係や利用するプラグインの情報を指定します。 今回の指定では以下2点を指定しています。
allprojectsと記述されている場所では以下を指定しています。
depnedenciesでは以下を指定、変更しました。
1点目のappcompatについてですが、Eclipseだとプロジェクトを追加した時にappcompat_v7も一緒に作成されて、ビルドが必要となります。ただし、サーバーでは面倒なので、この役目はGradleに任せる事としてコメントアウトしています。
2点目は1点目でコメントアウトしたappcompatについてGradleで依存解決する為の記述です。コンパイルする時にこのプロジェクトはappcompat-v7:18以上に依存しているよという事を記述しています。
3点目ではsupport-v4に関しての依存部分は解決しなくてよい、という事を指定しています。Gradleで依存解決を行う時は対象のものが依存しているものも一緒に依存解決しようとします。 試しにexcludeを消して、gradle dependenciesというコマンドをタイプして各ライブラリの依存関係を表示します。
$gradle dependencies ・・・・ _debugCompile - ## Internal use, do not manually configure ## \--- com.android.support:appcompat-v7:18.0+ -> 18.0.0 \--- com.android.support:support-v4:18.0.0
上記のようにappcompat-v7:18はsupport-v4に依存している事が分かります。
依存解決は通常ありがたいことなのですが、今回作成したプロジェクトではlibsフォルダ配下に既にsupport-v4が存在しています。そのため、excludeしないとビルドエラーとなってしまいます。(Multiple dex files define Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompatとか出ます。)
libs配下のsupport-v4を削除するとEclipseのビルドができなくなってしまいますので、今回は上記のように書いてありますが、Gradleでのビルド前提の場合にはGradleで依存解決は解決する方が妥当だと思います。
まず、自分がビルドしたいAndoridプロジェクトをサーバーに任意の場所にcloneします。
そして、build.gradleがある場所(対象のAndroidプロジェクトのRoot)に移動します。
そこで、build.gradleを開き、buildToolsVersionがサーバーでインストールしたバージョンと合っているか確認して下さい。もし、違う場合にはエラーとなるので、書き換えてください。
ANDROID_BUILD_TOOLSというような変数にしておいて、gradle.propertiesなどに設定しておく方法がおすすめです。
さて、ビルドしてみます。
$gradle build
もし、特にエラーがなければ、build/outputs/apk配下にapkが作成されているはずです。
buidl.gradleを編集してRobolectricでテスト出来るようにします。
各変更点は後述しますが、全体で以下のようになりました。
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.13.0' classpath 'org.robolectric:robolectric-gradle-plugin:0.13.0' } } allprojects { repositories { mavenCentral() } } apply plugin: 'android' apply plugin: 'robolectric' android { compileSdkVersion 17 buildToolsVersion "20.0.0" sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aidl.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } androidTest { setRoot('test') } // Move the tests to tests/java, tests/res, etc... //instrumentTest.setRoot('tests') // Move the build types to build-types/<type> // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ... // This moves them out of them default location under src/<type>/... which would // conflict with src/ being used by the main source set. // Adding new build types or product flavors should be accompanied // by a similar customization. debug.setRoot('build-types/debug') //release.setRoot('build-types/release') } } robolectric { include '**/*Test.class' } dependencies { compile fileTree(dir: 'libs', include: '*.jar') compile ('com.android.support:appcompat-v7:18.0+') { exclude module: 'support-v4' } // test androidTestCompile('junit:junit:4.11') androidTestCompile('org.robolectric:robolectric:2.3') }
変更点は以下の通りです。
自分がこの中でも特にはまったのがテストフォルダの位置を指定する箇所です。
これについてなのですが、robolectric-gradle-plugin:0.12.0までは本設定をしてもまったく有効化せず、必ずsrc/test/java配下にファイルを配置しないといけませんでした。
ただ、0.13からは任意のディレクトリの指定が可能となりました。ただし、必ず指定したディレクトリ配下にjavaというフォルダがある必要はありますので、注意が必要です。
早速やってみます。
$gradle clean test
gradle1.12では下記エラーになってしまいます。。。
* What went wrong: A problem occurred evaluating root project 'RobolectricGradleSample'. > Could not create plugin of type 'AppPlugin'.
ただし、Gradle2.1ではうまくできます。
$gvm install gradle 2.1 $gvm use gradle 2.1 $gradle clean test
こんな感じで結果がbuild/test-report/index.htmlに出力されています。
また、build/test-result/にXMLも出力されるのでこれを利用してJenkinsで実行結果のグラフ表示も可能です。
RobolectricのPluginが1.x系に対応してないからなのでしょうか。。。ちょっといまいち理由が分かっていません。知っている人がいらっしゃったら教えて頂けるとありがたいです。