unrealMan’s blog

IT関連の奮闘記を備忘録がてら記載していきます!

【Gitlab】コマンドで簡単操作、labコマンドを使ってみた【大奮闘】

GitbashでGitlabをコマンド操作

labコマンドとは?

GitLabのCLIクラアントとして以下に紹介されています。
コマンドラインからGitlabへのissueのopen/close、マージリクエストやブラウザ遷移など。
Webブラウザ上の操作をコマンドで操作できちゃいます。
fzfなどのワンライナーツールと組み合わせると超効率が実現できそうです。
about.gitlab.com


今回使うのはこれ!
github.com


ただlabコマンドを使っている人が少ないのか情報がほとんどない。。
とりあえず↟のREADMEをみながら進めてみた。
環境はWindows10で、愛用のGitbashを使用していきます。

labコマンドのインストール

bashのインストール手順通りに進めますが、いきなり躓きます。

unrealman@DESKTOP-XXXXX MINGW64 ~
$ curl -s https://raw.githubusercontent.com/zaquestion/lab/master/install.sh | sudo bash
bash: sudo: command not found
(23) Failed writing body

Gitbashにはsudoコマンドがありません。
sudoを省きます。

unrealman@DESKTOP-XXXXX MINGW64 ~
$ curl -s https://raw.githubusercontent.com/zaquestion/lab/master/install.sh | bash
OS not supported

「OS not supported」
OSがサポートされていないと出てきました。。
これ終わりじゃ、、と思いましたが諦めません。

WindowsPowerShellからパッケージ管理ツール「Scoop」を使えばインストールする手順があります。

パッケージ管理「Scoop」をインストールする

PowerShellを開き以下のコマンドを実行します。

Set-ExecutionPolicy RemoteSigned -scope CurrentUser; iex (new-object net.webclient).downloadstring('https://get.scoop.sh')
labコマンドをインストールする

PowerShellではなくGitbashを使いたいのです。
WSLでもよいのですが、WSLだとCLIからブラウジングができないのです(検証済み)。
(WSLからブラウザの制御が難しい模様、できなくはないのだろうが骨が折れそうです。。)

Gitbahを開き、以下のコマンドを実行します。

scoop bucket add zaquestion https://github.com/zaquestion/scoop-bucket.git
scoop install lab

インストール完了!

labコマンドの実行

さっそく実行してみます。

$ lab
Enter GitLab host (default: https://gitlab.com):
Create a token here: https://gitlab.com/profile/personal_access_tokens
Enter default GitLab token (scope: api): 2019/12/04 22:45:11 main.go:68: The handle is invalid.

はい失敗しました。
labコマンドを構成しているgo言語ファイルでエラーをはいています。

おそらくこれが原因じゃなかろうかと、minttyのwindowsラッパーのwinptyを付けてみます。

$ winpty lab
Enter GitLab host (default: https://gitlab.com):
Create a token here: https://gitlab.com/profile/personal_access_tokens
Enter default GitLab token (scope: api):

いけました!

Gitlabでパーソナルアクセストークンを発行

labコマンドを入力し、Enterを押下するとトークンを作るURLが表示されるのでブラウザで開きます。
これ

Create a token here: https://gitlab.com/profile/personal_access_tokens

f:id:unrealman:20191206023849p:plain

名前(トークンの名前)とScopes(有効範囲とアクセスレベル)を設定します。
f:id:unrealman:20191206024014p:plain
今回は
Scopesはapi(完全な権限)
Expiers atは未入力(有効期限が無期限)とします。
入力したら、Create personal access tokenを押下します。
f:id:unrealman:20191206024031p:plain
パーソナルアクセストークンが発行されました。


先ほどのコマンドラインで生成されたアクセストークンを入力しEnterを押下します。

コマンド操作してみる

ちゃんと動いています。
以下はプロジェクトのリスト表示コマンド

$ lab project list
leberwurscht/teardownwalls
technomancy/leiningen
jonan/heroes-of-wesnoth
jonan/k
hcs/hcs_utils
soeren/sspssptest

cloneしたプロジェクトは以下で以下のコマンドを打つとブラウザ表示します。素晴らしいです。
$ lab project browse

f:id:unrealman:20191206024059p:plain

しかし、うまくいったと思ったのも束の間。

issueもマージリクエストも作成できない

また、エラーです。viの実行可能ファイルがPATHにないと言っています。

$ lab issue create
2019/12/06 02:13:27 issue_create.go:55: /home/travis/gopath/src/github.com/zaquestion/lab/cmd/issue_create.go:54 exec: "vi": executable file not found in %PATH%

しかし、viはパス通っています。認識しています。

$ vi

f:id:unrealman:20191206024240p:plain

念の為確認しますが、やっぱり通っています。

$ echo $PATH
(省略):/usr/local/bin:/usr/bin:(省略)

ここにちゃんといます。

$ ll /usr/bin/vi
-rwxr-xr-x 1 unrealman 197609 25 10月 21 21:40 /usr/bin/vi*

調べてもどこにも情報はなく、Githubのissueにもありませんでした。
(似たような人はいましたが放置状態)
ここ大事なとこなので諦められません。

まったく関係ないとこで何やら、.exeが付いているかついていないかで動きが違うという情報を取得。
理由は謎らしいので触れません。
https://stackoverflow.com/questions/54276583/getting-an-stdin-is-not-a-tty-error-when-using-python-json-tool-in-git-bash
viコマンドを表示してみると、なぜかviは.exeがついていない。
これはなぜなのか?

$ ll /usr/bin/vi*
-rwxr-xr-x 1 daisuke 197609      25 10月 21 21:40 /usr/bin/vi*
-rwxr-xr-x 1 daisuke 197609 2729207 11月  4 16:09 /usr/bin/view.exe*
-rwxr-xr-x 1 daisuke 197609 2729207 11月  4 16:09 /usr/bin/vim.exe*
-rwxr-xr-x 1 daisuke 197609 2729207 11月  4 16:09 /usr/bin/vimdiff.exe*
-rwxr-xr-x 1 daisuke 197609    2121 11月  4 16:09 /usr/bin/vimtutor*

ひとまず、vi.exeを作成します。
※管理者権限必要なので、Gitbashを管理者として開いていなければ、右クリック-「管理者として実行」してください。

$ cp -p /usr/bin/vi /usr/bin/vi.exe

また、エラーです。。。
しかし、内容が変わった。着実に進んでいる証拠です。

$ lab issue create
2019/12/06 02:25:07 issue_create.go:55: /home/travis/gopath/src/github.com/zaquestion/lab/cmd/issue_create.go:54 fork/exec C:\Program Files\Git\usr\bin\vi.exe: This version of %1 is not compatible with the version of Windows you're running. Check your computer's system information and then contact the software publisher.

「互換性がないからコンピューターのシステム情報を確認してから、ソフトウェアの発行元に連絡してください。」
と言われました。

ええ、なにか方法はないか、WSLを開きDebianのviを何気なく見てみたらヒントが。。!

unrealman@DESKTOP-XXXXX:~$ ll /usr/bin/vi
lrwxrwxrwx 1 root root 20 Aug  3 17:40 /usr/bin/vi -> /etc/alternatives/vi

unrealman@DESKTOP-XXXXX:~$ ll /etc/alternatives/vi
lrwxrwxrwx 1 root root 17 Aug  3 17:40 /etc/alternatives/vi -> /usr/bin/vim.tiny

シンボリックリンクをたどった先はvimでした。

もしやとvi.exeでvim.exeへのシンボリックリンクを張ってみました。

$ ln -s /usr/bin/vim.exe /usr/bin/vi.exe

いけました!

$ lab issue create

やっとwindowsからlabコマンドでissueが作れた。。。
# Write a message for this issue. The first block
# of text is the title and the rest is the description.
~

画像はslackと連携させているので、そこに通知が来ています。

f:id:unrealman:20191206024150p:plain

ゆっくり眠れそうです。

【Git for Windows】tty/mintty/winptyとは何なのか?【Gitbash】

tty/minttyとは何なのか?

Windows環境で、Linux操作が可能なGitbashでdockerコマンドなどをしようすると以下のようなエラーとなる。

$ docker exec -it unreal_container bash
the input device is not a TTY.  If you are using mintty, try prefixing the command with 'winpty'

何やら、
「入力デバイスはTTYではないよ。minttyを使用しているなら、コマンドの先頭に「winpty」を付けてくれ」
とのこと。

言われた通り、winptyを使用すれば問題なく動くので、.bash_profileにalias設定をしていました。
(補足)
もしくは以下にwinpty経由にしたいコマンドを追加でもOKなようです。

        for name in node ipython php php5 psql python2.7
        do
                case "$(type -p "$name".exe 2>/dev/null)" in
                ''|/usr/bin/*) continue;;
                esac
                alias $name="winpty $name.exe"
        done

なぜこのようなことが起こるのか?
以下が参考になりました。
■参考
GitbashはデフォルトでMinTTYを使用しており、それはGit for Windowsをインストールした際の構成ウィンドウで選択しているとのこと。
何気なくデフォルトでインストールしていましたが、確かに選択した記憶があります。。

ここで「Use MinTTY」を選択すると、Bashプロンプトは、Windowsに同梱されているCMDコンソールではなく、MinTTYターミナルエミュレーターでホストされます。MinTTYターミナルエミュレータは、コマンドの前にwinptyを付けない限り、Windowsコンソールプログラムと互換性がありません

https://willi.am/blog/2016/08/08/docker-for-windows-interactive-sessions-in-mintty-git-bash/
winptyとは?

MinTTYは、Windows APIを使用するプログラムと対話する場合、ptyの非互換性/文字エンコードの非互換性の問題からうまく動作しないらしく、回避策としてwinptyというラッパーを使うように推奨しているようです。
また、これはMinTTYの問題ではないとのこと。
https://github.com/mintty/mintty/wiki/Tips#inputoutput-interaction-with-alien-programs


また、もしWindows10デフォルトのコンソールに戻りたければ、Git for Windowsインストーラを再実行して選択しなおす。
どうしてもMinTTYを使いたい場合は、インタラクティブセッションでは先頭にwinptyをつけましょうということです。

そもそもtty/minttyとは何なのか?

ttyとは?

“tty”はもともとは “テレタイプ”を意味し、 “pty”は “擬似テレタイプ”を意味します。

https://codeday.me/jp/qa/20181203/23640.html

⇒ttyは端末、ptyは仮想端末(そこに読み書きするプロセスの端末のように機能するが、他のものによって管理されるデバイスエントリ)

コンソール上で、ttyコマンドを打つと自分のデバイスファイル名が表示されます。
(接続している人の名札のようなもの)

unrealman@STN-XXXXX MINGW64 ~/dev/docker (master)
$ tty
/dev/pty0

さらにセッションを立ち上げてttyを入力すると違うデバイスファイル名が表示されます。
(セッションごとにデバイスファイル名が生成される)

unrealman@STN-XXXXX MINGW64 ~/dev/docker (master)
$ tty
/dev/pty1

また、「/dev/pty0」が割り当てられている端末側から、

$ echo "hogehoge" > /dev/pty1

を実行すると、「/dev/pty1」が割り当てられている端末に"hogehoge"と表示されます。

つまり、どの端末から実行されているかを表している情報ということでよさそうです。

MinTTYとは?

Git for Windowsのインストール画面を参考。

ターミナルエミュレータ
それはサイズが変更可能なウインドウで、非長方形の選択、Unicodeをサポートしている。Windowsコンソール・プログラムは(対話型のPythonのような)MinTTYの中で動作させるために「winpty」を通して起動しなければならない。

結論

ttyは端末を持っていることを示し、コマンドの受け手は標準に対する統制(キーボードを介しての入力)があると期待しているのに、MinTTY(仮想端末)を使用することでptyとなり異常検知され警告されているということでしょうか?
上手く整理できていませんので、またアップデートします。
■参考
https://codeday.me/jp/qa/20190802/1364237.html
https://codeday.me/jp/qa/20190112/131467.html

【Windows】コマンド操作で超効率【fzf/ff】

Windows環境で爆速ファイル操作

fzfのダウンロード

github.com
64bitであればfzf-0.19.0-windows_amd64.zip
32bitであればfzf-0.19.0-windows_386.zip
(2019/12/15時点の最新)
任意のディレクトリに展開してください。

ffのダウンロード

Windows環境ではfzfの機能が制限されるので、fzfの Windowsラッパーであるffもダウンロードします。
github.com
ff-v0.1.1.zip
(2019/12/15時点の最新)
任意のディレクトリに展開してください。

環境変数に設定(パスを通す)

上記でダウンロードしたfzf.exeとff.exeのパスを通します。

使い方

以下のREADME.mdを参照。
github.com

便利設定

Gitbashでの設定

Gitbashを使用されている方は、そのままだとffが使えなかったので以下で実行する必要があります。

$ winpty ff

ただし、毎回winptyを入力するのは面倒なので、以下のようにエイリアスを設定しておくと良いと思います。
.bash_profileファイル

alias ff="winpty ff"
ショートカット設定

ff.exeと同階層の以下のファイルでAutoHotKeyに設定しておくと、「Windowsキー+/」ショートカットであいまい検索ができてさらに爆速です。
(ショートカットは自由に変更可能)
ff.ahkファイル

エクスプローラで開く

ff.exeと同階層の以下のファイルで下記の設定をすると「ff e」であいまい検索で選択したファイルのディレクトリをWindowsエクスプローラで開けるので便利です。
ff.cfgファイル

e.name = "Open Explorer in selected file"
e.select = "file"
e.action = "/MIN cmd /c for %i in ({}) do explorer %~dpi"

以上です。

【moment.js】日付を扱うライブラリの便利機能

便利機能メモ

月のショートネームを返却

moment.monthsShort();  // ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
moment.monthsShort(0); // "Jan"

// インスタンス生成
let m = moment();
// 現在の月のショートネームを小文字で返却(※実行したのは12月なので"dec")
moment.monthsShort(m.month()).toLowerCase(); // "dec"

うるう年の判定

moment([2000]).isLeapYear(); //true
moment([2001]).isLeapYear(); //false

インスタンスの複製

let m = moment();
mTmp = moment(m);

日付の加算・減算

let m = moment("2019-12-04");
m.add(1, "M").format("YYYY-MM-DD");      // "2020-01-04"
m.subtract(1, "M").format("YYYY-MM-DD"); // "2019-12-04" ↑で2020-01-04となったので

上記は月で指定したが、もちろん年や時間も可能
(指定は表のKeyでもShorthandでも良い)

Key Shorthand
years y
quarters Q
months M
weeks w
days d
hours h
minutes m
seconds s
milliseconds ms

その他

let m = moment("2019-12-04");

// 月の日数(末日)を取得
m.endOf("M").date(); // 31
// 月の末日の曜日を取得
m.endOf("M").day();  // 2 ([日(0)月(1)火(2)水(3)木(4)金(5)土(6)])
// 逆に月初は startOf() を使う
m.startOf("M").date(); // 1
m.startOf("M").day();  // 0

// 月を10月に設定(月の指定は0~11)
m.set("M", 10).format("YYYY-MM-DD"); // "2019-11-01"

以上です。

【javaScript】変数スコープの整理

スコープの種類

グローバルスコープ

プログラムのどこからでもアクセス可能なスコープ。
プログラムのトップレベルで宣言された変数(グローバル変数)はこのスコープを持つ。

ローカルスコープ(関数スコープ/ブロックスコープ)

グローバル変数以外は、ローカルスコープを持つローカル変数です。
関数スコープとブロックスコープの2つに分けられます。

関数スコープ

関数ごとのスコープ。
関数内で宣言した変数は、関数の内側からのみアクセス可能なローカル変数になります。
※仮引数も同じく関数スコープを持ちます。

function fn(arg) {
  // 仮引数 arg は参照できる
  console.log(arg); // => 1
}
fn(1);
ブロックスコープ

ブロック({})ごとのスコープ。
ブロック内で宣言した変数は、ブロックの内側からのみアクセス可能なローカル変数になります。
※仮引数も同じく関数スコープを持ちます。

for (let i = 0; i < 5; i++) {
  // 仮引数 i は参照できる
  console.log(i);
}

変数キーワードの種類

var

・関数スコープを持つ。
つまり、ifブロック内の宣言であろうと宣言された関数のどこからでもアクセスできる。

(function() {
  if (true) {
    var x = 'hoge';
  }
  console.log(x); // => hoge
}());

・変数を宣言する前に参照してもエラーとならない。

console.log(s); // => undefined
var s = "hoge";

・再定義可能

var x = "hoge";
var x = "moge";
console.log(x); // => moge

これは、意図せずに同じ変数名で定義してもエラーとならずに、値を上書きしてしまう。

let

ブロックスコープを持つ。
つまり、letで宣言された変数にアクセスできるのは、それらの変数が宣言されたブロック(またはサブブロック)の内側のみとなる。
・変数がvarに比べてはるかに予測可能なものとなり、ブロック外での使用されたことによるバグの紛れ込みがなくなる。
・変数を宣言する前に参照するとエラーとなる。

console.log(t); // => ReferenceError: Cannot access 't' before initialization
let t = "moge";

・再定義不可能

let x;
let x; // => SyntaxError: Identifier 'x' has already been declared

const

・定数。変更不可。
・再代入が必要ないときはconstを使う。


以上です。

【WSL】windowsでbashを利用する

WSLとは?

WSL(Windows Subsystem for Linux)とは、一言でいうとWindows 10からLinuxを利用するための仕組みです。
GUIよりもコマンド操作の方が手っ取り早いという人にLinuxの恩恵をもたらします。
また、仮想マシンとは違い起動も早く、同じWindows OSの中のプロセスのため、Windows OS側でアクセスを禁止しているものを除く全てのファイルやフォルダにアクセスすることができます。
そのため、LinuxコマンドでWindows 10側のファイルを処理したり、Linuxで処理した結果をExcelやWordで読み込んだりすることが可能となっています。

WSLのインストール方法

WSLの有効化

スタートボタンを右クリック- アプリと機能 を押下
f:id:unrealman:20191201072339j:plain

関連設定のプログラムと機能を押下
f:id:unrealman:20191201072352j:plain

Windowsの機能の有効化または無効化を押下
f:id:unrealman:20191201073154j:plain

Windows Subsystem for LinuxにチェックしOKを押下
f:id:unrealman:20191201072512j:plain

インストールが始まるので、完了したら再起動してください。
f:id:unrealman:20191201072612j:plain
f:id:unrealman:20191201072525j:plain

Linuxディストリビューションを取得

スタートボタンからMicroSoft Storeを押下
f:id:unrealman:20191201072528j:plain

今回はDebianを取得するため、検索窓で"debian"と入力した。
f:id:unrealman:20191201072534j:plain

Debianを選択
※別の端末でもインストールしたため画像は取得済みとなっています。
f:id:unrealman:20191201072537j:plain

インストールを押下
f:id:unrealman:20191201072539j:plain

インストールが完了したら起動を押下
f:id:unrealman:20191201072544j:plain

ユーザー名とパスワードの設定を求められるので入力してください。
f:id:unrealman:20191201073839j:plain
f:id:unrealman:20191201073842j:plain

これで完了です。

ちなみに/mntでWindows側のドライブが見えるようです。
画像はCドライブとDドライブが表示されています。
f:id:unrealman:20191201073847j:plain



以上です。

【Gitlab】プロジェクトを別のグループへ移動

プロジェクトを別のグループへ移動

移動したいプロジェクトを選択

f:id:unrealman:20191130201005p:plain

サイドメニューから「設定」-「一般」を押下

f:id:unrealman:20191130201009p:plain

高度な設定の「展開」を押下

f:id:unrealman:20191130201012p:plain

高度な設定のメニューがスライド表示されるので、Transfer projectで移動先のグループを選択

f:id:unrealman:20191130202611p:plain

「Transfer project」を押下

f:id:unrealman:20191130202607p:plain

プロジェクト名を入力すると「確認」ボタンが活性化するので押下

f:id:unrealman:20191130203249p:plain

以上です。