sahara3のブログ

プログラミング関連のメモみたいなものを、つらつらと書くかもしれない。

GitHub Actions のローカルテスト

GitHub に置いてある Java ライブラリー、 GitHub Actions を使って、Bintray へのアップロードとかを自動化しようとしてみたときのこと。

YAML でワークフローを書くのはいいのだが、動作確認がやりづらくて困っていた。 とりあえず commit & push してみれば動くものもあるのだが、release とかを自動化するのに、 何度も try & error するのは避けたかった。

何かいいツールはないかと探していたら、act という便利なツールを見つけた。

github.com

Linux で Docker でも動かせば、割と気軽に使えたので、便利便利。

HTTP Cookie とポート番号

HTTP Cookie は、指定したドメインをまたいで送信することは、ない。 それは、RFC 6265 の 4.1.2.3 などにも書かれている。

RFC 6265 - HTTP State Management Mechanism

http://localhost:8080/ の場合は、この「ドメインの一致」を見る部分は 「localhost:8080」、つまりポート番号まで含むとずっと思い込んでいたのだが、 RFCをよく読むと、ポート番号では分離されない、と書いてあった。

8.5. Weak Confidentiality
Cookies do not provide isolation by port.

とある開発で、1台のサーバー上で複数のWebアプリケーションを ポート番号を分けて起動していたのだが、上の思い込みにより嵌ってしまった。

git svn dcommit でSubversionに記録されるコミットログ

諸般の事情でSubversionの中央リポジトリーを使わなくてはならないが、複数人で分散作業したくなった時。

git-svnが使えそうな気がしていたが、Subversion側にどのようなコミットログが残るか心配だった。たとえば、各人がgit内で適当に書いたログがそのまま載ってしまうのだろうか、とか。

少し試してみた感じだと、気をつければ、なんとかなるような感触。

  • svn-master
    • git-master (git svn clonse -s svn-master してきたやつ。1つにする。)
      • git-work (git clone git-master してきたやつ。人数分作ってよい。)

こんなかんじの階層にしておき、おおよそ以下の流れで作業する。

  1. 各人の作業はgit-workでやる。
  2. 各人の作業がよい感じになったら、git-masterにpull-requestする。
  3. git-masterの管理者は、git pull --no-commit でpullする。
  4. git-masterの管理者は、pullした内容に問題なければ、git commit する。
    • このときのコミットログがSubversionにも記録される模様。
  5. git-masterから、git svn dcommit する。


3で --no-commit を付けないと、git-workでコミットログした時の内容がそのままSubversionのコミットログになるっぽい。


あまり細かく試してはいないけれども、うまく運用すれば、何とかなりそうだ。

Cygwin ls と Windows 隠しファイル

Cygwin ls は、Windows的な隠しファイルかどうかなんて気にしないので、%USERPROFILE% == $HOME としていると、なんだか悲しいことになる。

coreutilsのソースを取り出し、以下みたいなパッチを当ててコンパイルすると、隠しファイルを表示しなくなる。
当然、-a とかオプションつければ、表示されるようになる。

--- origsrc/coreutils-8.23/src/ls.c	2015-04-19 00:25:42.231183700 +0900
+++ src/coreutils-8.23/src/ls.c	2015-04-26 00:47:11.372547200 +0900
@@ -118,7 +118,10 @@
 #endif
 
 #if __CYGWIN__
+# undef DATADIR
 # include "cygwin.h"
+# include <sys/cygwin.h>
+# include <windows.h>
 #endif
 
 #define PROGRAM_NAME (ls_mode == LS_LS ? "ls" \
@@ -249,7 +252,7 @@
                           size_t *width);
 static char *make_link_name (char const *name, char const *linkname);
 static int decode_switches (int argc, char **argv);
-static bool file_ignored (char const *name);
+static bool file_ignored (char const *dirname, char const *name);
 static uintmax_t gobble_file (char const *name, enum filetype type,
                               ino_t inode, bool command_line_arg,
                               char const *dirname);
@@ -2635,7 +2638,7 @@
       next = readdir (dirp);
       if (next)
         {
-          if (! file_ignored (next->d_name))
+          if (! file_ignored (name, next->d_name))
             {
               enum filetype type = unknown;
 
@@ -2750,11 +2753,61 @@
   return false;
 }
 
+#if __CYGWIN__
+/* Return true if FILE is a hidden file for Windows.  */
+
+static bool
+file_ignored_win32 (char const *dirname, char const *name)
+{
+  char *posix;
+  wchar_t *win32;
+  size_t len;
+  ssize_t size;
+  bool ignore;
+
+  if (ignore_mode != IGNORE_DEFAULT) {
+    return false;
+  }
+
+  len = strlen(dirname) + 1 + strlen(name);
+  if ((posix = (char*) malloc(len + 1)) == NULL) {
+    return false;
+  }
+  if (strcmp(dirname, "/") == 0) {
+    snprintf(posix, len, "/%s", name);
+  }
+  else {
+    snprintf(posix, len + 1, "%s/%s", dirname, name);
+  }
+
+  size = cygwin_conv_path(CCP_POSIX_TO_WIN_W, posix, NULL, 0);
+  if (size < 0 || (win32 = (wchar_t*) malloc(size)) == NULL) {
+    free(posix);
+    return false;
+  }
+
+  ignore = false;
+  if (cygwin_conv_path(CCP_POSIX_TO_WIN_W, posix, win32, size) == 0 &&
+      GetFileAttributesW(win32) & FILE_ATTRIBUTE_HIDDEN) {
+    ignore = true;
+  }
+  free(posix);
+  free(win32);
+  return ignore;
+}
+#endif /* __CYGWIN__ */
+
 /* Return true if FILE should be ignored.  */
 
 static bool
-file_ignored (char const *name)
+file_ignored (char const *dirname, char const *name)
 {
+#if __CYGWIN__
+  if (file_ignored_win32(dirname, name)) {
+    return true;
+  }
+#endif /* __CYGWIN__ */
+
   return ((ignore_mode != IGNORE_MINIMAL
            && name[0] == '.'
            && (ignore_mode == IGNORE_DEFAULT || ! name[1 + (name[1] == '.')]))

coreutils-8.23-4 でやったけど、たぶん他のバージョンでも同じ感じでOKのはず。

コンパイルは以下の様な感じ。だと思う。たぶん。

$ cd coreutils-8.23-4.src
$ mkdir src && cd src
$ tar xf ../coreutils-8.23.tar.xz
$ patch -p0 -u < coreutils-8.23-4.src.patch
$ patch -p0 -u < coreutils-8.23-4.cygwin.patch
$ patch -p0 -u < 上のパッチ
$ cd src/coreutils-8.23
$ ./configure && make
# cp -i src/{dir,ls,vdir}.exe /usr/local/bin/

coreutilsがGPLv3だと思うので、上記パッチもGPLv3扱いです。