From b68244165992915e66a9257e1e18cb59059846f8 Mon Sep 17 00:00:00 2001 From: nicholaslyang Date: Wed, 28 Aug 2024 16:27:23 -0400 Subject: [PATCH] Implementing persistence using spaces --- Cargo.lock | 602 +++++++++++++++++- Cargo.toml | 1 + crates/turborepo-analytics/Cargo.toml | 2 +- crates/turborepo-api-client/src/spaces.rs | 17 +- crates/turborepo-db/Cargo.toml | 16 + .../20240828183512_initial_tables.sql | 35 + crates/turborepo-db/src/lib.rs | 113 ++++ crates/turborepo-lib/Cargo.toml | 2 + crates/turborepo-lib/src/run/mod.rs | 1 + crates/turborepo-lib/src/run/summary/mod.rs | 37 +- .../turborepo-lib/src/run/summary/spaces.rs | 97 ++- crates/turborepo-telemetry/Cargo.toml | 2 +- 12 files changed, 854 insertions(+), 71 deletions(-) create mode 100644 crates/turborepo-db/Cargo.toml create mode 100644 crates/turborepo-db/migrations/20240828183512_initial_tables.sql create mode 100644 crates/turborepo-db/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 128d9683cc4d4..6f661fc759406 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -170,7 +170,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" dependencies = [ "concurrent-queue", - "event-listener", + "event-listener 2.5.3", "futures-core", ] @@ -321,7 +321,7 @@ version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" dependencies = [ - "event-listener", + "event-listener 2.5.3", ] [[package]] @@ -350,7 +350,7 @@ dependencies = [ "autocfg", "blocking", "cfg-if", - "event-listener", + "event-listener 2.5.3", "futures-lite", "libc", "signal-hook", @@ -423,6 +423,15 @@ dependencies = [ "syn 2.0.58", ] +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + [[package]] name = "atomic-waker" version = "1.1.0" @@ -636,6 +645,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "biome_console" version = "0.5.7" @@ -663,7 +678,7 @@ dependencies = [ "biome_json_parser", "biome_json_syntax", "biome_rowan", - "bitflags 2.5.0", + "bitflags 2.6.0", "indexmap 2.2.6", "serde", "serde_json", @@ -695,7 +710,7 @@ dependencies = [ "biome_rowan", "biome_text_edit", "biome_text_size", - "bitflags 2.5.0", + "bitflags 2.6.0", "bpaf", "oxc_resolver", "serde", @@ -782,7 +797,7 @@ dependencies = [ "biome_console", "biome_diagnostics", "biome_rowan", - "bitflags 2.5.0", + "bitflags 2.6.0", "drop_bomb", ] @@ -841,9 +856,12 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] [[package]] name = "block-buffer" @@ -1012,12 +1030,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" dependencies = [ "jobserver", "libc", + "shlex", ] [[package]] @@ -1188,6 +1207,12 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "const-random" version = "0.1.17" @@ -1283,6 +1308,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crc32fast" version = "1.3.2" @@ -1334,6 +1374,15 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.20" @@ -1362,7 +1411,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "crossterm_winapi", "libc", "mio 0.8.11", @@ -1490,7 +1539,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -1511,6 +1560,17 @@ dependencies = [ "uuid", ] +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + [[package]] name = "deranged" version = "0.3.9" @@ -1565,6 +1625,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] @@ -1646,6 +1707,12 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + [[package]] name = "downcast-rs" version = "1.2.0" @@ -1675,6 +1742,9 @@ name = "either" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +dependencies = [ + "serde", +] [[package]] name = "embedded-io" @@ -1744,12 +1814,34 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b" +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + [[package]] name = "event-listener" version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + [[package]] name = "fast_chemail" version = "0.9.6" @@ -1825,6 +1917,17 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "spin 0.9.8", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1912,6 +2015,17 @@ dependencies = [ "futures-util", ] +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + [[package]] name = "futures-io" version = "0.3.30" @@ -2153,14 +2267,23 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", "allocator-api2", ] +[[package]] +name = "hashlink" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +dependencies = [ + "hashbrown 0.14.5", +] + [[package]] name = "heck" version = "0.4.1" @@ -2194,6 +2317,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + [[package]] name = "hmac" version = "0.12.1" @@ -2203,6 +2335,15 @@ dependencies = [ "digest", ] +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "hostname" version = "0.3.1" @@ -2506,7 +2647,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "serde", ] @@ -2626,7 +2767,7 @@ dependencies = [ "curl", "curl-sys", "encoding_rs", - "event-listener", + "event-listener 2.5.3", "futures-lite", "http 0.2.11", "log", @@ -2698,9 +2839,9 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] @@ -2789,6 +2930,9 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] [[package]] name = "levenshtein" @@ -2840,6 +2984,17 @@ dependencies = [ "libc", ] +[[package]] +name = "libsqlite3-sys" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "libz-sys" version = "1.1.8" @@ -2895,7 +3050,7 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db2c024b41519440580066ba82aab04092b333e09066a5eb86c7c4890df31f22" dependencies = [ - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -2941,6 +3096,16 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + [[package]] name = "memchr" version = "2.6.3" @@ -3108,7 +3273,7 @@ version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efbf98e1bcb85cc441bbf7cdfb11070d2537a100e2697d75397b2584c32492d1" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "ctor", "napi-derive", "napi-sys", @@ -3227,7 +3392,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg-if", "cfg_aliases", "libc", @@ -3262,7 +3427,7 @@ version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "crossbeam-channel", "filetime", "fsevent-sys", @@ -3294,12 +3459,49 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -3307,6 +3509,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -3407,7 +3610,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4d6a8c22fc714f0c2373e6091bf6f5e9b37b1bc0b1184874b7e0a4e303d318f" dependencies = [ "dlv-list", - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -3513,6 +3716,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.0" @@ -3624,6 +3836,27 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1be1ec9e59f0360aefe84efa6f699198b685ab0d5718081e9f72aa2344289e2" +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.26" @@ -3957,7 +4190,7 @@ version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcb12f8fbf6c62614b0d56eb352af54f6a22410c3b079eb53ee93c7b97dd31d8" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cassowary", "compact_str", "crossterm 0.27.0", @@ -4015,6 +4248,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_users" version = "0.4.3" @@ -4144,6 +4386,26 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "rust-ini" version = "0.20.0" @@ -4214,7 +4476,7 @@ version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys 0.4.13", @@ -4597,6 +4859,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook" version = "0.3.17" @@ -4627,6 +4895,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + [[package]] name = "similar" version = "2.5.0" @@ -4662,6 +4940,9 @@ name = "smallvec" version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +dependencies = [ + "serde", +] [[package]] name = "smawk" @@ -4700,6 +4981,223 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlformat" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f895e3734318cc55f1fe66258926c9b910c124d47520339efecbb6c59cec7c1f" +dependencies = [ + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcfa89bea9500db4a0d038513d7a060566bfc51d46d1c014847049a45cce85e8" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06e2f2bd861719b1f3f0c7dbe1d80c30bf59e76cf019f07d9014ed7eefb8e08" +dependencies = [ + "atoi", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "either", + "event-listener 5.3.1", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashbrown 0.14.5", + "hashlink", + "hex", + "indexmap 2.2.6", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlformat", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f998a9defdbd48ed005a89362bd40dd2117502f15294f61c8d47034107dbbdc" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 2.0.58", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d100558134176a2629d46cec0c8891ba0be8910f7896abfdb75ef4ab6f4e7ce" +dependencies = [ + "dotenvy", + "either", + "heck 0.5.0", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 2.0.58", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cac0ab331b14cb3921c62156d913e4c15b74fb6ec0f3146bd4ef6e4fb3c12" +dependencies = [ + "atoi", + "base64 0.22.1", + "bitflags 2.6.0", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9734dbce698c67ecf67c442f768a5e90a49b2a4d61a9f1d59f73874bd4cf0710" +dependencies = [ + "atoi", + "base64 0.22.1", + "bitflags 2.6.0", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75b419c3c1b1697833dd927bdc4c6545a620bc1bbafabd44e1efbe9afcd337e" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "serde_urlencoded", + "sqlx-core", + "tracing", + "url", +] [[package]] name = "stability" @@ -4747,6 +5245,17 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9557cb6521e8d009c51a8666f09356f4b817ba9ba0981a305bd86aee47bd35c" +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + [[package]] name = "strsim" version = "0.11.1" @@ -5752,6 +6261,19 @@ dependencies = [ "tracing", ] +[[package]] +name = "turborepo-db" +version = "0.1.0" +dependencies = [ + "camino", + "serde_json", + "sqlx", + "thiserror", + "turbopath", + "turborepo-api-client", + "uuid", +] + [[package]] name = "turborepo-dirs" version = "0.1.0" @@ -5934,6 +6456,7 @@ dependencies = [ "turborepo-auth", "turborepo-cache", "turborepo-ci", + "turborepo-db", "turborepo-dirs", "turborepo-env", "turborepo-errors", @@ -5950,6 +6473,7 @@ dependencies = [ "turborepo-vercel-api-mock", "twox-hash", "uds_windows", + "uuid", "wax", "webbrowser", "which", @@ -6294,6 +6818,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-properties" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ea75f83c0137a9b98608359a5f1af8144876eb67bcb1ce837368e906a9f524" + [[package]] name = "unicode-segmentation" version = "1.10.1" @@ -6312,6 +6842,12 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + [[package]] name = "unsafe-libyaml" version = "0.2.11" @@ -6488,6 +7024,12 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" version = "0.2.91" @@ -6649,6 +7191,16 @@ dependencies = [ "once_cell", ] +[[package]] +name = "whoami" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +dependencies = [ + "redox_syscall 0.4.1", + "wasite", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 5e34955203a0d..00599ff6a367f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -188,6 +188,7 @@ triomphe = "0.1.13" tui-term = { version = "=0.1.9", default-features = false } url = "2.2.2" urlencoding = "2.1.2" +uuid = { version = "1.5.0", features = ["v4"] } webbrowser = "0.8.7" which = "4.4.0" unicode-segmentation = "1.10.1" diff --git a/crates/turborepo-analytics/Cargo.toml b/crates/turborepo-analytics/Cargo.toml index 554c3a5675e63..c9d07f83742e4 100644 --- a/crates/turborepo-analytics/Cargo.toml +++ b/crates/turborepo-analytics/Cargo.toml @@ -16,4 +16,4 @@ tokio = { workspace = true, features = ["full", "time"] } tracing = { workspace = true } turborepo-api-client = { workspace = true } turborepo-vercel-api = { workspace = true } -uuid = { version = "1.5.0", features = ["v4"] } +uuid = { workspace = true, features = ["v4"] } diff --git a/crates/turborepo-api-client/src/spaces.rs b/crates/turborepo-api-client/src/spaces.rs index cc6f11a78e90e..72b7fd1b230bc 100644 --- a/crates/turborepo-api-client/src/spaces.rs +++ b/crates/turborepo-api-client/src/spaces.rs @@ -13,6 +13,15 @@ pub enum RunStatus { Completed, } +impl AsRef for RunStatus { + fn as_ref(&self) -> &str { + match self { + RunStatus::Running => "RUNNING", + RunStatus::Completed => "COMPLETED", + } + } +} + #[derive(Serialize)] pub struct SpaceClientSummary { pub id: &'static str, @@ -144,13 +153,13 @@ impl APIClient { &self, space_id: &str, api_auth: &APIAuth, - payload: CreateSpaceRunPayload, + payload: &CreateSpaceRunPayload, ) -> Result { let url = format!("/v0/spaces/{}/runs", space_id); let request_builder = self .create_request_builder(&url, api_auth, Method::POST) .await? - .json(&payload); + .json(payload); let response = retry::make_retryable_request(request_builder, retry::RetryStrategy::Timeout) @@ -167,7 +176,7 @@ impl APIClient { space_id: &str, run_id: &str, api_auth: &APIAuth, - task: SpaceTaskSummary, + task: &SpaceTaskSummary, ) -> Result<(), Error> { let request_builder = self .create_request_builder( @@ -176,7 +185,7 @@ impl APIClient { Method::POST, ) .await? - .json(&task); + .json(task); retry::make_retryable_request(request_builder, retry::RetryStrategy::Timeout) .await? diff --git a/crates/turborepo-db/Cargo.toml b/crates/turborepo-db/Cargo.toml new file mode 100644 index 0000000000000..b4fd3b4ffb5a9 --- /dev/null +++ b/crates/turborepo-db/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "turborepo-db" +version = "0.1.0" +edition = "2021" + +[dependencies] +camino = { workspace = true } +serde_json = { workspace = true } +sqlx = { version = "0.8.1", features = ["runtime-tokio", "sqlite"] } +thiserror = { workspace = true } +turbopath = { workspace = true } +turborepo-api-client = { workspace = true } +uuid = { workspace = true, features = ["v4"] } + +[lints] +workspace = true diff --git a/crates/turborepo-db/migrations/20240828183512_initial_tables.sql b/crates/turborepo-db/migrations/20240828183512_initial_tables.sql new file mode 100644 index 0000000000000..6f33c8f1d8330 --- /dev/null +++ b/crates/turborepo-db/migrations/20240828183512_initial_tables.sql @@ -0,0 +1,35 @@ +CREATE TABLE IF NOT EXISTS runs ( + id TEXT PRIMARY KEY, -- primary key should be uuid + start_time INTEGER NOT NULL, + end_time INTEGER, + exit_code INTEGER, + status TEXT NOT NULL, + command TEXT NOT NULL, + package_inference_root TEXT, + context TEXT NOT NULL, + git_branch TEXT, + git_sha TEXT, + origination_user TEXT NOT NULL, + client_id TEXT NOT NULL, + client_name TEXT NOT NULL, + client_version TEXT NOT NULL +); + +CREATE TABLE IF NOT EXISTS tasks ( + id TEXT PRIMARY KEY, + run_id TEXT NOT NULL, + name TEXT NOT NULL, + package TEXT NOT NULL, + hash TEXT NOT NULL, + start_time INTEGER NOT NULL, + end_time INTEGER NOT NULL, + cache_status TEXT NOT NULL, + exit_code INTEGER, + logs TEXT NOT NULL +); + +CREATE TABLE IF NOT EXISTS task_dependencies ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + task_id TEXT NOT NULL, + dependency_id TEXT NOT NULL +); \ No newline at end of file diff --git a/crates/turborepo-db/src/lib.rs b/crates/turborepo-db/src/lib.rs new file mode 100644 index 0000000000000..7ac14ce407cd8 --- /dev/null +++ b/crates/turborepo-db/src/lib.rs @@ -0,0 +1,113 @@ +use camino::Utf8Path; +use sqlx::{Pool, Sqlite, SqlitePool}; +use thiserror::Error; +use turbopath::{AbsoluteSystemPath, AbsoluteSystemPathBuf}; +use turborepo_api_client::spaces::{CreateSpaceRunPayload, RunStatus, SpaceTaskSummary}; +use uuid::Uuid; + +#[derive(Debug, Error)] +pub enum Error { + #[error("failed to connect to database: {0}")] + Sqlx(#[from] sqlx::Error), + #[error("failed to migrate database: {0}")] + Migrate(#[from] sqlx::migrate::MigrateError), + #[error("failed to serialize")] + Serialize(#[from] serde_json::Error), +} + +#[derive(Clone)] +pub struct DatabaseHandle { + pool: Pool, +} + +impl DatabaseHandle { + pub async fn new(cache_dir: &Utf8Path, repo_root: &AbsoluteSystemPath) -> Result { + let cache_dir = AbsoluteSystemPathBuf::from_unknown(&repo_root, &cache_dir); + let pool = SqlitePool::connect(&format!( + "sqlite://{}?mode=rwc", + cache_dir.join_component("turbo.db") + )) + .await?; + + sqlx::migrate!().run(&pool).await?; + + Ok(Self { pool }) + } + + pub async fn create_run(&self, payload: &CreateSpaceRunPayload) -> Result { + let id = Uuid::new_v4(); + sqlx::query( + "INSERT INTO runs ( + id, + start_time, + status, + command, + package_inference_root, + context, + git_branch, + git_sha, + origination_user, + client_id, + client_name, + client_version + ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)", + ) + .bind(id.to_string()) + .bind(payload.start_time) + .bind(payload.status.as_ref()) + .bind(&payload.command) + .bind(&payload.package_inference_root) + .bind(payload.run_context) + .bind(&payload.git_branch) + .bind(&payload.git_sha) + .bind(&payload.user) + .bind(payload.client.id) + .bind(payload.client.name) + .bind(&payload.client.version) + .execute(&self.pool) + .await?; + + Ok(id) + } + + pub async fn finish_run(&self, id: Uuid, end_time: i64, exit_code: i32) -> Result<(), Error> { + sqlx::query("UPDATE runs SET status = $1, end_time = $2, exit_code = $3 WHERE id = $4") + .bind(RunStatus::Completed.as_ref()) + .bind(end_time) + .bind(exit_code) + .bind(id.to_string()) + .execute(&self.pool) + .await?; + + Ok(()) + } + + pub async fn finish_task(&self, id: Uuid, summary: &SpaceTaskSummary) -> Result<(), Error> { + sqlx::query( + "INSERT INTO tasks ( + run_id, + name, + package, + hash, + start_time, + end_time, + cache_status, + exit_code, + logs + ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)", + ) + .bind(id.to_string()) + .bind(&summary.name) + .bind(&summary.workspace) + .bind(&summary.hash) + .bind(summary.start_time) + .bind(summary.end_time) + .bind(serde_json::to_string(&summary.cache)?) + .bind(summary.exit_code) + .bind(&summary.logs) + .execute(&self.pool) + .await?; + + Ok(()) + } +} diff --git a/crates/turborepo-lib/Cargo.toml b/crates/turborepo-lib/Cargo.toml index 0785c49941ca7..3961045a23400 100644 --- a/crates/turborepo-lib/Cargo.toml +++ b/crates/turborepo-lib/Cargo.toml @@ -118,6 +118,7 @@ turborepo-api-client = { workspace = true } turborepo-auth = { path = "../turborepo-auth" } turborepo-cache = { workspace = true } turborepo-ci = { workspace = true } +turborepo-db = { path = "../turborepo-db" } turborepo-dirs = { path = "../turborepo-dirs" } turborepo-env = { workspace = true } turborepo-errors = { workspace = true } @@ -133,6 +134,7 @@ turborepo-unescape = { workspace = true } turborepo-vercel-api = { path = "../turborepo-vercel-api" } twox-hash = "1.6.3" uds_windows = "1.0.2" +uuid = { version = "1.5.0", features = ["v4"] } wax = { workspace = true } webbrowser = { workspace = true } which = { workspace = true } diff --git a/crates/turborepo-lib/src/run/mod.rs b/crates/turborepo-lib/src/run/mod.rs index 8c4949f22cdf9..2e06390b9746e 100644 --- a/crates/turborepo-lib/src/run/mod.rs +++ b/crates/turborepo-lib/src/run/mod.rs @@ -411,6 +411,7 @@ impl Run { self.api_auth.clone(), Vendor::get_user(), &self.scm, + self.opts.cache_opts.cache_dir.clone(), ); let mut visitor = Visitor::new( diff --git a/crates/turborepo-lib/src/run/summary/mod.rs b/crates/turborepo-lib/src/run/summary/mod.rs index 5fc65ba7aa54a..02afedec0db2d 100644 --- a/crates/turborepo-lib/src/run/summary/mod.rs +++ b/crates/turborepo-lib/src/run/summary/mod.rs @@ -13,6 +13,7 @@ mod task; mod task_factory; use std::{collections::HashSet, io, io::Write}; +use camino::Utf8PathBuf; use chrono::{DateTime, Local}; pub use duration::TurboDuration; pub use execution::{TaskExecutionSummary, TaskTracker}; @@ -69,6 +70,8 @@ pub enum Error { Env(#[source] turborepo_env::Error), #[error("failed to construct task summary: {0}")] TaskSummary(#[from] task_factory::Error), + #[error(transparent)] + Database(#[from] turborepo_db::Error), } // NOTE: When changing this, please ensure that the server side is updated to @@ -136,24 +139,28 @@ impl RunTracker { api_auth: Option, user: String, scm: &SCM, + cache_dir: Utf8PathBuf, ) -> Self { let scm = SCMState::get(env_at_execution_start, scm, repo_root); - - let spaces_client_handle = - SpacesClient::new(spaces_id.clone(), spaces_api_client, api_auth).and_then( - |spaces_client| { - let payload = CreateSpaceRunPayload::new( - started_at, - synthesized_command.clone(), - package_inference_root, - scm.branch.clone(), - scm.sha.clone(), - version.to_string(), - user.clone(), - ); - spaces_client.start(payload).ok() - }, + let spaces_client_handle = SpacesClient::new( + spaces_id.clone(), + spaces_api_client, + api_auth, + repo_root.to_owned(), + cache_dir, + ) + .and_then(|spaces_client| { + let payload = CreateSpaceRunPayload::new( + started_at, + synthesized_command.clone(), + package_inference_root, + scm.branch.clone(), + scm.sha.clone(), + version.to_string(), + user.clone(), ); + spaces_client.start(payload).ok() + }); RunTracker { scm, diff --git a/crates/turborepo-lib/src/run/summary/spaces.rs b/crates/turborepo-lib/src/run/summary/spaces.rs index 3616fc5da1aab..0000d87dff405 100644 --- a/crates/turborepo-lib/src/run/summary/spaces.rs +++ b/crates/turborepo-lib/src/run/summary/spaces.rs @@ -5,18 +5,22 @@ use std::{ time::Duration, }; +use camino::Utf8PathBuf; use chrono::{DateTime, Local}; use futures::{stream::FuturesUnordered, StreamExt}; use itertools::Itertools; use serde::Serialize; -use tokio::{sync::mpsc::Sender, task::JoinHandle}; +use tokio::{join, sync::mpsc::Sender, task::JoinHandle}; use tracing::debug; +use turbopath::AbsoluteSystemPathBuf; use turborepo_api_client::{ spaces::{CreateSpaceRunPayload, SpaceTaskSummary, SpacesCacheStatus}, APIAuth, APIClient, }; use turborepo_cache::CacheHitMetadata; +use turborepo_db::DatabaseHandle; use turborepo_vercel_api::SpaceRun; +use uuid::Uuid; use super::execution::TaskExecutionSummary; use crate::{ @@ -33,6 +37,8 @@ pub struct SpacesClient { space_id: String, api_client: APIClient, api_auth: APIAuth, + repo_root: AbsoluteSystemPathBuf, + cache_dir: Utf8PathBuf, request_timeout: Duration, } @@ -143,10 +149,13 @@ impl SpacesClient { space_id: Option, api_client: APIClient, api_auth: Option, + repo_root: AbsoluteSystemPathBuf, + cache_dir: Utf8PathBuf, ) -> Option { // If space_id is empty, we don't build a client let space_id = space_id?; let is_linked = api_auth.as_ref().map_or(false, |auth| auth.is_linked()); + println!("is_linked: {is_linked}"); if !is_linked { // TODO: Add back spaces warning with new UI return None; @@ -157,6 +166,8 @@ impl SpacesClient { space_id, api_client, api_auth, + repo_root, + cache_dir, request_timeout: Duration::from_secs(10), }) } @@ -167,9 +178,10 @@ impl SpacesClient { ) -> Result { let (tx, mut rx) = tokio::sync::mpsc::channel(100); let handle = tokio::spawn(async move { + let db_handle = DatabaseHandle::new(&self.cache_dir, &self.repo_root).await?; let mut errors = Vec::new(); - let run = match self.create_run(create_run_payload).await { - Ok(run) => run, + let (run, db_id) = match self.create_run(db_handle.clone(), create_run_payload).await { + Ok((run, db_id)) => (run, db_id), Err(e) => { debug!("error creating space run: {}", e); errors.push(e); @@ -185,9 +197,11 @@ impl SpacesClient { SpaceRequest::FinishedRun { end_time, exit_code, - } => self.finish_run_handler(&run, end_time, exit_code), + } => { + self.finish_run_handler(db_handle.clone(), db_id, &run, end_time, exit_code) + } SpaceRequest::FinishedTask { summary } => { - self.finish_task_handler(*summary, &run) + self.finish_task_handler(db_handle.clone(), db_id, *summary, &run) } }; requests.push(request) @@ -209,17 +223,27 @@ impl SpacesClient { Ok(SpacesClientHandle { handle, tx }) } - async fn create_run(&self, payload: CreateSpaceRunPayload) -> Result { - Ok(tokio::time::timeout( - self.request_timeout, - self.api_client - .create_space_run(&self.space_id, &self.api_auth, payload), - ) - .await??) + async fn create_run( + &self, + db_handle: DatabaseHandle, + payload: CreateSpaceRunPayload, + ) -> Result<(SpaceRun, Uuid), Error> { + let (api_result, db_result) = join!( + tokio::time::timeout( + self.request_timeout, + self.api_client + .create_space_run(&self.space_id, &self.api_auth, &payload), + ), + db_handle.create_run(&payload), + ); + + Ok((api_result??, db_result?)) } fn finish_task_handler( &self, + db_handle: DatabaseHandle, + db_id: Uuid, task_summary: SpaceTaskSummary, run: &SpaceRun, ) -> JoinHandle> { @@ -230,17 +254,25 @@ impl SpacesClient { let run_id = run.id.clone(); let api_auth = self.api_auth.clone(); tokio::spawn(async move { - Ok(tokio::time::timeout( - timeout, - api_client.create_task_summary(&space_id, &run_id, &api_auth, task_summary), - ) - .await??) + let (result1, result2) = join!( + tokio::time::timeout( + timeout, + api_client.create_task_summary(&space_id, &run_id, &api_auth, &task_summary), + ), + db_handle.finish_task(db_id, &task_summary) + ); + result1??; + result2?; + + Ok(()) }) } // Called by the worker thread upon receiving a SpaceRequest::FinishedRun fn finish_run_handler( &self, + db_handle: DatabaseHandle, + db_id: Uuid, run: &SpaceRun, end_time: i64, exit_code: i32, @@ -251,11 +283,18 @@ impl SpacesClient { let run_id = run.id.clone(); let api_auth = self.api_auth.clone(); tokio::spawn(async move { - Ok(tokio::time::timeout( - timeout, - api_client.finish_space_run(&space_id, &run_id, &api_auth, end_time, exit_code), - ) - .await??) + let (result1, result2) = join!( + tokio::time::timeout( + timeout, + api_client.finish_space_run(&space_id, &run_id, &api_auth, end_time, exit_code), + ), + db_handle.finish_run(db_id, end_time, exit_code) + ); + + result1??; + result2?; + + Ok(()) }) } } @@ -354,6 +393,7 @@ mod tests { use chrono::Local; use pretty_assertions::assert_eq; use test_case::test_case; + use turbopath::AbsoluteSystemPathBuf; use turborepo_api_client::{ spaces::{CreateSpaceRunPayload, SpaceTaskSummary}, APIAuth, APIClient, @@ -364,7 +404,7 @@ mod tests { }; use super::trim_logs; - use crate::run::summary::spaces::SpacesClient; + use crate::{opts::Opts, run::summary::spaces::SpacesClient}; #[test_case(vec![] ; "empty")] #[test_case(vec![SpaceTaskSummary::default()] ; "one task summary")] @@ -387,9 +427,16 @@ mod tests { team_id: Some(EXPECTED_TEAM_ID.to_string()), team_slug: Some(EXPECTED_TEAM_SLUG.to_string()), }); + let temp_dir = tempfile::tempdir()?; - let spaces_client = - SpacesClient::new(Some(EXPECTED_SPACE_ID.to_string()), api_client, api_auth).unwrap(); + let spaces_client = SpacesClient::new( + Some(EXPECTED_SPACE_ID.to_string()), + api_client, + api_auth, + AbsoluteSystemPathBuf::try_from(temp_dir.path()).unwrap(), + Opts::default(), + ) + .unwrap(); let start_time = Local::now(); let spaces_client_handle = spaces_client.start(CreateSpaceRunPayload::new( diff --git a/crates/turborepo-telemetry/Cargo.toml b/crates/turborepo-telemetry/Cargo.toml index a5013a16b439e..399cabb844dee 100644 --- a/crates/turborepo-telemetry/Cargo.toml +++ b/crates/turborepo-telemetry/Cargo.toml @@ -35,4 +35,4 @@ turborepo-dirs = { path = "../turborepo-dirs" } turborepo-ui = { workspace = true } turborepo-vercel-api = { workspace = true } url = { workspace = true } -uuid = { version = "1.5.0", features = ["v4"] } +uuid = { workspace = true, features = ["v4"] }