From 1c74ccf4902e677db861a87280d060a58195e7ef Mon Sep 17 00:00:00 2001 From: "heesk0223@gmail.com" Date: Tue, 2 Jun 2026 00:37:49 +0900 Subject: [PATCH] Discover Rust build artifacts and Cargo-generated files. --- .github/ISSUE_TEMPLATE/EPIC.md | 2 - .github/ISSUE_TEMPLATE/FEATURE_TESK.md | 2 - .github/ISSUE_TEMPLATE/TASK.md | 2 - Cargo.lock | 562 ++++++++++++++++++ apps/dustfril-cli/Cargo.toml | 6 + apps/dustfril-cli/src/cli.rs | 22 + apps/dustfril-cli/src/commands/analyze.rs | 3 + apps/dustfril-cli/src/commands/clean.rs | 3 + apps/dustfril-cli/src/commands/mod.rs | 3 + apps/dustfril-cli/src/commands/scan.rs | 20 + apps/dustfril-cli/src/main.rs | 23 +- crates/dustfril-core/Cargo.toml | 3 + .../src/detector/cargo_project.rs | 6 + crates/dustfril-core/src/detector/git.rs | 23 + crates/dustfril-core/src/detector/mod.rs | 11 +- crates/dustfril-core/src/detector/registry.rs | 23 + crates/dustfril-core/src/detector/scan.rs | 41 ++ crates/dustfril-core/src/detector/target.rs | 16 + crates/dustfril-core/src/detector/tests.rs | 38 ++ crates/dustfril-core/src/lib.rs | 5 - .../src/models/artifact_location.rs | 18 + .../dustfril-core/src/models/artifact_type.rs | 24 + crates/dustfril-core/src/models/mod.rs | 7 + .../dustfril-core/src/models/scan_result.rs | 6 + 24 files changed, 855 insertions(+), 14 deletions(-) create mode 100644 apps/dustfril-cli/src/cli.rs create mode 100644 apps/dustfril-cli/src/commands/analyze.rs create mode 100644 apps/dustfril-cli/src/commands/clean.rs create mode 100644 apps/dustfril-cli/src/commands/mod.rs create mode 100644 apps/dustfril-cli/src/commands/scan.rs create mode 100644 crates/dustfril-core/src/detector/cargo_project.rs create mode 100644 crates/dustfril-core/src/detector/git.rs create mode 100644 crates/dustfril-core/src/detector/registry.rs create mode 100644 crates/dustfril-core/src/detector/scan.rs create mode 100644 crates/dustfril-core/src/detector/target.rs create mode 100644 crates/dustfril-core/src/detector/tests.rs create mode 100644 crates/dustfril-core/src/models/artifact_location.rs create mode 100644 crates/dustfril-core/src/models/artifact_type.rs create mode 100644 crates/dustfril-core/src/models/scan_result.rs diff --git a/.github/ISSUE_TEMPLATE/EPIC.md b/.github/ISSUE_TEMPLATE/EPIC.md index 2481fdb..aa1ce45 100644 --- a/.github/ISSUE_TEMPLATE/EPIC.md +++ b/.github/ISSUE_TEMPLATE/EPIC.md @@ -5,8 +5,6 @@ title: '[EPIC] ' labels: epic --- ---- - ## Goal ## Includes diff --git a/.github/ISSUE_TEMPLATE/FEATURE_TESK.md b/.github/ISSUE_TEMPLATE/FEATURE_TESK.md index a583200..586b6dc 100644 --- a/.github/ISSUE_TEMPLATE/FEATURE_TESK.md +++ b/.github/ISSUE_TEMPLATE/FEATURE_TESK.md @@ -5,8 +5,6 @@ title: '[FEATURE] ' labels: enhancement --- ---- - ## Description ## Tasks diff --git a/.github/ISSUE_TEMPLATE/TASK.md b/.github/ISSUE_TEMPLATE/TASK.md index 59f1286..1c6afdb 100644 --- a/.github/ISSUE_TEMPLATE/TASK.md +++ b/.github/ISSUE_TEMPLATE/TASK.md @@ -5,8 +5,6 @@ title: '[TASK] ' labels: task --- ---- - ## Description ## Done When diff --git a/Cargo.lock b/Cargo.lock index 0c58494..0eb02ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,13 +2,575 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" + +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "bitflags" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "clap" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + [[package]] name = "dustfril-cli" version = "0.1.0" dependencies = [ + "clap", "dustfril-core", ] [[package]] name = "dustfril-core" version = "0.1.0" +dependencies = [ + "tempfile", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", + "wasip3", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", + "serde", + "serde_core", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "log" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" + +[[package]] +name = "memchr" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "wasip2" +version = "1.0.3+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +dependencies = [ + "wit-bindgen 0.57.1", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", +] + +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/apps/dustfril-cli/Cargo.toml b/apps/dustfril-cli/Cargo.toml index dcf37cf..7b70749 100644 --- a/apps/dustfril-cli/Cargo.toml +++ b/apps/dustfril-cli/Cargo.toml @@ -3,5 +3,11 @@ name = "dustfril-cli" version = "0.1.0" edition = "2024" +[[bin]] +name = "dfr" +path = "src/main.rs" + [dependencies] dustfril-core = { path = "../../crates/dustfril-core" } + +clap = { version = "4", features = ["derive"] } \ No newline at end of file diff --git a/apps/dustfril-cli/src/cli.rs b/apps/dustfril-cli/src/cli.rs new file mode 100644 index 0000000..be8c1b0 --- /dev/null +++ b/apps/dustfril-cli/src/cli.rs @@ -0,0 +1,22 @@ +use clap::{Parser, Subcommand}; + +/// DustFril CLI +#[derive(Parser, Debug)] +#[command(name = "dfr", version, about = "Rust artifact analyzer and cleaner")] +pub struct Cli { + #[command(subcommand)] + pub command: Commands, +} + +/// Available commands +#[derive(Subcommand, Debug)] +pub enum Commands { + /// Scan Rust artifacts + Scan, + + /// Analyze disk usage + Analyze, + + /// Clean artifacts + Clean, +} diff --git a/apps/dustfril-cli/src/commands/analyze.rs b/apps/dustfril-cli/src/commands/analyze.rs new file mode 100644 index 0000000..ef60fcc --- /dev/null +++ b/apps/dustfril-cli/src/commands/analyze.rs @@ -0,0 +1,3 @@ +pub fn execute() { + println!("Analyze command is not implemented yet."); +} diff --git a/apps/dustfril-cli/src/commands/clean.rs b/apps/dustfril-cli/src/commands/clean.rs new file mode 100644 index 0000000..d85d8e6 --- /dev/null +++ b/apps/dustfril-cli/src/commands/clean.rs @@ -0,0 +1,3 @@ +pub fn execute() { + println!("Clean command is not implemented yet."); +} diff --git a/apps/dustfril-cli/src/commands/mod.rs b/apps/dustfril-cli/src/commands/mod.rs new file mode 100644 index 0000000..3e49019 --- /dev/null +++ b/apps/dustfril-cli/src/commands/mod.rs @@ -0,0 +1,3 @@ +pub mod analyze; +pub mod clean; +pub mod scan; diff --git a/apps/dustfril-cli/src/commands/scan.rs b/apps/dustfril-cli/src/commands/scan.rs new file mode 100644 index 0000000..c86e69c --- /dev/null +++ b/apps/dustfril-cli/src/commands/scan.rs @@ -0,0 +1,20 @@ +use std::path::Path; + +use dustfril_core::detector; + +pub fn execute() { + let result = detector::scan(Path::new(".")); + + if result.artifacts.is_empty() { + println!("No Rust artifacts found."); + return; + } + + println!("Found {} artifact(s)\n", result.artifacts.len()); + + for artifact in result.artifacts { + println!("[{}]", artifact.artifact_type); + + println!(" {}\n", artifact.path.display()); + } +} diff --git a/apps/dustfril-cli/src/main.rs b/apps/dustfril-cli/src/main.rs index d9e4543..2f739b7 100644 --- a/apps/dustfril-cli/src/main.rs +++ b/apps/dustfril-cli/src/main.rs @@ -1,5 +1,24 @@ -use dustfril_core::scan; +mod cli; +mod commands; + +use clap::Parser; + +use cli::{Cli, Commands}; fn main() { - scan(); + let cli = Cli::parse(); + + match cli.command { + Commands::Scan => { + commands::scan::execute(); + } + + Commands::Analyze => { + commands::analyze::execute(); + } + + Commands::Clean => { + commands::clean::execute(); + } + } } diff --git a/crates/dustfril-core/Cargo.toml b/crates/dustfril-core/Cargo.toml index dd15295..9164324 100644 --- a/crates/dustfril-core/Cargo.toml +++ b/crates/dustfril-core/Cargo.toml @@ -4,3 +4,6 @@ version = "0.1.0" edition = "2024" [dependencies] + +[dev-dependencies] +tempfile = "3.0" \ No newline at end of file diff --git a/crates/dustfril-core/src/detector/cargo_project.rs b/crates/dustfril-core/src/detector/cargo_project.rs new file mode 100644 index 0000000..5dcc082 --- /dev/null +++ b/crates/dustfril-core/src/detector/cargo_project.rs @@ -0,0 +1,6 @@ +use std::path::Path; + +/// Cargo project detection and artifact scanning. +pub fn is_cargo_project(root: &Path) -> bool { + root.join("Cargo.toml").exists() +} diff --git a/crates/dustfril-core/src/detector/git.rs b/crates/dustfril-core/src/detector/git.rs new file mode 100644 index 0000000..4309869 --- /dev/null +++ b/crates/dustfril-core/src/detector/git.rs @@ -0,0 +1,23 @@ +use std::{env, path::Path}; + +use crate::models::{ArtifactLocation, ArtifactType}; + +pub fn detect() -> Option { + // TODO: + // Replace HOME lookup with dirs::home_dir() + // for cross-platform support. + let Ok(home_dir) = env::var("HOME") else { + return None; + }; + + let git_path = Path::new(&home_dir).join(".cargo").join("git"); + + if !git_path.exists() { + return None; + } + + Some(ArtifactLocation { + path: git_path, + artifact_type: ArtifactType::CargoGit, + }) +} diff --git a/crates/dustfril-core/src/detector/mod.rs b/crates/dustfril-core/src/detector/mod.rs index 4817161..5b89cf9 100644 --- a/crates/dustfril-core/src/detector/mod.rs +++ b/crates/dustfril-core/src/detector/mod.rs @@ -1 +1,10 @@ -//! Detector module. +mod cargo_project; +mod git; +mod registry; +mod scan; +mod target; + +#[cfg(test)] +mod tests; + +pub use scan::{scan, scan_global, scan_project}; diff --git a/crates/dustfril-core/src/detector/registry.rs b/crates/dustfril-core/src/detector/registry.rs new file mode 100644 index 0000000..e9b4ca8 --- /dev/null +++ b/crates/dustfril-core/src/detector/registry.rs @@ -0,0 +1,23 @@ +use std::{env, path::Path}; + +use crate::models::{ArtifactLocation, ArtifactType}; + +pub fn detect() -> Option { + // TODO: + // Replace HOME lookup with dirs::home_dir() + // for cross-platform support. + let Ok(home_dir) = env::var("HOME") else { + return None; + }; + + let registry_path = Path::new(&home_dir).join(".cargo").join("registry"); + + if !registry_path.exists() { + return None; + } + + Some(ArtifactLocation { + path: registry_path, + artifact_type: ArtifactType::CargoRegistry, + }) +} diff --git a/crates/dustfril-core/src/detector/scan.rs b/crates/dustfril-core/src/detector/scan.rs new file mode 100644 index 0000000..ccc6184 --- /dev/null +++ b/crates/dustfril-core/src/detector/scan.rs @@ -0,0 +1,41 @@ +use std::path::Path; + +use crate::models::ScanResult; + +use super::{cargo_project, git, registry, target}; + +pub fn scan_project(root: &Path) -> ScanResult { + let mut result = ScanResult::default(); + + if !cargo_project::is_cargo_project(root) { + return result; + } + + if let Some(target) = target::detect(root) { + result.artifacts.push(target); + } + + result +} + +pub fn scan_global() -> ScanResult { + let mut result = ScanResult::default(); + + if let Some(registry) = registry::detect() { + result.artifacts.push(registry); + } + + if let Some(git) = git::detect() { + result.artifacts.push(git); + } + + result +} + +pub fn scan(root: &Path) -> ScanResult { + let mut result = scan_project(root); + + result.artifacts.extend(scan_global().artifacts); + + result +} diff --git a/crates/dustfril-core/src/detector/target.rs b/crates/dustfril-core/src/detector/target.rs new file mode 100644 index 0000000..81ee194 --- /dev/null +++ b/crates/dustfril-core/src/detector/target.rs @@ -0,0 +1,16 @@ +use std::path::Path; + +use crate::models::{ArtifactLocation, ArtifactType}; + +pub fn detect(root: &Path) -> Option { + let target_path = root.join("target"); + + if !target_path.exists() { + return None; + } + + Some(ArtifactLocation { + path: target_path, + artifact_type: ArtifactType::Target, + }) +} diff --git a/crates/dustfril-core/src/detector/tests.rs b/crates/dustfril-core/src/detector/tests.rs new file mode 100644 index 0000000..448e963 --- /dev/null +++ b/crates/dustfril-core/src/detector/tests.rs @@ -0,0 +1,38 @@ +use tempfile::TempDir; + +use crate::{detector::scan_project, models::ArtifactType}; + +#[test] +fn scan_returns_empty_when_not_cargo_project() { + let temp_dir = TempDir::new().unwrap(); + + let result = scan_project(temp_dir.path()); + + assert!(result.artifacts.is_empty()); +} + +#[test] +fn cargo_project_without_target_returns_empty() { + let temp_dir = TempDir::new().unwrap(); + + std::fs::write(temp_dir.path().join("Cargo.toml"), "[package]").unwrap(); + + let result = scan_project(temp_dir.path()); + + assert!(result.artifacts.is_empty()); +} + +#[test] +fn detects_target_directory() { + let temp_dir = TempDir::new().unwrap(); + + std::fs::write(temp_dir.path().join("Cargo.toml"), "[package]").unwrap(); + + std::fs::create_dir(temp_dir.path().join("target")).unwrap(); + + let result = scan_project(temp_dir.path()); + + assert_eq!(result.artifacts.len(), 1); + + assert_eq!(result.artifacts[0].artifact_type, ArtifactType::Target); +} diff --git a/crates/dustfril-core/src/lib.rs b/crates/dustfril-core/src/lib.rs index 8708828..fb21a2b 100644 --- a/crates/dustfril-core/src/lib.rs +++ b/crates/dustfril-core/src/lib.rs @@ -2,8 +2,3 @@ pub mod analyzer; pub mod cleaner; pub mod detector; pub mod models; - -pub fn scan() { - println!("DustFril scan"); - println!("github actions: check"); -} diff --git a/crates/dustfril-core/src/models/artifact_location.rs b/crates/dustfril-core/src/models/artifact_location.rs new file mode 100644 index 0000000..cd26b42 --- /dev/null +++ b/crates/dustfril-core/src/models/artifact_location.rs @@ -0,0 +1,18 @@ +use std::path::PathBuf; + +use super::ArtifactType; + +#[derive(Debug, Clone)] +pub struct ArtifactLocation { + pub path: PathBuf, + pub artifact_type: ArtifactType, +} + +impl ArtifactLocation { + pub fn new(path: PathBuf, artifact_type: ArtifactType) -> Self { + Self { + path, + artifact_type, + } + } +} diff --git a/crates/dustfril-core/src/models/artifact_type.rs b/crates/dustfril-core/src/models/artifact_type.rs new file mode 100644 index 0000000..cb4f55b --- /dev/null +++ b/crates/dustfril-core/src/models/artifact_type.rs @@ -0,0 +1,24 @@ +use std::fmt; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum ArtifactType { + Target, + CargoRegistry, + CargoGit, +} + +impl fmt::Display for ArtifactType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ArtifactType::Target => { + write!(f, "TARGET") + } + ArtifactType::CargoRegistry => { + write!(f, "CARGO REGISTRY") + } + ArtifactType::CargoGit => { + write!(f, "CARGO GIT") + } + } + } +} diff --git a/crates/dustfril-core/src/models/mod.rs b/crates/dustfril-core/src/models/mod.rs index 7a3a919..7de9a2b 100644 --- a/crates/dustfril-core/src/models/mod.rs +++ b/crates/dustfril-core/src/models/mod.rs @@ -1 +1,8 @@ //! Shared models. +mod artifact_location; +mod artifact_type; +mod scan_result; + +pub use artifact_location::*; +pub use artifact_type::*; +pub use scan_result::*; diff --git a/crates/dustfril-core/src/models/scan_result.rs b/crates/dustfril-core/src/models/scan_result.rs new file mode 100644 index 0000000..b26e0a7 --- /dev/null +++ b/crates/dustfril-core/src/models/scan_result.rs @@ -0,0 +1,6 @@ +use super::ArtifactLocation; + +#[derive(Debug, Default)] +pub struct ScanResult { + pub artifacts: Vec, +}