アドベントペアプロ #8 denoland/deno
以下をhyper::Errorを使うようにしたかったけどいろいろ断念
io::Error::new(io::ErrorKind::Other, e)
https://docs.rs/hyper/0.11.17/hyper/error/enum.Error.html
エラーハンドリング https://doc.rust-jp.rs/the-rust-programming-language-ja/1.6/book/error-handling.html
なんだかんだ送ったプルリク
Rename source url to script name #1329 https://github.com/denoland/deno/pull/1329
Change default to false Base.bool #1330 https://github.com/denoland/deno/pull/1330
アドベントペアプロ #7 react-native
ファシリテータ: @ggtmtmgg セクリタリ: @ggtmtmgg 参加者: @saitoxu レポジトリ: https://github.com/facebook/react-native Issue: https://github.com/facebook/react-native/issues/20410
前回: https://hackmd.io/3bjDo5SDSvW9rnR-gKieow
spyOn
jestのspyOnが便利 spyOnをつかって、特定の関数が呼ばれるかをテストしたり、test中だけ実装を入れ替えたりできる。
... "flow": "flow", "flow-check-ios": "flow check", "flow-check-android": "flow check --flowconfig-name .flowconfig.android", ...
後でPR送る(@saitoxu)
React.
... // $FlowFixMe - TODO T29156721 `React.forwardRef` is not defined in Flow, yet. ViewToExport = React.forwardRef(View); ...
Reactv16.6.3では引数の型が定義されているので、おそらくコメントアウトごと消せば良い。 https://github.com/facebook/react/tree/v16.6.3
よくわからないので質問する https://github.com/facebook/react-native/issues/22595
アドベントペアプロ #9 expo/expo
home/ はexpoクライアント
ApolloClient はgraphQL用
home/ に狙いを定める
- react-navigationのバージョンを上げる
console.log(e)をSentryに送る← そもそもSenry入ってなかった- home/utils/requestCameraPermissionsAsync.jsのexportの仕方を治す
以下、home/ および、apps/以下のサンプルアプリの実行が出来ない問題
NixはThe Purely Functional Package Manager
クライアントアプリのビルド・セットアップ
$ curl https://nixos.org/nix/install | sh $ . /Users/TSUBASA/.nix-profile/etc/profile.d/nix.sh $ nix-env -iA nixpkgs.direnv $ cd tools-public $ yarn
iosのセットアップ
$ brew update $ brew install git-lfs $ cd expo/ $ git lfs pull $ cd tools-pubilc $ ./generate-files-ios.js $ open ../ios/Exponent.xcworkspace
サブモジュールのインストール
$ git submodule init $ git submodule update
もしくは
$ git clone --recurse-submodules git@github.com...
Permission denied (publickey).が出てしまったら
$ git clone --recurse-submodules https://github.com/expo/react-native.git
質問をする - フォーラムに投げる - apps/native-component-listとhome/を実行できない問題 - それぞれ同じエラーが出てるから同じ問題だと思う - それぞれの動かし方をまとめてるドキュメントがあれば教えて欲しい - もしくはこのエラーの対処法を...!
アドベントペアプロ #6 denoland/deno
ファシリテータ: @ggtmtgg セクリタリ: @ggtmtmgg 参加者: @binaryta, @Haga
h2
src/fs.rs
// TODO: on posix, set mode flags to 0o700
- posixを理解する
- create_dirした後にstg::fs::set_permissionsをつかって権限を700にする
- main.rsでサンプルコードを書く
- 参考: https://doc.rust-lang.org/std/fs/fn.set_permissions.html
- そのtestを書く
サンプルコード
use std::fs; fn main() -> std::io::Result<()> { let d = fs::create_dir("/Users/naritatakuya/dir")?; fs::set_permissions("/Users/naritatakuya/dir", perms); println!("{:?}", d); Ok(()) }
- // TODO: on posix, set mode flags to 0o700. let r = create_dir(buf.as_path()); + let mut file; + match r { + Ok(_) => { + file = OpenOptions::new().open(buf.as_path())?; + }, + Err(e) => return Err(e), + } + + let r = set_permissions(&mut file, 0o700); + + match r {
このtestを通す
$ ./tools/test.py
use std::fs; use std::fs::{OpenOptions}; use std::os::unix::fs::PermissionsExt; fn main() -> std::io::Result<()> { // let d = fs::create_dir("/Users/TSUBASA/workspace/deno/foo")?; let file; let path = "/Users/TSUBASA/workspace/deno/foo"; let r = fs::create_dir(path); match r { Ok(_) => { file = OpenOptions::new().create(true).open(path)?; }, Err(e) => return Err(e), } let _r = file.set_permissions(PermissionsExt::from_mode(0o700 & 0o777)); Ok(()) }
が{ code: 22, kind: InvalidInput, message: "Invalid argument" }
を出しているのをなおす`
use std::fs; use std::fs::{OpenOptions}; use std::os::unix::fs::PermissionsExt; fn main() -> std::io::Result<()> { // let d = fs::create_dir("/Users/TSUBASA/workspace/deno/foo")?; let file; let path = "/Users/TSUBASA/workspace/deno/foo"; let r = fs::create_dir(path); match r { Ok(_) => { file = OpenOptions::new() .read(true) .write(true) .create(true) .open(path)?; }, Err(e) => return Err(e), } let _r = file.set_permissions(PermissionsExt::from_mode(0o700 & 0o777)); Ok(()) }
が Error: Os { code: 21, kind: Other, message: "Is a directory" }
を出しているのをなおす
僕らは file のpermissionを変更するやつをdirにやろうとしてた。 dirのpermissionを変え無くてはならない。
use std::path::PathBuf; use std::fs; use std::os::unix::fs::PermissionsExt; fn main() -> std::io::Result<()> { let path = PathBuf::from("/Users/naritatakuya/foo"); let r = fs::create_dir(path.as_path()); fs::set_permissions(path.as_path(), PermissionsExt::from_mode(0o700))?; Ok(()) }
が動いた
[Darwin (deno)] (master) $ find ./target/ -type f | grep msg_generated ./target//debug/gen/msg_generated.ts ./target//debug/gen/msg_generated.rs
アドベントペアプロ #5 denoland/deno
ファシリテーター: @ggtmtmgg
セクリタリ: @ggtmtmgg
参加者: @binaryta, @Haga
情報の共通化
unit_testsのエラーについて
$ ./tools/unit_tests.py target/debug/deno ... HttpOther: an error occurred trying to connect: Connection refused (os error 61)
というエラーがでる問題と戦ってみた。
os error 61
が何か分からなかった。
サンドボックスのせいかな?--allow-net
が上手く渡せてない?
もしくはlocalhost:4545をたてれてない?
replでconst, letが動かない問題について
replへの入力をreplLoop()が監視している
evaluate(code)で一行ずつ読み込む
evaluateのなかで呼んでるeval.call(window, code)に渡してるスコープが間違っていそう
cost window = globalEval("this");
globalEvalとevalがある。
単なるevalはそのスコープで動く。呼ばれたfunciton内のスコープで動く。
globalEvalはグローバルなスコープで動くっぽい
つまりreplの入力一行ごとに関数のブロックスコープが作られそのなかでconstで変数を定義してしまっている。
だから二行で書くと動かない、一行でやれば動く
> const a = 1; undefined > a ReferenceError: a is not defined
> const a = 1; console.log(a); 1 undefined > var c = 1; console.log(c); 1 undefined >
方針の決定
denoのts側のソースコードの問題に着手するというコンセプトで行く
Error("ErrTooLarge") を DenoError(TooLarge)に書き換える作業が良さそう
DenoErrorの使う
gen/以下からErrorKindをインポートしている。
genはたぶんGNでビルドされたやつ。
genはgRPCみたいに資源共有するやつが出力されてる。
msg.fbsが型共有の仕組みの実装部分。そこに記述してビルドすればgen/以下に出力されるはず。
なので、今回はmsg.fbにErrorKindにTooLargeを追加してビルドする。
その後、
new DenoError( ErrorKind.TooLarge, "" )
に書き換える
エラーメッセージを考える
grow()はバッファの容量を増やす関数 今回のエラーはgrow()でこれ以上バッファを増やせないよってときに吐くエラー
throw new DenoError( ErrorKind.TooLarge, "The buffer can't grow because it becomes too large" );
src/msg.fbs
enum ErrorKind: byte { // ... TooLarge, }
テストがないのでテストを書く
やること
- Bufferのwrite, readのどちらかもしくは両方で_grow()を使ってる部分を確認する
- どれくらいの大きさでTooLargeになるのか把握する
- TooLargeな状況で_grow()が呼ばれる状態をjs/buffer_test.tsで再現する
- それをassertする
$ git remote add binaryta git@github.com:Tnarita0000/deno.git $ git fetch binaryta js/modify-buffer-large-error $ git checkout js/modify-buffer-large-error
c > MAXSIZE - c - n
のときにTooLargeになる
cの実態に関して
c = this.capasity
はthis.capasity = this.buf.buffer.byteLength
this.buf
はUint8Array型
nの実態に関して
write(p: Uint8Array)
で渡される。
n = p.buffer.byteLength
書き込むデータの大きさ。
bufferTestGrow()がそのまま使えそう。
test(async function bufferTestGrow() { const tmp = new Uint8Array(72); for (let startLen of [0, 100, 1000, 10000, 100000]) { const xBytes = repeat("x", startLen); for (let growLen of [0, 100, 1000, 10000, 100000]) { const buf = new Buffer(xBytes.buffer as ArrayBuffer); // If we read, this affects buf.off, which is good to test. const { nread, eof } = await buf.read(tmp); buf.grow(growLen); const yBytes = repeat("y", growLen); await buf.write(yBytes); // Check that buffer has correct data. assertEqual( buf.bytes().subarray(0, startLen - nread), xBytes.subarray(nread) ); assertEqual( buf.bytes().subarray(startLen - nread, startLen - nread + growLen), yBytes ); } } });
Number.MAX_VALUE
をgrowLenに渡してみる。
$ deno > 1.7976931348623157e+308
こんな感じでtestを書いてみる
test(async function bufferTooLargeByteWrites() { init(); const tmp = new Uint8Array(72); const growLen = Number.MAX_VALUE; const xBytes = repeat("x", 0); const buf = new Buffer(xBytes.buffer as ArrayBuffer); // If we read, this affects buf.off, which is good to test. const { nread, eof } = await buf.read(tmp); try { buf.grow(growLen); } catch (e) { assertEqual(stringify(e).split("\n")[0], "TooLarge: The buffer can't grow because it becomes too large"); } });
そしてPRを送って解散
JS Ninja アドベントペアプロ #4 expo/expo
本記事は JS Ninja OSSペアプロ Advent Calendar 2018 - Qiitaの#4です。
ファシリテータ: @ggtmtmgg セクリタリ: @ggtmtmgg 参加者: @hmktsu
方針の整理
実務で使うためにレポジトリを良くする。そのためにPRを送る。
- react-navigation v2 -> v3の変更でうまれた歪の回収
- expoのpackageを作る
- expoのいい感じのissueを見つける
- expoのTODOコメントアウトを探す ←
$ git grep 'TODO' G apps apps/native-component-list/screens/Contacts/ContactUtils.js: // TODO: Evan: add support for calendars: https://github.com/moment/moment/issues/1454 apps/native-component-list/screens/MediaLibrary/MediaDetailsScreen.js: case MediaLibrary.MediaType.video: // TODO: render Expo.Video component apps/test-suite/tests/AdMobRewarded.js: // TODO: Fix apps/test-suite/tests/SQLite.js:// TODO: Only tests successful cases, needs to test error cases like bad database name etc. packages/expo-firebase-app/tests/App.js: // TODO add back in when android sdk support for deleting apps becomes available
apps/test-suite/tests/SQLite.js:// TODO: Only tests successful cases, needs to test error cases like bad database name etc.
↑これをがんばる
方針の整理
apps/test-suite/tests/SQLite.js
に失敗する場合のテストも追加してPRを投げる。
PRのメッセージで @ide さんにフィードバックを求める。
やることリスト
etc
は無視してbad database name
な例のテストを書く- テストを実行する ←
- PRを送る
test-suiteを実行するための手順
$ cd Desktop $ git clone https://github.com/watanabeyu/expo expo $ cd expo/apps/test-suite ~~$ yarn add --dev expo-yarn-workspaces~~ # 下記のfileから始まるパスのexpo-yarn-workspacesを使う $ yarn $ yarn test // ← エラーになりました
副産物PR
package.json
のdevパッケージにexpo-yarn-workspaces
を追加する
yarn add --dev expo-yarn-warkspaces
だと、
Error: Cannot find module metro/src/blacklist
になる
以下の追加の仕方が筋が良さそう
"devDependencies": { "expo-yarn-workspaces": "file:../../packages/expo-yarn-workspaces" }
だと思ったけど、Error: Cannot find module 'metro-config/src/defaults/blacklist'
になるところで断念。
package.json
のcd Runner
をcd runner
にする
VSCodeの一部の環境ではcd Runner
でrunner/ディレクトリに移動できる。
他の環境ではRunner/ディレクトリが見つからないよエラーになってしまう。
PRを送ってマージされた。 https://github.com/expo/expo/pull/2929
アドベントペアプロ #3 deno
2018/12/05のアドベントペアプロの議事録
ファシリテータ: @binaryta
セクリタリ: @binaryta
参加者: @__syumai
レポジトリ: https://github.com/denoland/deno
issue: https://github.com/denoland/deno/issues/1159
denoのTODOコメントを見てみた
TS側一部抜粋
$ find ./js -type f -print | xargs grep TODO .//net.ts:// TODO support other types: .//net.ts:// TODO Support finding network from Addr, see https://golang.org/pkg/net/#Addr .//net.ts: * TODO: `tcp4` (IPv4-only), `tcp6` (IPv6-only), `udp`, `udp4` (IPv4-only), .//net_test.ts:/* TODO Fix broken test. .//net_test.ts:/* TODO Fix broken test. .//net_test.ts:/* TODO Fix broken test.
- denoのinterfaceにはGoを流用しているものがいくつかある
- net_testなどは、Go標準ライブラリのtestを読みつつ書いたら直せるかも
Rust側一部抜粋
$ find ./src -type f -print | xargs grep TODO .//version.rs:// TODO Extract this version string from Cargo.toml.
実際に読んでみた
TS側
net_test.ts
コメントアウトを外しても普通にテスト既存のテストコードが動いたので問題無さそう.
net.ts
9 export type Network = "tcp"; 10 // TODO support other types: 11 // export type Network = "tcp" | "tcp4" | "tcp6" | "unix" | "unixpacket"; 12 13 // TODO Support finding network from Addr, see https://golang.org/pkg/net/#Addr 14 export type Addr = string; 15
プロトコルの種類を増やしてtypeを増やすTODO. 重そうだから一旦無視.
issue
Use let
in REPL gives ReferenceError #1159
https://github.com/denoland/deno/issues/1159
- REPLの実行時にletで定義した変数を後から参照したらReferenceErrorが発生する.
- constも同様にReferenceErrorが発生する.
- varで定義したものは動作しているように見えるが、実際にはグローバル変数(windowのプロパティ)になっているだけだった.
問題
- evalはグローバルのスコープで実行されてしまう
const myEvalGen = () => { const lines = []; return line => { lines.push(line); const code = lines.join(";"); try { return eval(code); } catch (err) { lines.pop(); throw err; } }; }; const myEval = myEvalGen(); myEval("const a = 1;"); myEval("const b = 2;"); myEval("a + b;"); // => 3 myEval("a + b + c;"); // error thrown myEval("const c = 3;"); myEval("a + b + c;"); // => 6 (error fixed)
解決策)
- 1行1行のソースコードlines配列にpushしていき、eval実行の行を毎度バッファする.
- 例外を一度でも吐くと、以降も例外が引き継がれてしまうでの、try/catchにより例外時の行はバッファから取り除く(popする)