読者です 読者をやめる 読者になる 読者になる

【GAE/Go】 'ImportError: cannot import name goroots' の対処

こんにちは。

GAE/Go開発している最中にふとappengine sdkのアップデートをしました。

$ gcloud components update

 これでappengine sdk含め諸々のアップデートがなされたわけですが、この直後から goapp コマンドでエラーが出るようになりました。

➜  goapp
Traceback (most recent call last):
  File "/Users/shimbaroid/google-cloud-sdk/platform/google_appengine/goapp", line 13, in <module>
    from google.appengine.tools import goroots
ImportError: cannot import name goroots

gorootsなるパッケージのimportに失敗しているようです。

このスクリプト(goapp)、pythonで書かれているので「pythonのパッケージいれればいいのかな」なんて思いましたが面倒くさそうなので避けました。pythonやったことないワカンナイ。

今回インストールされたappengineのバージョンは1.9.53でした。アップデート前のバージョンはわからないです…

➜  goapp version
go version 1.6.3 (appengine-1.9.53) darwin/amd64

対処

件のgorootsは$GOROOTを取得するためのもののようですが、別のマシンに入っている古いバージョンのgoappを確認したところ、gorootsを使わずに$GOROOTを取得していました。

これに倣って手元のマシンのgoappを書き換えてしまいます。

- from google.appengine.tools import goroots

SDK_BASE = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
- GOROOT = os.path.join(SDK_BASE, goroots.GOROOTS['go1'])
+ GOROOT = os.path.join(SDK_BASE, 'goroot')

古いマシンのappengineのバージョンは1.9.50でした。

以上です

google cloud sdkのインストールのときもinstall.sh書き直してたな…

【Ubuntu】自宅のマシンにssh接続して開発するためのセットアップメモ

自宅マシンに外出先からssh接続して開発を行おうと思い、サーバ・クライアントをセットアップしました。

LAN内でクライアントからサーバにssh接続するまでのメモです。WANから自宅LANにつなぐための、ルータやDNSの設定等の話はしていません。

参考にした記事は最後にまとめて記載しております。

想定環境

セットアップ

クライアントとサーバを行ったり来たりしながら解説します

1. apt-get update (サーバ

sudo apt-get update

2. sshのインストール (サーバ

sudo apt-get install openssh-server

3. sshキーの生成 (クライアント

ssh-keygen

エンターキー3連打

4. 公開鍵をサーバに送る (クライアント

scpを利用してファイルを送信 scp ~/.ssh/id_rsa.pub user@192.168.11.2:~

user@192.168.11.2の部分は手元の環境に合わせて置き換える。

5. 送られてきた公開鍵をauthorized_keysに登録する (サーバ

もし~/.sshが存在していなかったら mkdir ~/.ssh

authorized_keysファイルをつくる touch ~/.ssh/authorized_keys

authorized_keysに公開鍵を追記 cat ~/id_rsa.pub >> ~/.ssh/authorized_keys

6. sshd_configの設定 (サーバ

必要に応じてアクセス権の変更 sudo chmod a+w /etc/ssh/sshd_config

sshd_configを編集 vi /etc/ssh/sshd_config

Port XXXXX # ポートを22以外に変更
PermitRootLogin no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no
ChallengeResponseAuthentication no

sshdの再起動 sudo /etc/init.d/ssh restart

7. クライアントからサーバへ接続できるか確認 (クライアント

sshd_configに設定したPortが44444であれば ssh -p 44444 user@192.168.11.2

接続できなかった場合、サーバ側でauthorized_keysにちゃんと公開鍵が追記されているかとsshd_configに間違いがないかを確認。sshd_configを修正する場合はsshdの再起動を忘れない。

以上

「自宅に開発マシンおいて外から繋いで開発すれば、マシンも作業場所も選ばないじゃーん」とおもってセットアップしたんですが、wi-fiの具合に超依存します。テザリングなんかじゃ快適とは程遠いやい。

その他ファイアーウォール等セキュリティの設定がありますが、今回はここまで。


参考

SCPコマンドでローカルのファイルをサーバにアップ&サーバ上のファイルをDL

そこそこセキュアなlinuxサーバーを作るLinux

サーバに新たなSSH公開鍵を追加する

【Haskell】Stringの連結でハマった

ここ数日、「すごいHaskell楽しく学ぼう!」でHaskellしてます。関数型プログラミングを勉強してみたかった。

第4章を少し進めて再帰の考え方がわかってきたため、復習としてFizzBuzzを。

fizzbuzz :: Int -> [String]
fizzbuzz n | n < 1 = []
fizzbuzz n = fizzbuzz (n-1) ++ [(fb n)]
    where fb n
            | n `mod` 15 == 0 = "FizzBuzz"
            | n `mod` 3 == 0 = "Fizz"
            | n `mod` 5 == 0 = "Buzz"
            | otherwise = show n

Intを引数にとり、1から引数で指定した数までをFizzBuzzします。

引数nを関数fbでFizzBuzz文字へ変換し、その先頭へ再帰でまたFizzBuzz文字をつなげています。

本題ですが、3行目のリストの連結で2時間ほどハマっていました。

リストの連結には2つ方法がある

リストの連結には2つの方法があります。 : を使う方法と ++ を使う方法です。

Prelude> let x = [3,5,7]
Prelude> x ++ [5, 3]
[3,5,7,5,3]

Prelude> 5 : x
[5,3,5,7]
Prelude> 7 : 5 : x
[7,5,3,5,7]
Prelude>

これだけでは違いがわかりにくいですね。

これではどうでしょう。

Prelude> [5,3] ++ x
[5,3,3,5,7]
Prelude> x : 5

<interactive>:31:1: error:
    • Non type-variable argument in the constraint: Num [[t]]
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        it :: forall t. (Num [[t]], Num t) => [[t]]
Prelude> x : 5 : 3

<interactive>:32:1: error:
    • Non type-variable argument in the constraint: Num [[t]]
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        it :: forall t. (Num [[t]], Num [t], Num t) => [[t]]
Prelude>

++演算子は2つの値を入れ替えても動作します。

一方 : 演算子はエラーが発生しました。

演算子の定義を確認してみましょう。

Prelude> :t (++)
(++) :: [a] -> [a] -> [a]

Prelude> :t (:)
(:) :: a -> [a] -> [a]

つまり、

  • ++演算子は「2つのリストを連結する」
  • : 演算子は「後者のリストの先頭に前者を追加する」

というように考えられます。似ているようで似てなかった。

FizzBuzz書いているときは当該の行を

fizzbuzz n = (fizzbuzz (n-1)) : (fb n)

としておりました。エラーメッセージでも型の齟齬が吐かれていましたが、少しややこしいものでした。

キョウリョクナカタスイロン

先程の一行を型に注目するとこうなります。

fizzbuzz n = [String] : String

またエラーメッセージではこの行について

  • 「(fizzbuzz (n-1))の返り値の型、[[String] ]になってんぞ。[String]じゃね?」

  • 「(fb n)の返り値の型、[Char]になってんぞ。[[String] ]じゃね?」

と、強力な型推論のおかげ(せい)で余計に惑わされました。

以上です。

まとめ

haskellを触り始めて1日目、エラーにハマったおかげでかえって満足です。エラーメッセージとがっつり対峙できたため今後はスルスルと進めていきたいですね。カモン、デバッグりょく

【Retrofit2】jsonschema2pojoがUnexpected character was〜する

pojo変換用のclassをjsonschema2pojoにレスポンスをコピペして作るわけですが、ぼくの環境だとどうも

There's a problem: Unexpected character ('m' (code 109)): was expecting double-quote to start field name (line 2, column 2)

f:id:shimbaroid:20160818234319p:plain

とエラーが出てしまいます。フィールドにあたる文字のクォーテーションが無いぞとのことです。

これは、GoogleChromeのJSONViewという拡張機能が原因でした。

この拡張機能jsonのレスポンスを整形してchrome上で見やすくしてくれるものですが、フィールドにあたる文字のクォーテーションを外してしまいます。そのために上記のエラーが発生していました。

じゃあコピペのあとにキーひとつずつにクォーテーションをつければいいわけですが、ぼくはこのときだけSafariを使っています。生のjsonならpojo classを生成できます。

ありがとうございました。

【Android Studio】Api keyを始めとしたgit管理したくない定数を環境変数で管理する

Api keyやGoogle AnalyticsのトラッキングIDなんかは、ハードコーディングしてgithub等でオープンにするのが好ましくないですよね。

そこでOS X環境変数にそれらを登録しておき、Android Studioのビルドの際に参照するようにして回避しましょう。

OS X環境変数にkeyを登録する

ターミナルから以下を実行します。

$ launchctl setenv APIKEY hogehoge

APIKEYがkey、hogehogeがvalueにあたるKeyValue形式です。

build.gradleから環境変数を参照する

buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

        // 環境変数を参照する
        manifestPlaceholders = [api_key: System.getenv("APIKEY")]
    }
}

環境変数のAPIKEYを参照し、api_keyへ格納しています。

AndroidManifest.xmlからmanifestPlaceholdersを参照する

<application>
    <meta-data android:name="apiKey" android:value="${api_key}"/>
</application>

javaプログラムの中からAndroidManifest.xmlのmeta-dataを参照する

String key = "";
try{
    ApplicationInfo info
            = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
    key = info.metaData.getString("apiKey");
}catch(PackageManager.NameNotFoundException e){
    e.printStackTrace();
}

// keyを使った処理〜〜

これでString keyはhogehogeになっています。

Windowsから環境変数を登録し参照することは検証していないです。

ありがとうございました。

参考

AndroidManifest.xmlにAPIキーを書いたコードをGitHubにコミットしないために AndroidManifest.xmlに記述したメタデータを取得する

【Jenkins】Ubuntu16.04にjenkinsをインストールする

多くがQiitaや他の技術ブログのコピペになってしまいますが、Ubuntu16.04にセットアップした話は見かけなかったのでここに残します。

JDKのインストール

$sudo add-apt-repository ppa:webupd8team/java
$sudo apt-get update
$sudo apt-get install oracle-java7-installer

Jenkinsのインストール

$wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -
$sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list'
$sudo apt-get update
$sudo apt-get install jenkins

nginxのインストール

$sudo apt-get install nginx

nginxのリバースプロキシの設定

$gedit /etc/nginx/sites/available/default

で設定ファイルを開き、以下のように編集。(保存ができない場合、下記参照)

server {
    listen 80 default_server;
    listen [::]:80 default_server ipv6only=on;

    root /usr/share/nginx/html;
    index index.html index.htm;

    # Make site accessible from http://localhost/
    server_name localhost;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;

        if (!-f $request_filename) {
            proxy_pass http://localhost:8080;
            break;
        }
    }
}

※保存ができない場合、以下のコマンドで権限を変更してから再度編集。

$sudo chmod a+w /etc/nginx/sites-available/default


nginxを再起動

$sudo service nginx restart

これでブラウザから http://localhost/にアクセスするとjenkinsが起動していることが確認できます。 f:id:shimbaroid:20160624164949p:plain

初回はパスワードを求められます。赤字でハイライトされているpathのinitialAdminPasswordのなかに記述されています。これを確認します。

initialAdminPasswordを確認する

$sudo chmod a+r+x /var/lib/jenkins/secrets
$sudo chmod a+r+x /var/lib/jenkins/secrets/initialAdminPassword
$cat /var/lib/jenkins/secrets/initialAdminPassword


これで表示された英数字列を先ほどのブラウザ画面にコピペしてContinueを押します。 f:id:shimbaroid:20160624171121p:plain

pluginのインストールですが、Install suggested pluginsで問題ないかと思います。

インストール完了!

f:id:shimbaroid:20160624171520p:plain

Jenkinsのインストールが完了しました。今回は以上です。

参考

UbuntuにJenkinsをインストールする

【Android】EspressoでUIテストの準備

build.gradleに以下を追記

// defaultConfig 
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

// dependencies
androidTestCompile 'com.android.support.test:runner:0.3'
androidTestCompile 'com.android.support.test:rules:0.3'
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2' 
androidTestCompile 'com.android.support:support-annotations:23.2.1'

support-annotationの一行は適宜バージョンを変更する。gradleのエラーにでるバージョンに指定すれば問題ない。

 

テストクラス(e.g. MainActivityTest.java)頭に@RunWith()を追記

@RunWith(AndroidJUnit4.class)
public class MainActivityTest extends ActivityInstrumentationTestCase2{
.
.
.

あとはテストを書いていく。