✨ feat(cli): scaffold InitCli subcommand and clap wiring
This commit is contained in:
committed by
Jeremiah Russell
parent
f02ae0ae10
commit
fd70ef9511
299
Cargo.lock
generated
299
Cargo.lock
generated
@@ -101,6 +101,37 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "assert_cmd"
|
||||||
|
version = "2.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2bd389a4b2970a01282ee455294913c0a43724daedcd1a24c3eb0ec1c1320b66"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"bstr",
|
||||||
|
"doc-comment",
|
||||||
|
"libc",
|
||||||
|
"predicates",
|
||||||
|
"predicates-core",
|
||||||
|
"predicates-tree",
|
||||||
|
"wait-timeout",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "assert_fs"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a652f6cb1f516886fcfee5e7a5c078b9ade62cfcb889524efe5a64d682dd27a9"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"doc-comment",
|
||||||
|
"globwalk",
|
||||||
|
"predicates",
|
||||||
|
"predicates-core",
|
||||||
|
"predicates-tree",
|
||||||
|
"tempfile",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-lock"
|
name = "async-lock"
|
||||||
version = "3.4.1"
|
version = "3.4.1"
|
||||||
@@ -203,6 +234,17 @@ dependencies = [
|
|||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bstr"
|
||||||
|
version = "1.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.19.0"
|
version = "3.19.0"
|
||||||
@@ -327,6 +369,19 @@ dependencies = [
|
|||||||
"winnow",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "console"
|
||||||
|
version = "0.15.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8"
|
||||||
|
dependencies = [
|
||||||
|
"encode_unicode",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"unicode-width",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.10.1"
|
version = "0.10.1"
|
||||||
@@ -361,6 +416,25 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-epoch"
|
||||||
|
version = "0.9.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.21"
|
version = "0.8.21"
|
||||||
@@ -381,23 +455,28 @@ dependencies = [
|
|||||||
name = "cull-gmail"
|
name = "cull-gmail"
|
||||||
version = "0.0.11"
|
version = "0.0.11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"assert_cmd",
|
||||||
|
"assert_fs",
|
||||||
"base64",
|
"base64",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"clap-verbosity-flag",
|
"clap-verbosity-flag",
|
||||||
"config",
|
"config",
|
||||||
|
"dialoguer",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"flate2",
|
"flate2",
|
||||||
"futures",
|
"futures",
|
||||||
"google-gmail1",
|
"google-gmail1",
|
||||||
"httpmock",
|
"httpmock",
|
||||||
|
"indicatif",
|
||||||
"lazy-regex",
|
"lazy-regex",
|
||||||
"log",
|
"log",
|
||||||
|
"predicates",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"temp-env",
|
"temp-env",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror 2.0.17",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-test",
|
"tokio-test",
|
||||||
"toml",
|
"toml",
|
||||||
@@ -448,6 +527,25 @@ dependencies = [
|
|||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dialoguer"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de"
|
||||||
|
dependencies = [
|
||||||
|
"console",
|
||||||
|
"shell-words",
|
||||||
|
"tempfile",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "difflib"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.10.7"
|
version = "0.10.7"
|
||||||
@@ -469,6 +567,12 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "doc-comment"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dyn-clone"
|
name = "dyn-clone"
|
||||||
version = "1.0.20"
|
version = "1.0.20"
|
||||||
@@ -481,6 +585,12 @@ version = "1.15.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encode_unicode"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_filter"
|
name = "env_filter"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
@@ -563,6 +673,15 @@ dependencies = [
|
|||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "float-cmp"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@@ -712,6 +831,30 @@ version = "0.32.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7"
|
checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "globset"
|
||||||
|
version = "0.4.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eab69130804d941f8075cfd713bf8848a2c3b3f201a9457a11e6f87e1ab62305"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"bstr",
|
||||||
|
"log",
|
||||||
|
"regex-automata",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "globwalk"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"ignore",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "google-apis-common"
|
name = "google-apis-common"
|
||||||
version = "7.0.0"
|
version = "7.0.0"
|
||||||
@@ -896,7 +1039,7 @@ dependencies = [
|
|||||||
"similar",
|
"similar",
|
||||||
"stringmetrics",
|
"stringmetrics",
|
||||||
"tabwriter",
|
"tabwriter",
|
||||||
"thiserror",
|
"thiserror 2.0.17",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"url",
|
"url",
|
||||||
@@ -1100,6 +1243,22 @@ dependencies = [
|
|||||||
"icu_properties",
|
"icu_properties",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ignore"
|
||||||
|
version = "0.4.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "81776e6f9464432afcc28d03e52eb101c93b6f0566f52aef2427663e700f0403"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-deque",
|
||||||
|
"globset",
|
||||||
|
"log",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"same-file",
|
||||||
|
"walkdir",
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.9.3"
|
version = "1.9.3"
|
||||||
@@ -1123,6 +1282,19 @@ dependencies = [
|
|||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indicatif"
|
||||||
|
version = "0.17.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235"
|
||||||
|
dependencies = [
|
||||||
|
"console",
|
||||||
|
"number_prefix",
|
||||||
|
"portable-atomic",
|
||||||
|
"unicode-width",
|
||||||
|
"web-time",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "io-uring"
|
name = "io-uring"
|
||||||
version = "0.7.10"
|
version = "0.7.10"
|
||||||
@@ -1278,6 +1450,12 @@ dependencies = [
|
|||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "normalize-line-endings"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-conv"
|
name = "num-conv"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -1302,6 +1480,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "number_prefix"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.37.3"
|
version = "0.37.3"
|
||||||
@@ -1421,6 +1605,36 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "predicates"
|
||||||
|
version = "3.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"difflib",
|
||||||
|
"float-cmp",
|
||||||
|
"normalize-line-endings",
|
||||||
|
"predicates-core",
|
||||||
|
"regex",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "predicates-core"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "predicates-tree"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c"
|
||||||
|
dependencies = [
|
||||||
|
"predicates-core",
|
||||||
|
"termtree",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.101"
|
version = "1.0.101"
|
||||||
@@ -1603,6 +1817,15 @@ version = "1.0.20"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "same-file"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "schannel"
|
name = "schannel"
|
||||||
version = "0.1.28"
|
version = "0.1.28"
|
||||||
@@ -1776,6 +1999,12 @@ dependencies = [
|
|||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shell-words"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@@ -1902,13 +2131,39 @@ dependencies = [
|
|||||||
"windows-sys 0.61.1",
|
"windows-sys 0.61.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "termtree"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "2.0.17"
|
version = "2.0.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
|
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl 2.0.17",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2186,6 +2441,25 @@ version = "0.9.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wait-timeout"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "walkdir"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||||
|
dependencies = [
|
||||||
|
"same-file",
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "want"
|
name = "want"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@@ -2269,6 +2543,25 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web-time"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.61.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-core"
|
name = "windows-core"
|
||||||
version = "0.62.1"
|
version = "0.62.1"
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ tokio = { version = "1.47.1", features = ["macros", "rt-multi-thread", "process"
|
|||||||
toml = "0.9.7"
|
toml = "0.9.7"
|
||||||
base64 = "0.22"
|
base64 = "0.22"
|
||||||
flate2 = "1.0"
|
flate2 = "1.0"
|
||||||
|
dialoguer = "0.11"
|
||||||
|
indicatif = "0.17"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
httpmock = "0.8"
|
httpmock = "0.8"
|
||||||
@@ -46,6 +48,9 @@ tokio-test = "0.4"
|
|||||||
temp-env = "0.3"
|
temp-env = "0.3"
|
||||||
tempfile = "3.12"
|
tempfile = "3.12"
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
|
assert_cmd = "2.0"
|
||||||
|
assert_fs = "1.1"
|
||||||
|
predicates = "3.1"
|
||||||
|
|
||||||
[lints.clippy]
|
[lints.clippy]
|
||||||
uninlined-format-args = "warn"
|
uninlined-format-args = "warn"
|
||||||
|
|||||||
197
src/cli/init_cli.rs
Normal file
197
src/cli/init_cli.rs
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
//! # Initialization CLI Module
|
||||||
|
//!
|
||||||
|
//! This module provides CLI functionality for initializing the cull-gmail application,
|
||||||
|
//! including creating configuration directories, setting up OAuth2 credentials,
|
||||||
|
//! generating default configuration files, and completing the initial authentication flow.
|
||||||
|
//!
|
||||||
|
//! ## Overview
|
||||||
|
//!
|
||||||
|
//! The initialization system allows users to:
|
||||||
|
//!
|
||||||
|
//! - **Create configuration directory**: Set up the cull-gmail configuration directory
|
||||||
|
//! - **Install credentials**: Copy and validate OAuth2 credential files
|
||||||
|
//! - **Generate configuration**: Create default cull-gmail.toml and rules.toml files
|
||||||
|
//! - **Complete OAuth2 flow**: Authenticate with Gmail API and persist tokens
|
||||||
|
//! - **Interactive setup**: Guide users through setup with prompts and confirmations
|
||||||
|
//! - **Dry-run mode**: Preview all actions without making changes
|
||||||
|
//!
|
||||||
|
//! ## Use Cases
|
||||||
|
//!
|
||||||
|
//! ### First-time Setup
|
||||||
|
//! ```bash
|
||||||
|
//! # Interactive setup with credential file
|
||||||
|
//! cull-gmail init --interactive --credential-file ~/Downloads/client_secret.json
|
||||||
|
//!
|
||||||
|
//! # Non-interactive setup (credential file copied manually later)
|
||||||
|
//! cull-gmail init --config-dir ~/.cull-gmail
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! ### Planning and Verification
|
||||||
|
//! ```bash
|
||||||
|
//! # See what would be created without making changes
|
||||||
|
//! cull-gmail init --dry-run
|
||||||
|
//!
|
||||||
|
//! # Preview with specific options
|
||||||
|
//! cull-gmail init --config-dir /custom/path --credential-file credentials.json --dry-run
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! ### Force Overwrite
|
||||||
|
//! ```bash
|
||||||
|
//! # Recreate configuration, backing up existing files
|
||||||
|
//! cull-gmail init --force
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! ## Security Considerations
|
||||||
|
//!
|
||||||
|
//! - **Credential Protection**: OAuth2 credential files are copied with 0600 permissions
|
||||||
|
//! - **Token Directory**: Token cache directory is created with 0700 permissions
|
||||||
|
//! - **Backup Safety**: Existing files are backed up with timestamps before overwriting
|
||||||
|
//! - **Interactive Confirmation**: Prompts for confirmation before overwriting existing files
|
||||||
|
|
||||||
|
use clap::Parser;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
/// Initialize cull-gmail configuration, credentials, and OAuth2 tokens.
|
||||||
|
///
|
||||||
|
/// This command sets up the complete cull-gmail environment by creating the configuration
|
||||||
|
/// directory, installing OAuth2 credentials, generating default configuration files,
|
||||||
|
/// and completing the initial Gmail API authentication to persist tokens.
|
||||||
|
///
|
||||||
|
/// ## Setup Process
|
||||||
|
///
|
||||||
|
/// 1. **Configuration Directory**: Create or verify the configuration directory
|
||||||
|
/// 2. **Credential Installation**: Copy and validate OAuth2 credential file (if provided)
|
||||||
|
/// 3. **Configuration Generation**: Create cull-gmail.toml with safe defaults
|
||||||
|
/// 4. **Rules Template**: Generate rules.toml with example retention rules
|
||||||
|
/// 5. **Token Directory**: Ensure OAuth2 token cache directory exists
|
||||||
|
/// 6. **Authentication**: Complete OAuth2 flow to generate and persist tokens
|
||||||
|
///
|
||||||
|
/// ## Interactive vs Non-Interactive
|
||||||
|
///
|
||||||
|
/// - **Non-interactive** (default): Proceeds with provided options, fails if conflicts exist
|
||||||
|
/// - **Interactive** (`--interactive`): Prompts for missing information and confirmation for conflicts
|
||||||
|
/// - **Dry-run** (`--dry-run`): Shows planned actions without making any changes
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
///
|
||||||
|
/// ```bash
|
||||||
|
/// # Basic initialization
|
||||||
|
/// cull-gmail init
|
||||||
|
///
|
||||||
|
/// # Interactive setup with credential file
|
||||||
|
/// cull-gmail init --interactive --credential-file client_secret.json
|
||||||
|
///
|
||||||
|
/// # Custom configuration directory
|
||||||
|
/// cull-gmail init --config-dir /path/to/config
|
||||||
|
///
|
||||||
|
/// # Preview actions without changes
|
||||||
|
/// cull-gmail init --dry-run
|
||||||
|
///
|
||||||
|
/// # Force overwrite existing files
|
||||||
|
/// cull-gmail init --force
|
||||||
|
/// ```
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
pub struct InitCli {
|
||||||
|
/// Configuration directory path.
|
||||||
|
///
|
||||||
|
/// Supports path prefixes:
|
||||||
|
/// - `h:path` - Relative to home directory (default: `h:.cull-gmail`)
|
||||||
|
/// - `c:path` - Relative to current directory
|
||||||
|
/// - `r:path` - Relative to filesystem root
|
||||||
|
/// - `path` - Use path as-is
|
||||||
|
#[arg(
|
||||||
|
long = "config-dir",
|
||||||
|
value_name = "DIR",
|
||||||
|
default_value = "h:.cull-gmail",
|
||||||
|
help = "Configuration directory path"
|
||||||
|
)]
|
||||||
|
pub config_dir: String,
|
||||||
|
|
||||||
|
/// OAuth2 credential file path.
|
||||||
|
///
|
||||||
|
/// This should be the JSON file downloaded from Google Cloud Console
|
||||||
|
/// containing your OAuth2 client credentials for Desktop application type.
|
||||||
|
/// The file will be copied to the configuration directory as `credential.json`.
|
||||||
|
#[arg(
|
||||||
|
long = "credential-file",
|
||||||
|
value_name = "PATH",
|
||||||
|
help = "Path to OAuth2 credential JSON file"
|
||||||
|
)]
|
||||||
|
pub credential_file: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// Overwrite existing files without prompting.
|
||||||
|
///
|
||||||
|
/// When enabled, existing configuration files will be backed up with
|
||||||
|
/// timestamps and then overwritten with new defaults. Use with caution
|
||||||
|
/// as this will replace your current configuration.
|
||||||
|
#[arg(
|
||||||
|
long = "force",
|
||||||
|
help = "Overwrite existing files (creates timestamped backups)"
|
||||||
|
)]
|
||||||
|
pub force: bool,
|
||||||
|
|
||||||
|
/// Show planned actions without making changes.
|
||||||
|
///
|
||||||
|
/// Enables preview mode where all planned operations are displayed
|
||||||
|
/// but no files are created, modified, or removed. OAuth2 authentication
|
||||||
|
/// flow is also skipped in dry-run mode.
|
||||||
|
#[arg(
|
||||||
|
long = "dry-run",
|
||||||
|
help = "Preview actions without making changes"
|
||||||
|
)]
|
||||||
|
pub dry_run: bool,
|
||||||
|
|
||||||
|
/// Enable interactive prompts and confirmations.
|
||||||
|
///
|
||||||
|
/// When enabled, the command will prompt for missing information
|
||||||
|
/// (such as credential file path) and ask for confirmation before
|
||||||
|
/// overwriting existing files. Recommended for first-time users.
|
||||||
|
#[arg(
|
||||||
|
long = "interactive",
|
||||||
|
short = 'i',
|
||||||
|
help = "Prompt for missing information and confirmations"
|
||||||
|
)]
|
||||||
|
pub interactive: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InitCli {
|
||||||
|
/// Execute the initialization command.
|
||||||
|
///
|
||||||
|
/// This method orchestrates the complete initialization workflow including
|
||||||
|
/// configuration directory creation, credential installation, file generation,
|
||||||
|
/// and OAuth2 authentication based on the provided command-line options.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// Returns `Result<()>` indicating success or failure of the initialization process.
|
||||||
|
///
|
||||||
|
/// # Process Flow
|
||||||
|
///
|
||||||
|
/// 1. **Plan Operations**: Analyze current state and generate operation plan
|
||||||
|
/// 2. **Validate Inputs**: Check credential file validity and resolve paths
|
||||||
|
/// 3. **Interactive Prompts**: Request missing information if in interactive mode
|
||||||
|
/// 4. **Execute or Preview**: Apply operations or show dry-run preview
|
||||||
|
/// 5. **OAuth2 Flow**: Complete authentication and token generation
|
||||||
|
/// 6. **Success Reporting**: Display results and next steps
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// This method can return errors for:
|
||||||
|
/// - Invalid or missing credential files
|
||||||
|
/// - File system permission issues
|
||||||
|
/// - Configuration conflicts without force or interactive resolution
|
||||||
|
/// - OAuth2 authentication failures
|
||||||
|
/// - Network connectivity issues during authentication
|
||||||
|
pub async fn run(&self) -> cull_gmail::Result<()> {
|
||||||
|
log::info!("Starting cull-gmail initialization");
|
||||||
|
|
||||||
|
if self.dry_run {
|
||||||
|
println!("DRY RUN: No changes will be made");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implement initialization logic
|
||||||
|
println!("Init command called with options: {self:?}");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -111,6 +111,7 @@
|
|||||||
|
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
|
|
||||||
|
mod init_cli;
|
||||||
mod labels_cli;
|
mod labels_cli;
|
||||||
mod messages_cli;
|
mod messages_cli;
|
||||||
mod rules_cli;
|
mod rules_cli;
|
||||||
@@ -120,6 +121,7 @@ use config::Config;
|
|||||||
use cull_gmail::{ClientConfig, EolAction, GmailClient, Result, RuleProcessor, Rules};
|
use cull_gmail::{ClientConfig, EolAction, GmailClient, Result, RuleProcessor, Rules};
|
||||||
use std::{env, error::Error as stdError};
|
use std::{env, error::Error as stdError};
|
||||||
|
|
||||||
|
use init_cli::InitCli;
|
||||||
use labels_cli::LabelsCli;
|
use labels_cli::LabelsCli;
|
||||||
use messages_cli::MessagesCli;
|
use messages_cli::MessagesCli;
|
||||||
use rules_cli::RulesCli;
|
use rules_cli::RulesCli;
|
||||||
@@ -175,6 +177,13 @@ struct Cli {
|
|||||||
/// then query specific messages, and finally configure automated rules.
|
/// then query specific messages, and finally configure automated rules.
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
enum SubCmds {
|
enum SubCmds {
|
||||||
|
/// Initialize cull-gmail configuration, credentials, and OAuth2 tokens.
|
||||||
|
///
|
||||||
|
/// Sets up the complete cull-gmail environment including configuration directory,
|
||||||
|
/// OAuth2 credentials, default configuration files, and initial authentication flow.
|
||||||
|
#[clap(name = "init", display_order = 1)]
|
||||||
|
Init(InitCli),
|
||||||
|
|
||||||
/// Query, filter, and perform batch operations on Gmail messages.
|
/// Query, filter, and perform batch operations on Gmail messages.
|
||||||
///
|
///
|
||||||
/// Supports advanced Gmail query syntax, label filtering, and batch actions
|
/// Supports advanced Gmail query syntax, label filtering, and batch actions
|
||||||
@@ -295,6 +304,10 @@ async fn run(args: Cli) -> Result<()> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
match sub_command {
|
match sub_command {
|
||||||
|
SubCmds::Init(init_cli) => {
|
||||||
|
// Init commands don't need a Gmail client since they set up the config
|
||||||
|
init_cli.run().await
|
||||||
|
}
|
||||||
SubCmds::Message(messages_cli) => messages_cli.run(&mut client).await,
|
SubCmds::Message(messages_cli) => messages_cli.run(&mut client).await,
|
||||||
SubCmds::Labels(labels_cli) => labels_cli.run(client).await,
|
SubCmds::Labels(labels_cli) => labels_cli.run(client).await,
|
||||||
SubCmds::Rules(rules_cli) => rules_cli.run(&mut client).await,
|
SubCmds::Rules(rules_cli) => rules_cli.run(&mut client).await,
|
||||||
|
|||||||
Reference in New Issue
Block a user