Windows11で、cargo newで作ったgitリポジトリが「detected dubious ownership in repository」というエラーで使えない

Windows11に乗り換えたばっかりのエンジニア、ナナオです。 やはり乗り換えると今までと使い勝手が変わるので、何かするたびにエラーになりますね。 今回はGit関連でエラーが起きたので備忘録を残します。 どんなエラー? cargo newでCargoパッケージ作成すると、ありがたいことに最初からgit関連の設定もされた状態になっていると思いますが、そのパッケージ内でgitコマンドを使用するとこのようなエラーになってしまいました。 > git status fatal: detected dubious ownership in repository at 'C:/Users/Nanao/Project/study/rust-playground' 'C:/Users/Nanao/Project/study/rust-playground/.git' is owned by: 'S-1-5-32-544' but the current user is: 'S-1-5-21-2894757817-1525132421-3221859733-1001' To add an exception for this directory, call: git config --global --add safe.directory C:/Users/Nanao/Project/study/rust-playground このエラーはなんなの? 要は「このgitリポジトリの所有者はあなたじゃないから操作できませんよ」というエラーです。 結論としては以下のようなコマンドをPowerShell上で実行することで解決します。 takeown.exe /f [gitリポジトリのパス] /r | Out-Null takeownはファイルの所有者を変更するコマンドです。 Windows�Ńt�@�C���̏��L�҂��ύX�����i�R�}���h�v�����v�g�ҁj�FTech TIPS - ��IT Linuxのchownと同じようなものですね。 Linuxコマンド【 chown 】ファイルの所有者やグループを変更 - Linux入門 - Webkaru このコマンドを使用して所有者を自身に再設定しています。 まとめ いちいちこのコマンドで所有者を変更するのも面倒だなぁ…まぁ慣れればいいか…? 参考 krymtkts - git で local repo が自分のものじゃないとなったやつ

2023年10月30日 · にあえん

Windowsでexaを使う

最近メインPCをWindows11にしました。ナナオです。 cargoなどの初期セットアップがだいぶ終わって作業しやすくなってきましたが、lsの高速版であるexaを入れようとしたら詰まったので備忘録を残しておこうと思います。 exaのインストール Windows以外であれば以下のコマンドでインストールは終わります。 cargo install exa ただし、exaはまだ正式にWindows版をリリースしていないため、同じ事をwindowsでやるとエラーになります。 (以下は実際のエラー) > cargo install exa Updating crates.io index Downloaded exa v0.10.1 Downloaded 1 crate (136.6 KB) in 1.23s Installing exa v0.10.1 Updating crates.io index Downloaded number_prefix v0.4.0 Downloaded users v0.11.0 Downloaded term_size v0.3.2 Downloaded byteorder v1.5.0 Downloaded ansi_term v0.12.1 Downloaded scoped_threadpool v0.1.9 Downloaded jobserver v0.1.27 Downloaded libgit2-sys v0.12.26+1.3.0 Downloaded natord v1.0.9 Downloaded term_grid v0.1.7 Downloaded zoneinfo_compiled v0.5.1 Downloaded locale v0.2.2 Downloaded pad v0.1.6 Downloaded datetime v0.5.2 Downloaded git2 v0.13.25 Downloaded 15 crates (1.9 MB) in 1.29s (largest was `libgit2-sys` at 1.5 MB) Compiling libc v0.2.149 Compiling winapi v0.3.9 Compiling jobserver v0.1.27 Compiling pkg-config v0.3.27 Compiling vcpkg v0.2.15 Compiling tinyvec_macros v0.1.1 Compiling unicode-width v0.1.11 Compiling unicode-bidi v0.3.13 Compiling percent-encoding v2.3.0 Compiling log v0.4.20 Compiling bitflags v1.3.2 Compiling byteorder v1.5.0 Compiling glob v0.3.1 Compiling num_cpus v1.16.0 Compiling number_prefix v0.4.0 Compiling natord v1.0.9 Compiling scoped_threadpool v0.1.9 Compiling lazy_static v1.4.0 Compiling tinyvec v1.6.0 Compiling pad v0.1.6 Compiling term_grid v0.1.7 Compiling form_urlencoded v1.2.0 Compiling cc v1.0.83 Compiling locale v0.2.2 Compiling users v0.11.0 error[E0433]: failed to resolve: could not find `unix` in `os` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:36:14 | 36 | use std::os::unix::ffi::OsStrExt; | ^^^^ could not find `unix` in `os` error[E0432]: unresolved imports `libc::uid_t`, `libc::gid_t` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\lib.rs:128:16 | 128 | pub use libc::{uid_t, gid_t}; | ^^^^^ ^^^^^ no `gid_t` in the root | | | no `uid_t` in the root error[E0432]: unresolved imports `libc::uid_t`, `libc::gid_t` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:45:20 | 45 | use libc::{c_char, uid_t, gid_t, c_int}; | ^^^^^ ^^^^^ no `gid_t` in the root | | | no `uid_t` in the root | = help: consider importing this unresolved item through its public re-export instead: uid_t = help: consider importing this unresolved item through its public re-export instead: gid_t error[E0432]: unresolved import `libc::passwd` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:46:5 | 46 | use libc::passwd as c_passwd; | ^^^^^^^^^^^^^^^^^^^^^^^^ no `passwd` in the root error[E0432]: unresolved import `libc::group` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:47:5 | 47 | use libc::group as c_group; | ^^^^^^^^^^^^^^^^^^^^^^ no `group` in the root error[E0432]: unresolved imports `libc::uid_t`, `libc::gid_t` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\cache.rs:87:12 | 87 | use libc::{uid_t, gid_t}; | ^^^^^ ^^^^^ no `gid_t` in the root | | | no `uid_t` in the root | = help: consider importing this unresolved item through its public re-export instead: uid_t = help: consider importing this unresolved item through its public re-export instead: gid_t error[E0432]: unresolved imports `libc::uid_t`, `libc::gid_t` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\mock.rs:63:16 | 63 | pub use libc::{uid_t, gid_t}; | ^^^^^ ^^^^^ no `gid_t` in the root | | | no `uid_t` in the root | = help: consider importing this unresolved item through its public re-export instead: uid_t = help: consider importing this unresolved item through its public re-export instead: gid_t error[E0432]: unresolved imports `libc::uid_t`, `libc::gid_t` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\switch.rs:4:12 | 4 | use libc::{uid_t, gid_t, c_int}; | ^^^^^ ^^^^^ no `gid_t` in the root | | | no `uid_t` in the root | = help: consider importing this unresolved item through its public re-export instead: uid_t = help: consider importing this unresolved item through its public re-export instead: gid_t error[E0432]: unresolved imports `libc::uid_t`, `libc::gid_t` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\traits.rs:4:12 | 4 | use libc::{uid_t, gid_t}; | ^^^^^ ^^^^^ no `gid_t` in the root | | | no `uid_t` in the root | = help: consider importing this unresolved item through its public re-export instead: uid_t = help: consider importing this unresolved item through its public re-export instead: gid_t error[E0433]: failed to resolve: could not find `UserExtras` in `os` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:78:26 | 78 | let extras = os::UserExtras::default(); | ^^^^^^^^^^ could not find `UserExtras` in `os` error[E0433]: failed to resolve: could not find `GroupExtras` in `os` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:192:26 | 192 | let extras = os::GroupExtras::default(); | ^^^^^^^^^^^ could not find `GroupExtras` in `os` error[E0433]: failed to resolve: could not find `UserExtras` in `os` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:266:28 | 266 | extras: os::UserExtras::from_passwd(passwd), | ^^^^^^^^^^ could not find `UserExtras` in `os` error[E0433]: failed to resolve: could not find `GroupExtras` in `os` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:280:23 | 280 | extras: os::GroupExtras::from_struct(group), | ^^^^^^^^^^^ could not find `GroupExtras` in `os` error[E0412]: cannot find type `UserExtras` in module `os` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:57:17 | 57 | extras: os::UserExtras, | ^^^^^^^^^^ not found in `os` | note: found an item that was configured out --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:1176:14 | 1176 | pub type UserExtras = bsd::UserExtras; | ^^^^^^^^^^ note: found an item that was configured out --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:1180:14 | 1180 | pub type UserExtras = unix::UserExtras; | ^^^^^^^^^^ error[E0412]: cannot find type `GroupExtras` in module `os` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:171:17 | 171 | extras: os::GroupExtras, | ^^^^^^^^^^^ not found in `os` | note: found an item that was configured out --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:1184:14 | 1184 | pub type GroupExtras = unix::GroupExtras; | ^^^^^^^^^^^ error[E0425]: cannot find function `getpwuid_r` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:336:19 | 336 | libc::getpwuid_r(uid, &mut passwd, buf.as_mut_ptr(), buf.len(), &mut result) | ^^^^^^^^^^ not found in `libc` error[E0425]: cannot find function `getpwnam_r` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:398:19 | 398 | libc::getpwnam_r(username.as_ptr(), &mut passwd, buf.as_mut_ptr(), buf.len(), &mut result) | ^^^^^^^^^^ not found in `libc` error[E0425]: cannot find function `getgrgid_r` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:451:19 | 451 | libc::getgrgid_r(gid, &mut passwd, buf.as_mut_ptr(), buf.len(), &mut result) | ^^^^^^^^^^ not found in `libc` error[E0425]: cannot find function `getgrnam_r` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:513:19 | 513 | libc::getgrnam_r(groupname.as_ptr(), &mut group, buf.as_mut_ptr(), buf.len(), &mut result) | ^^^^^^^^^^ not found in `libc` error[E0425]: cannot find function `getuid` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:556:20 | 556 | unsafe { libc::getuid() } | ^^^^^^ help: a function with a similar name exists: `getpid` | ::: C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\libc-0.2.149\src\windows\mod.rs:491:5 | 491 | pub fn getpid() -> ::c_int; | -------------------------- similarly named function `getpid` defined here error[E0425]: cannot find function `geteuid` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:603:20 | 603 | unsafe { libc::geteuid() } | ^^^^^^^ help: a function with a similar name exists: `getpid` | ::: C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\libc-0.2.149\src\windows\mod.rs:491:5 | 491 | pub fn getpid() -> ::c_int; | -------------------------- similarly named function `getpid` defined here error[E0425]: cannot find function `getgid` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:647:20 | 647 | unsafe { libc::getgid() } | ^^^^^^ help: a function with a similar name exists: `getpid` | ::: C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\libc-0.2.149\src\windows\mod.rs:491:5 | 491 | pub fn getpid() -> ::c_int; | -------------------------- similarly named function `getpid` defined here error[E0425]: cannot find function `getegid` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:691:20 | 691 | unsafe { libc::getegid() } | ^^^^^^^ help: a function with a similar name exists: `getpid` | ::: C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\libc-0.2.149\src\windows\mod.rs:491:5 | 491 | pub fn getpid() -> ::c_int; | -------------------------- similarly named function `getpid` defined here error[E0425]: cannot find function `getgroups` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:745:15 | 745 | libc::getgroups(1024, buff.as_mut_ptr()) | ^^^^^^^^^ not found in `libc` error[E0425]: cannot find value `buff` in this scope --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:783:21 | 783 | let mut count = buff.len() as c_int; | ^^^^ not found in this scope error[E0425]: cannot find value `res` in this scope --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:799:8 | 799 | if res < 0 { | ^^^ not found in this scope error[E0425]: cannot find value `buff` in this scope --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:803:9 | 803 | buff.dedup(); | ^^^^ not found in this scope error[E0425]: cannot find value `buff` in this scope --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:804:9 | 804 | buff.into_iter() | ^^^^ not found in this scope error[E0425]: cannot find function `setpwent` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:858:11 | 858 | libc::setpwent(); | ^^^^^^^^ not found in `libc` error[E0425]: cannot find function `endpwent` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:873:24 | 873 | unsafe { libc::endpwent() }; | ^^^^^^^^ not found in `libc` error[E0425]: cannot find function `getpwent` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:890:37 | 890 | let result = unsafe { libc::getpwent() }; | ^^^^^^^^ not found in `libc` error[E0425]: cannot find function `setuid` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\switch.rs:41:26 | 41 | match unsafe { libc::setuid(uid) } { | ^^^^^^ help: a function with a similar name exists: `getpid` | ::: C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\libc-0.2.149\src\windows\mod.rs:491:5 | 491 | pub fn getpid() -> ::c_int; | -------------------------- similarly named function `getpid` defined here error[E0425]: cannot find function `setgid` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\switch.rs:72:26 | 72 | match unsafe { libc::setgid(gid) } { | ^^^^^^ help: a function with a similar name exists: `getpid` | ::: C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\libc-0.2.149\src\windows\mod.rs:491:5 | 491 | pub fn getpid() -> ::c_int; | -------------------------- similarly named function `getpid` defined here error[E0425]: cannot find function `seteuid` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\switch.rs:103:26 | 103 | match unsafe { libc::seteuid(uid) } { | ^^^^^^^ not found in `libc` error[E0425]: cannot find function `setegid` in crate `libc` --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\switch.rs:134:26 | 134 | match unsafe { libc::setegid(gid) } { | ^^^^^^^ not found in `libc` error[E0599]: no function or associated item named `from_bytes` found for struct `OsStr` in the current scope --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:252:20 | 252 | T::from(OsStr::from_bytes(CStr::from_ptr(p).to_bytes())) | ^^^^^^^^^^ function or associated item not found in `OsStr` error[E0599]: no method named `as_bytes` found for reference `&OsStr` in the current scope --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:380:57 | 380 | let username = match CString::new(username.as_ref().as_bytes()) { | ^^^^^^^^ method not found in `&OsStr` Compiling unicode-normalization v0.1.22 error[E0599]: no method named `as_bytes` found for reference `&OsStr` in the current scope --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:495:59 | 495 | let groupname = match CString::new(groupname.as_ref().as_bytes()) { | ^^^^^^^^ method not found in `&OsStr` error[E0599]: no method named `as_bytes` found for reference `&OsStr` in the current scope --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\base.rs:782:47 | 782 | let name = CString::new(username.as_ref().as_bytes()).unwrap(); | ^^^^^^^^ method not found in `&OsStr` error[E0282]: type annotations needed --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\cache.rs:207:43 | 207 | Occupied(e) => return e.get().as_ref().map(Arc::clone), | ^^^^^^ cannot infer type for type parameter `V` error[E0282]: type annotations needed --> C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\users-0.11.0\src\cache.rs:288:43 | 288 | Occupied(e) => return e.get().as_ref().map(Arc::clone), | ^^^^^^ cannot infer type for type parameter `V` Some errors have detailed explanations: E0282, E0412, E0425, E0432, E0433, E0599. For more information about an error, try `rustc --explain E0282`. error: could not compile `users` (lib) due to 41 previous errors warning: build failed, waiting for other jobs to finish... error: failed to compile `exa v0.10.1`, intermediate artifacts can be found at `C:\Users\Nanao\AppData\Local\Temp\cargo-installiJkMjV`. To reuse those artifacts with a future compilation, set the environment variable `CARGO_TARGET_DIR` to that path. C:\Users\Nanao\Project\study\proc-macro-workshop\builder>cargo install libc Updating crates.io index error: there is nothing to install in `libc v0.2.149`, because it has no binaries `cargo install` is only for installing programs, and can't be used with libraries. To use a library crate, add it as a dependency to a Cargo project with `cargo add`. とまあこんな感じなので、バックドア的な方法でインストールしてあげる必要があります。 ...

2023年10月29日 · にあえん

「proc-macro-workshop」で学ぶ手続き型マクロ

Rustにハマりつつあるナナオです。 最近Rustばかり触っているのですが、Rustはpythonと比べるととにかくコーディングに時間がかかってしまうのが欠点だなと思うこの頃… 自前の構造体とか作って運用してると、気をつけないと同じよーな処理がプロジェクト内に点在してしまいがちだなと感じています。 (deriveを活用できていないケースとか) そこで今回はRustのメタプログラミングツール、マクロについて学んでいこうと思います。 -> 僕がマクロを学ぶきっかけになった記事はこちら 前提知識となるマクロの参考資料は以下。 マクロ - The Rust Programming Language 日本語版 Rustのマクロを覚える #Rust - Qiita マクロのチュートリアルを実践する マクロを学ぶためのちょうどいいリポジトリがありました。 GitHub - dtolnay/proc-macro-workshop: Learn to write Rust procedural macros [Rust Latam conference, Montevideo Uruguay, March 2019] マクロを使用するパターンについて、いくつかのケーススタディが用意されています。 bitfield builder debug seq sorted とりあえず聞き馴染みのあるbuilderからやってみます。 9つテストケースが用意されており、一つづつパスできるようにしていくことで、段階的にBuilderマクロを実装できるという内容になっています。 わかりやすい。。 ここからは自分の備忘録も兼ねて答えとなるコードを載せていきます。 もし自分で解きたいと言う場合はこれから先の閲覧は注意してください。 01-parse.rs これはとりあえずTokenStreamを返却できればいいだけですね。 必要なライブラリを追加してあげます。 cargo add syn quote とりあえずquote!マクロの結果を返却するだけでこのテストは通ります。 use proc_macro::TokenStream; use quote::quote; #[proc_macro_derive(Builder)] pub fn derive(input: TokenStream) -> TokenStream { let _ = input; let q = quote! {} q.into() } 02-create-builder.rs さて、ここからが本番です。 ...

2023年10月10日 · にあえん

Rustのfactorybot的なライブラリ「factori」とsqlxでモックデータを生成する【1】

pythonの単体テストでよく使っていたfactoryboyというツールがあるのですが、これが本当に使いやすい! factory_boy — Factory Boy stable documentation これとfixtureを使えば、大抵のテストケースに必要なデータを引数から取得することができます。 で、これと同じようなことをRustでもやりたいな〜と思っていたんですが、「factori」というライブラリがそれに相当するということで、備忘録を兼ねて触った感想などをここに書いていこうと思います。 使い方 とりあえずCargoパッケージに追加します。 [dependencies] factori = { version = "1.1.0" } fake = "2.8.0" uuid = { version = "1.4.1", features = [ "serde", "v4" ] } 使い方はメチャクチャ簡単で、定義された構造体にfactori!マクロを定義してあげれば、create!マクロから呼び出すことができます。 fakeというライブラリと組み合わせてテストデータを作る実装は以下のようになります。 use factori::{factori, create}; use fake::Fake; use fake::faker::name::raw::*; use fake::locales::JA_JP; use uuid::Uuid; #[derive(Debug)] pub struct User { id: Uuid, name: String, } factori!(User, { default { id = Uuid::new_v4(), name = Name(JA_JP).fake::<String>(), } }); fn main() { // Userを10人作成する let user: Vec<User> = [0; 10].iter().map(|_| create!(User)).collect(); println!("{:?}", user); } これだけでUserをちゃちゃっと作る実装ができました。 ...

2023年10月7日 · にあえん

次世代DBマイグレーションツール「sqldef」

先々月くらいにPrismaを知り、関連の記事をいろいろ書いていました。 prisma-client-pythonでpythonからORMを楽にやる prisma client pythonが実行しているNodeはどこにあるのか prismaでfactoryboyみたいなやつが作りたい ただ、最近Rustを触ることが多くてPrismaの使いどころがマイグレーションぐらいしかないのでちょっとしょんぼりしてたんですが、関連してちょっと気になるツールを見つけたので勉強がてら紹介します。 GitHub - sqldef/sqldef: Idempotent schema management for MySQL, PostgreSQL, SQLite, and SQL Server このツールを使うと、Prismaでいうschema.prismaをSQLファイルで管理できるようになるとのこと! すごい柔軟性!!!!! つまり、1つのSQLファイルと現在のDBを比較して、追加・変更・削除されたテーブルや列などの差分情報を読み取り、マイグレーションを行ってくれるという感じです。 ちなみに、sqlx関連で調べて見ていた参考にしていたブログはこちら。 [Rust] sqlxを使ってみる #Database - Qiita インストール まずは使用しているUbuntuにダウンロードしてみます。 私は普段使いがPostgresなので、以下のコマンドでpsqldefをインストールします。 curl -OL https://github.com/k0kubun/sqldef/releases/download/v0.16.9/psqldef_linux_amd64.tar.gz sudo tar xf psqldef_linux_amd64.tar.gz -C /usr/local/bin/ インストールできたか確認してみます。 % psqldef --help Usage: psqldef [option...] db_name Application Options: -U, --user=username PostgreSQL user name (default: postgres) -W, --password=password PostgreSQL user password, overridden by $PGPASSWORD -h, --host=hostname Host or socket directory to connect to the PostgreSQL server (default: 127.0.0.1) -p, --port=port Port used for the connection (default: 5432) --password-prompt Force PostgreSQL user password prompt -f, --file=filename Read schema SQL from the file, rather than stdin (default: -) --dry-run Don't run DDLs but just show them --export Just dump the current schema to stdout --enable-drop-table Enable destructive changes such as DROP (enable only table drops) --before-apply= Execute the given string before applying the regular DDLs --config= YAML file to specify: target_tables, skip_tables --help Show this help --version Show this version ヘルプコマンドが表示されたので、ちゃんとインストールできましたね。 ...

2023年10月6日 · にあえん

RustでAsync Dropができないか調べた

Rust、最近使い出しました。 テストを書くにあたって、テスト用のデータベース作成と削除をうまく実装できないか考えていて、調べるとDropというトレイトが使えるとわかりました。 ただ、Dropはasyncに対応していないので、どういう代替案があるかな〜と気になったので調べてみました。 そもそもDropトレイトとは? dropメソッドのみが定義されており、ここに実装を入れるとオブジェクトがメモリから開放される際に勝手に呼び出されるという仕組みです。 メモリ解放 - Rust By Example 日本語版 async-dropper 調べてみたら一応メジャーリリースしているasyncに対応したDropトレイトがありました。 async-dropper ちょっと使ってみましょう。 以下のようにパッケージを追加してあげます。 [dependencies] async-dropper = { version = "0.2.3", features = [ "tokio" ] } async-trait = "0.1.73" sqlx = { version = "0.7", features = [ "runtime-tokio", "postgres" ] } 普段からtokioを使っているので、そのfeaturesも入れてあげます。 tokioの対応バージョンは^1.29.1からとなっているので、比較的新しいバージョンじゃないと動かないようになってますね。 async-traitはトレイトにasyncメソッドを定義できるようになるマクロで、async-dropperを使用する際に役立つので入れておきます。 データベースの作成・削除に使用するためSQLXも入れておきます。 ついでにdocker-composeで使えるpostgresサーバーも作っておきましょう。 version: '3' services: db: image: postgres:15 container_name: postgres ports: - 5432:5432 environment: - POSTGRES_PASSWORD=example 次に実装です。 とりあえずデータベース作成をランダム文字列で行うような実装をしました。 use sqlx::postgres::{PgPool, PgPoolOptions}; use rand::{Rng}; const CHARSET: &[u8] = b"abcdefghijklmnopqrstuvwxyz"; const DBNAME_LEN: usize = 30; struct MockDBServer { pool: PgPool, } impl MockDBServer { async fn new() -> Self { let mut rng = rand::thread_rng(); let dbname: String = (0..DBNAME_LEN) .map(|_| { let idx = rng.gen_range(0..CHARSET.len()); char::from(unsafe { *CHARSET.get_unchecked(idx) }) }) .collect(); let pool = PgPoolOptions::new() .max_connections(5) .connect("postgres://postgres:example@localhost/postgres").await.unwrap(); sqlx::query(format!("CREATE DATABASE {};", dbname).as_str()) .bind(dbname) .execute(&pool).await.unwrap(); Self { pool } } } #[tokio::main] async fn main() { MockDBServer::new().await; } これを実行するとデータベースが作成されます。ただ作成されっぱなしになってしまいます。 ...

2023年10月4日 · にあえん

Windows11でRust使ってたら「error failed to run custom build command for `openssl sys v0.9.93`」がでたとき

新しく使いはじめたWindows11でcargo buildしたらこんなエラーが出ました。 error: failed to run custom build command for `openssl-sys v0.9.93` Caused by: process didn't exit successfully: `C:\Users\Nanao\Project\tools\sync-zaim\target\debug\build\openssl-sys-18a1f426c8f5f296\build-script-main` (exit code: 101) --- stdout cargo:rerun-if-env-changed=X86_64_PC_WINDOWS_MSVC_OPENSSL_LIB_DIR X86_64_PC_WINDOWS_MSVC_OPENSSL_LIB_DIR unset cargo:rerun-if-env-changed=OPENSSL_LIB_DIR OPENSSL_LIB_DIR unset cargo:rerun-if-env-changed=X86_64_PC_WINDOWS_MSVC_OPENSSL_INCLUDE_DIR X86_64_PC_WINDOWS_MSVC_OPENSSL_INCLUDE_DIR unset cargo:rerun-if-env-changed=OPENSSL_INCLUDE_DIR OPENSSL_INCLUDE_DIR unset cargo:rerun-if-env-changed=X86_64_PC_WINDOWS_MSVC_OPENSSL_DIR X86_64_PC_WINDOWS_MSVC_OPENSSL_DIR unset cargo:rerun-if-env-changed=OPENSSL_DIR OPENSSL_DIR unset note: vcpkg did not find openssl: Could not look up details of packages in vcpkg tree could not read status file updates dir: 指定されたパスが見つかりません。 (os error 3) --- stderr thread 'main' panicked at ' Could not find directory of OpenSSL installation, and this `-sys` crate cannot proceed without this knowledge. If OpenSSL is installed and this crate had trouble finding it, you can set the `OPENSSL_DIR` environment variable for the compilation process. Make sure you also have the development packages of openssl installed. For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora. If you're in a situation where you think the directory *should* be found automatically, please open a bug at https://github.com/sfackler/rust-openssl and include information about your system as well as this message. $HOST = x86_64-pc-windows-msvc $TARGET = x86_64-pc-windows-msvc openssl-sys = 0.9.93 It looks like you're compiling for MSVC but we couldn't detect an OpenSSL installation. If there isn't one installed then you can try the rust-openssl README for more information about how to download precompiled binaries of OpenSSL: https://github.com/sfackler/rust-openssl#windows ', C:\Users\Nanao\.cargo\registry\src\index.crates.io-6f17d22bba15001f\openssl-sys-0.9.93\build\find_normal.rs:190:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace warning: build failed, waiting for other jobs to finish... OpenSSLが存在しないから出てるエラーっぽい? ...

2023年10月2日 · にあえん

Windows11にwingetを使ってAWS CLIをインストールする

Windows11でのAWS CLIのセットアップの備忘録です。 あまりにも簡単すぎますが、wingetコマンドを使うだけです。 winget install Amazon.AWSCLI あとは再起動して、いつも通りaws configureとかで設定を追加します。

2023年10月1日 · にあえん

cargo buildしたら「error: linker `link.exe` not found」が出たとき

そのまんまなタイトルですが、備忘録のために解決方法を記載しておきます。 Windows11でRustの開発中、cargo buildしたらこんな感じでエラーが出ました。 error: linker `link.exe` not found | = note: program not found note: the msvc targets depend on the msvc linker but `link.exe` was not found note: please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option. note: VS Code is a different product, and is not sufficient. wingetコマンドでビルドツールをインストールしてあげましょう。 winget install Microsoft.VisualStudio.2022.BuildTools これが終わったら、Visual Studio Installerを起動します。 インストール済みのところに先ほどインストールしたビルドツールが表示されています。 ここの変更を押します。 ...

2023年10月1日 · にあえん

一般的なエンジニアがやるであろうWindowsインストール後のセットアップについて

最近、デスクトップPCのUbuntuがめちゃくちゃ調子が悪くなってしまったのと、確定申告を行うにあたって電子申告にLinuxが対応していないようなので、「ええい!もうUbuntuなんてこりごりでい!」ということでWindowsに載せ替えました。 まっさらな状態からセットアップを行っていくにあたって、備忘録も兼ねて文章に残しておこうと思います。 Braveのインストール Edgeがいくら使いやすくなったとて、今まで使っていたブラウザがBraveで同期などもしたかったのでインストールしました。 標準ブラウザじゃ話にならんので 開発環境周りの整備 ここら辺はパッケージマネージャーを活用しようと思い、Windows用のパッケージマネージャーならChocolateyとかかな…と思ってたんですが、いつの間にやら標準でパッケージマネージャーが搭載されるようになっていたようです。 Windowsのパッケージマネージャー「winget」を使ってみた | DevelopersIO これがまーーーーー素晴らしい。 例えば、VSCodeなら以下のコマンドで一発で導入できます。 winget install "Microsoft Visual Studio Code" ね?簡単でしょう? Rustのインストールも楽々できます。 winget install "Rustlang.Rustup" あまりにも素晴らしすぎる。 ちなみに、wingetからChocolateyのインストールもできます。 winget install Chocolatey Chocolateyのインストール後は再起動が必要なため、すぐには使用できません。 再起動後、コマンドが有効になっているか確認します。 > choco Chocolatey v2.2.2 Please run 'choco -?' or 'choco <command> -?' for help menu. うーん、なんかここまで楽だと逆に手ごたえがないですね。もちろんいい意味で。 そしてDockerもインストールしておきます。何でもできるなこれ。 winget install Docker.DockerDesktop こちらもインストール後は再起動が必要です。 WSLのセットアップ WSLはMicrosoft StoreからUbuntuをダウンロードしました。 wingetからでもダウンロードできます。 Ubuntu 22.04をインストールしたければ以下のコマンドで可能です。 (ほんとなんでもできるなこいつ) winget install Canonical.Ubuntu.2204 このインストールには結構時間がかかりますが、のんびり行きましょう。 あとターミナルですが、これもWindowsが提供してるやつがあるので使いましょう。 前にも使ったことがありますが、WSL、CMD、PowerShellを横断的に使えるので便利ですよ。(あと一応オフィシャルだから安心感ある) ほんでこれもwingetが使えます。 winget install Microsoft.WindowsTerminal ターミナルからWSLの軌道ができたら普段zshを使っているので、ここを参考にしてzshの環境構築を行いました。 https://zenn.dev/moroya/articles/0ab24a733e4b7a ...

2023年9月25日 · にあえん