tangled
alpha
login
or
join now
tsiry-sandratraina.com
/
oh-my-droid
3
fork
atom
Opinionated Android 15+ Linux Terminal Setup
android
linux
command-line-tools
3
fork
atom
overview
issues
pulls
pipelines
Initial Commit
tsiry-sandratraina.com
7 months ago
2f209d48
+1199
11 changed files
expand all
collapse all
unified
split
.gitignore
Cargo.lock
Cargo.toml
src
apply.rs
cmd
init.rs
mod.rs
setup.rs
command.rs
config.rs
consts.rs
main.rs
+2
.gitignore
···
1
1
+
/target
2
2
+
oh-my-droid.toml
+498
Cargo.lock
···
1
1
+
# This file is automatically @generated by Cargo.
2
2
+
# It is not intended for manual editing.
3
3
+
version = 4
4
4
+
5
5
+
[[package]]
6
6
+
name = "anstream"
7
7
+
version = "0.6.20"
8
8
+
source = "registry+https://github.com/rust-lang/crates.io-index"
9
9
+
checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192"
10
10
+
dependencies = [
11
11
+
"anstyle",
12
12
+
"anstyle-parse",
13
13
+
"anstyle-query",
14
14
+
"anstyle-wincon",
15
15
+
"colorchoice",
16
16
+
"is_terminal_polyfill",
17
17
+
"utf8parse",
18
18
+
]
19
19
+
20
20
+
[[package]]
21
21
+
name = "anstyle"
22
22
+
version = "1.0.11"
23
23
+
source = "registry+https://github.com/rust-lang/crates.io-index"
24
24
+
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
25
25
+
26
26
+
[[package]]
27
27
+
name = "anstyle-parse"
28
28
+
version = "0.2.7"
29
29
+
source = "registry+https://github.com/rust-lang/crates.io-index"
30
30
+
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
31
31
+
dependencies = [
32
32
+
"utf8parse",
33
33
+
]
34
34
+
35
35
+
[[package]]
36
36
+
name = "anstyle-query"
37
37
+
version = "1.1.4"
38
38
+
source = "registry+https://github.com/rust-lang/crates.io-index"
39
39
+
checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
40
40
+
dependencies = [
41
41
+
"windows-sys",
42
42
+
]
43
43
+
44
44
+
[[package]]
45
45
+
name = "anstyle-wincon"
46
46
+
version = "3.0.10"
47
47
+
source = "registry+https://github.com/rust-lang/crates.io-index"
48
48
+
checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
49
49
+
dependencies = [
50
50
+
"anstyle",
51
51
+
"once_cell_polyfill",
52
52
+
"windows-sys",
53
53
+
]
54
54
+
55
55
+
[[package]]
56
56
+
name = "anyhow"
57
57
+
version = "1.0.99"
58
58
+
source = "registry+https://github.com/rust-lang/crates.io-index"
59
59
+
checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
60
60
+
61
61
+
[[package]]
62
62
+
name = "bitflags"
63
63
+
version = "2.9.1"
64
64
+
source = "registry+https://github.com/rust-lang/crates.io-index"
65
65
+
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
66
66
+
67
67
+
[[package]]
68
68
+
name = "cfg-if"
69
69
+
version = "1.0.1"
70
70
+
source = "registry+https://github.com/rust-lang/crates.io-index"
71
71
+
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
72
72
+
73
73
+
[[package]]
74
74
+
name = "clap"
75
75
+
version = "4.5.45"
76
76
+
source = "registry+https://github.com/rust-lang/crates.io-index"
77
77
+
checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318"
78
78
+
dependencies = [
79
79
+
"clap_builder",
80
80
+
]
81
81
+
82
82
+
[[package]]
83
83
+
name = "clap_builder"
84
84
+
version = "4.5.44"
85
85
+
source = "registry+https://github.com/rust-lang/crates.io-index"
86
86
+
checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8"
87
87
+
dependencies = [
88
88
+
"anstream",
89
89
+
"anstyle",
90
90
+
"clap_lex",
91
91
+
"strsim",
92
92
+
]
93
93
+
94
94
+
[[package]]
95
95
+
name = "clap_lex"
96
96
+
version = "0.7.5"
97
97
+
source = "registry+https://github.com/rust-lang/crates.io-index"
98
98
+
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
99
99
+
100
100
+
[[package]]
101
101
+
name = "colorchoice"
102
102
+
version = "1.0.4"
103
103
+
source = "registry+https://github.com/rust-lang/crates.io-index"
104
104
+
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
105
105
+
106
106
+
[[package]]
107
107
+
name = "dirs"
108
108
+
version = "6.0.0"
109
109
+
source = "registry+https://github.com/rust-lang/crates.io-index"
110
110
+
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
111
111
+
dependencies = [
112
112
+
"dirs-sys",
113
113
+
]
114
114
+
115
115
+
[[package]]
116
116
+
name = "dirs-sys"
117
117
+
version = "0.5.0"
118
118
+
source = "registry+https://github.com/rust-lang/crates.io-index"
119
119
+
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
120
120
+
dependencies = [
121
121
+
"libc",
122
122
+
"option-ext",
123
123
+
"redox_users",
124
124
+
"windows-sys",
125
125
+
]
126
126
+
127
127
+
[[package]]
128
128
+
name = "equivalent"
129
129
+
version = "1.0.2"
130
130
+
source = "registry+https://github.com/rust-lang/crates.io-index"
131
131
+
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
132
132
+
133
133
+
[[package]]
134
134
+
name = "getrandom"
135
135
+
version = "0.2.16"
136
136
+
source = "registry+https://github.com/rust-lang/crates.io-index"
137
137
+
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
138
138
+
dependencies = [
139
139
+
"cfg-if",
140
140
+
"libc",
141
141
+
"wasi",
142
142
+
]
143
143
+
144
144
+
[[package]]
145
145
+
name = "hashbrown"
146
146
+
version = "0.15.5"
147
147
+
source = "registry+https://github.com/rust-lang/crates.io-index"
148
148
+
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
149
149
+
150
150
+
[[package]]
151
151
+
name = "indexmap"
152
152
+
version = "2.10.0"
153
153
+
source = "registry+https://github.com/rust-lang/crates.io-index"
154
154
+
checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
155
155
+
dependencies = [
156
156
+
"equivalent",
157
157
+
"hashbrown",
158
158
+
]
159
159
+
160
160
+
[[package]]
161
161
+
name = "is_terminal_polyfill"
162
162
+
version = "1.70.1"
163
163
+
source = "registry+https://github.com/rust-lang/crates.io-index"
164
164
+
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
165
165
+
166
166
+
[[package]]
167
167
+
name = "itoa"
168
168
+
version = "1.0.15"
169
169
+
source = "registry+https://github.com/rust-lang/crates.io-index"
170
170
+
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
171
171
+
172
172
+
[[package]]
173
173
+
name = "libc"
174
174
+
version = "0.2.175"
175
175
+
source = "registry+https://github.com/rust-lang/crates.io-index"
176
176
+
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
177
177
+
178
178
+
[[package]]
179
179
+
name = "libredox"
180
180
+
version = "0.1.9"
181
181
+
source = "registry+https://github.com/rust-lang/crates.io-index"
182
182
+
checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3"
183
183
+
dependencies = [
184
184
+
"bitflags",
185
185
+
"libc",
186
186
+
]
187
187
+
188
188
+
[[package]]
189
189
+
name = "libyml"
190
190
+
version = "0.0.5"
191
191
+
source = "registry+https://github.com/rust-lang/crates.io-index"
192
192
+
checksum = "3302702afa434ffa30847a83305f0a69d6abd74293b6554c18ec85c7ef30c980"
193
193
+
dependencies = [
194
194
+
"anyhow",
195
195
+
"version_check",
196
196
+
]
197
197
+
198
198
+
[[package]]
199
199
+
name = "memchr"
200
200
+
version = "2.7.5"
201
201
+
source = "registry+https://github.com/rust-lang/crates.io-index"
202
202
+
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
203
203
+
204
204
+
[[package]]
205
205
+
name = "oh-my-droid"
206
206
+
version = "0.1.0"
207
207
+
dependencies = [
208
208
+
"anyhow",
209
209
+
"clap",
210
210
+
"dirs",
211
211
+
"owo-colors",
212
212
+
"serde",
213
213
+
"serde_yml",
214
214
+
"toml",
215
215
+
]
216
216
+
217
217
+
[[package]]
218
218
+
name = "once_cell_polyfill"
219
219
+
version = "1.70.1"
220
220
+
source = "registry+https://github.com/rust-lang/crates.io-index"
221
221
+
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
222
222
+
223
223
+
[[package]]
224
224
+
name = "option-ext"
225
225
+
version = "0.2.0"
226
226
+
source = "registry+https://github.com/rust-lang/crates.io-index"
227
227
+
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
228
228
+
229
229
+
[[package]]
230
230
+
name = "owo-colors"
231
231
+
version = "4.2.2"
232
232
+
source = "registry+https://github.com/rust-lang/crates.io-index"
233
233
+
checksum = "48dd4f4a2c8405440fd0462561f0e5806bd0f77e86f51c761481bdd4018b545e"
234
234
+
235
235
+
[[package]]
236
236
+
name = "proc-macro2"
237
237
+
version = "1.0.97"
238
238
+
source = "registry+https://github.com/rust-lang/crates.io-index"
239
239
+
checksum = "d61789d7719defeb74ea5fe81f2fdfdbd28a803847077cecce2ff14e1472f6f1"
240
240
+
dependencies = [
241
241
+
"unicode-ident",
242
242
+
]
243
243
+
244
244
+
[[package]]
245
245
+
name = "quote"
246
246
+
version = "1.0.40"
247
247
+
source = "registry+https://github.com/rust-lang/crates.io-index"
248
248
+
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
249
249
+
dependencies = [
250
250
+
"proc-macro2",
251
251
+
]
252
252
+
253
253
+
[[package]]
254
254
+
name = "redox_users"
255
255
+
version = "0.5.2"
256
256
+
source = "registry+https://github.com/rust-lang/crates.io-index"
257
257
+
checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
258
258
+
dependencies = [
259
259
+
"getrandom",
260
260
+
"libredox",
261
261
+
"thiserror",
262
262
+
]
263
263
+
264
264
+
[[package]]
265
265
+
name = "ryu"
266
266
+
version = "1.0.20"
267
267
+
source = "registry+https://github.com/rust-lang/crates.io-index"
268
268
+
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
269
269
+
270
270
+
[[package]]
271
271
+
name = "serde"
272
272
+
version = "1.0.219"
273
273
+
source = "registry+https://github.com/rust-lang/crates.io-index"
274
274
+
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
275
275
+
dependencies = [
276
276
+
"serde_derive",
277
277
+
]
278
278
+
279
279
+
[[package]]
280
280
+
name = "serde_derive"
281
281
+
version = "1.0.219"
282
282
+
source = "registry+https://github.com/rust-lang/crates.io-index"
283
283
+
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
284
284
+
dependencies = [
285
285
+
"proc-macro2",
286
286
+
"quote",
287
287
+
"syn",
288
288
+
]
289
289
+
290
290
+
[[package]]
291
291
+
name = "serde_spanned"
292
292
+
version = "1.0.0"
293
293
+
source = "registry+https://github.com/rust-lang/crates.io-index"
294
294
+
checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83"
295
295
+
dependencies = [
296
296
+
"serde",
297
297
+
]
298
298
+
299
299
+
[[package]]
300
300
+
name = "serde_yml"
301
301
+
version = "0.0.12"
302
302
+
source = "registry+https://github.com/rust-lang/crates.io-index"
303
303
+
checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd"
304
304
+
dependencies = [
305
305
+
"indexmap",
306
306
+
"itoa",
307
307
+
"libyml",
308
308
+
"memchr",
309
309
+
"ryu",
310
310
+
"serde",
311
311
+
"version_check",
312
312
+
]
313
313
+
314
314
+
[[package]]
315
315
+
name = "strsim"
316
316
+
version = "0.11.1"
317
317
+
source = "registry+https://github.com/rust-lang/crates.io-index"
318
318
+
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
319
319
+
320
320
+
[[package]]
321
321
+
name = "syn"
322
322
+
version = "2.0.105"
323
323
+
source = "registry+https://github.com/rust-lang/crates.io-index"
324
324
+
checksum = "7bc3fcb250e53458e712715cf74285c1f889686520d79294a9ef3bd7aa1fc619"
325
325
+
dependencies = [
326
326
+
"proc-macro2",
327
327
+
"quote",
328
328
+
"unicode-ident",
329
329
+
]
330
330
+
331
331
+
[[package]]
332
332
+
name = "thiserror"
333
333
+
version = "2.0.14"
334
334
+
source = "registry+https://github.com/rust-lang/crates.io-index"
335
335
+
checksum = "0b0949c3a6c842cbde3f1686d6eea5a010516deb7085f79db747562d4102f41e"
336
336
+
dependencies = [
337
337
+
"thiserror-impl",
338
338
+
]
339
339
+
340
340
+
[[package]]
341
341
+
name = "thiserror-impl"
342
342
+
version = "2.0.14"
343
343
+
source = "registry+https://github.com/rust-lang/crates.io-index"
344
344
+
checksum = "cc5b44b4ab9c2fdd0e0512e6bece8388e214c0749f5862b114cc5b7a25daf227"
345
345
+
dependencies = [
346
346
+
"proc-macro2",
347
347
+
"quote",
348
348
+
"syn",
349
349
+
]
350
350
+
351
351
+
[[package]]
352
352
+
name = "toml"
353
353
+
version = "0.9.5"
354
354
+
source = "registry+https://github.com/rust-lang/crates.io-index"
355
355
+
checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8"
356
356
+
dependencies = [
357
357
+
"indexmap",
358
358
+
"serde",
359
359
+
"serde_spanned",
360
360
+
"toml_datetime",
361
361
+
"toml_parser",
362
362
+
"toml_writer",
363
363
+
"winnow",
364
364
+
]
365
365
+
366
366
+
[[package]]
367
367
+
name = "toml_datetime"
368
368
+
version = "0.7.0"
369
369
+
source = "registry+https://github.com/rust-lang/crates.io-index"
370
370
+
checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3"
371
371
+
dependencies = [
372
372
+
"serde",
373
373
+
]
374
374
+
375
375
+
[[package]]
376
376
+
name = "toml_parser"
377
377
+
version = "1.0.2"
378
378
+
source = "registry+https://github.com/rust-lang/crates.io-index"
379
379
+
checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10"
380
380
+
dependencies = [
381
381
+
"winnow",
382
382
+
]
383
383
+
384
384
+
[[package]]
385
385
+
name = "toml_writer"
386
386
+
version = "1.0.2"
387
387
+
source = "registry+https://github.com/rust-lang/crates.io-index"
388
388
+
checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64"
389
389
+
390
390
+
[[package]]
391
391
+
name = "unicode-ident"
392
392
+
version = "1.0.18"
393
393
+
source = "registry+https://github.com/rust-lang/crates.io-index"
394
394
+
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
395
395
+
396
396
+
[[package]]
397
397
+
name = "utf8parse"
398
398
+
version = "0.2.2"
399
399
+
source = "registry+https://github.com/rust-lang/crates.io-index"
400
400
+
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
401
401
+
402
402
+
[[package]]
403
403
+
name = "version_check"
404
404
+
version = "0.9.5"
405
405
+
source = "registry+https://github.com/rust-lang/crates.io-index"
406
406
+
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
407
407
+
408
408
+
[[package]]
409
409
+
name = "wasi"
410
410
+
version = "0.11.1+wasi-snapshot-preview1"
411
411
+
source = "registry+https://github.com/rust-lang/crates.io-index"
412
412
+
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
413
413
+
414
414
+
[[package]]
415
415
+
name = "windows-link"
416
416
+
version = "0.1.3"
417
417
+
source = "registry+https://github.com/rust-lang/crates.io-index"
418
418
+
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
419
419
+
420
420
+
[[package]]
421
421
+
name = "windows-sys"
422
422
+
version = "0.60.2"
423
423
+
source = "registry+https://github.com/rust-lang/crates.io-index"
424
424
+
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
425
425
+
dependencies = [
426
426
+
"windows-targets",
427
427
+
]
428
428
+
429
429
+
[[package]]
430
430
+
name = "windows-targets"
431
431
+
version = "0.53.3"
432
432
+
source = "registry+https://github.com/rust-lang/crates.io-index"
433
433
+
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
434
434
+
dependencies = [
435
435
+
"windows-link",
436
436
+
"windows_aarch64_gnullvm",
437
437
+
"windows_aarch64_msvc",
438
438
+
"windows_i686_gnu",
439
439
+
"windows_i686_gnullvm",
440
440
+
"windows_i686_msvc",
441
441
+
"windows_x86_64_gnu",
442
442
+
"windows_x86_64_gnullvm",
443
443
+
"windows_x86_64_msvc",
444
444
+
]
445
445
+
446
446
+
[[package]]
447
447
+
name = "windows_aarch64_gnullvm"
448
448
+
version = "0.53.0"
449
449
+
source = "registry+https://github.com/rust-lang/crates.io-index"
450
450
+
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
451
451
+
452
452
+
[[package]]
453
453
+
name = "windows_aarch64_msvc"
454
454
+
version = "0.53.0"
455
455
+
source = "registry+https://github.com/rust-lang/crates.io-index"
456
456
+
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
457
457
+
458
458
+
[[package]]
459
459
+
name = "windows_i686_gnu"
460
460
+
version = "0.53.0"
461
461
+
source = "registry+https://github.com/rust-lang/crates.io-index"
462
462
+
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
463
463
+
464
464
+
[[package]]
465
465
+
name = "windows_i686_gnullvm"
466
466
+
version = "0.53.0"
467
467
+
source = "registry+https://github.com/rust-lang/crates.io-index"
468
468
+
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
469
469
+
470
470
+
[[package]]
471
471
+
name = "windows_i686_msvc"
472
472
+
version = "0.53.0"
473
473
+
source = "registry+https://github.com/rust-lang/crates.io-index"
474
474
+
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
475
475
+
476
476
+
[[package]]
477
477
+
name = "windows_x86_64_gnu"
478
478
+
version = "0.53.0"
479
479
+
source = "registry+https://github.com/rust-lang/crates.io-index"
480
480
+
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
481
481
+
482
482
+
[[package]]
483
483
+
name = "windows_x86_64_gnullvm"
484
484
+
version = "0.53.0"
485
485
+
source = "registry+https://github.com/rust-lang/crates.io-index"
486
486
+
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
487
487
+
488
488
+
[[package]]
489
489
+
name = "windows_x86_64_msvc"
490
490
+
version = "0.53.0"
491
491
+
source = "registry+https://github.com/rust-lang/crates.io-index"
492
492
+
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
493
493
+
494
494
+
[[package]]
495
495
+
name = "winnow"
496
496
+
version = "0.7.12"
497
497
+
source = "registry+https://github.com/rust-lang/crates.io-index"
498
498
+
checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95"
+13
Cargo.toml
···
1
1
+
[package]
2
2
+
name = "oh-my-droid"
3
3
+
version = "0.1.0"
4
4
+
edition = "2024"
5
5
+
6
6
+
[dependencies]
7
7
+
anyhow = "1.0.99"
8
8
+
clap = "4.5.45"
9
9
+
dirs = "6.0.0"
10
10
+
owo-colors = "4.2.2"
11
11
+
serde = { version = "1.0.219", features = ["serde_derive", "derive"] }
12
12
+
serde_yml = "0.0.12"
13
13
+
toml = "0.9.5"
+381
src/apply.rs
···
1
1
+
use std::{collections::HashMap, path::Path};
2
2
+
3
3
+
use anyhow::{Context, Error};
4
4
+
use owo_colors::OwoColorize;
5
5
+
6
6
+
use crate::command::{run_command, run_command_without_local_path};
7
7
+
8
8
+
#[derive(Debug)]
9
9
+
pub enum SetupStep<'a> {
10
10
+
AptGet(&'a [String]),
11
11
+
Pkgx(&'a HashMap<String, String>),
12
12
+
Curl(&'a HashMap<String, String>),
13
13
+
Mise(&'a HashMap<String, String>),
14
14
+
BleSh(bool),
15
15
+
Nix(&'a HashMap<String, String>),
16
16
+
Stow(&'a HashMap<String, String>),
17
17
+
OhMyPosh(&'a str),
18
18
+
Zoxide(bool),
19
19
+
Alias(&'a HashMap<String, String>),
20
20
+
Paths,
21
21
+
}
22
22
+
23
23
+
impl<'a> SetupStep<'a> {
24
24
+
pub fn run(&self) -> Result<(), Error> {
25
25
+
match self {
26
26
+
SetupStep::AptGet(pkgs) => install_apt(pkgs),
27
27
+
SetupStep::Pkgx(map) => install_pkgx(map),
28
28
+
SetupStep::Curl(map) => run_curl_installers(map),
29
29
+
SetupStep::Mise(map) => setup_mise(map),
30
30
+
SetupStep::BleSh(enabled) => enable_blesh(*enabled),
31
31
+
SetupStep::Nix(map) => setup_nix(map),
32
32
+
SetupStep::Stow(map) => setup_stow(map),
33
33
+
SetupStep::OhMyPosh(theme) => setup_oh_my_posh(theme),
34
34
+
SetupStep::Zoxide(enabled) => enable_zoxide(*enabled),
35
35
+
SetupStep::Alias(map) => setup_alias(map),
36
36
+
SetupStep::Paths => setup_paths(),
37
37
+
}
38
38
+
}
39
39
+
40
40
+
pub fn format_dry_run(&self) -> String {
41
41
+
match self {
42
42
+
SetupStep::AptGet(pkgs) => {
43
43
+
let pkg_list = pkgs
44
44
+
.iter()
45
45
+
.map(|p| format!(" - {}", p.green()))
46
46
+
.collect::<Vec<_>>()
47
47
+
.join("\n");
48
48
+
format!(
49
49
+
"{} {}\n{}",
50
50
+
"AptGet".blue().bold(),
51
51
+
"(Install system packages via apt-get)".italic(),
52
52
+
pkg_list
53
53
+
)
54
54
+
}
55
55
+
SetupStep::Pkgx(map) => {
56
56
+
let pkg_list = map
57
57
+
.iter()
58
58
+
.map(|(k, v)| format!(" - {}: {}", k.green(), v.cyan()))
59
59
+
.collect::<Vec<_>>()
60
60
+
.join("\n");
61
61
+
format!(
62
62
+
"{} {}\n{}",
63
63
+
"Pkgx".blue().bold(),
64
64
+
"(Install tools via pkgx)".italic(),
65
65
+
pkg_list
66
66
+
)
67
67
+
}
68
68
+
SetupStep::Curl(map) => {
69
69
+
let curl_list = map
70
70
+
.iter()
71
71
+
.map(|(k, v)| format!(" - {}: {}", k.green(), v.cyan()))
72
72
+
.collect::<Vec<_>>()
73
73
+
.join("\n");
74
74
+
format!(
75
75
+
"{} {}\n{}",
76
76
+
"Curl".blue().bold(),
77
77
+
"(Run curl-based installers)".italic(),
78
78
+
curl_list
79
79
+
)
80
80
+
}
81
81
+
SetupStep::Mise(map) => {
82
82
+
let mise_list = map
83
83
+
.iter()
84
84
+
.map(|(k, v)| format!(" - {}: {}", k.green(), v.cyan()))
85
85
+
.collect::<Vec<_>>()
86
86
+
.join("\n");
87
87
+
format!(
88
88
+
"{} {}\n{}",
89
89
+
"Mise".blue().bold(),
90
90
+
"(Configure tools via mise)".italic(),
91
91
+
mise_list
92
92
+
)
93
93
+
}
94
94
+
SetupStep::BleSh(enabled) => {
95
95
+
format!(
96
96
+
"{} {}\n - Enabled: {}",
97
97
+
"BleSh".blue().bold(),
98
98
+
"(Enable ble.sh shell enhancements)".italic(),
99
99
+
enabled.to_string().green()
100
100
+
)
101
101
+
}
102
102
+
SetupStep::Zoxide(enabled) => {
103
103
+
format!(
104
104
+
"{} {}\n - Enabled: {}",
105
105
+
"Zoxide".blue().bold(),
106
106
+
"(Enable zoxide for directory navigation)".italic(),
107
107
+
enabled.to_string().green()
108
108
+
)
109
109
+
}
110
110
+
SetupStep::Nix(map) => {
111
111
+
let nix_list = map
112
112
+
.iter()
113
113
+
.map(|(k, v)| format!(" - {}: {}", k.green(), v.cyan()))
114
114
+
.collect::<Vec<_>>()
115
115
+
.join("\n");
116
116
+
format!(
117
117
+
"{} {}\n{}",
118
118
+
"Nix".blue().bold(),
119
119
+
"(Install tools via nix)".italic(),
120
120
+
nix_list
121
121
+
)
122
122
+
}
123
123
+
SetupStep::Stow(map) => {
124
124
+
let stow_list = map
125
125
+
.iter()
126
126
+
.map(|(k, v)| format!(" - {}: {}", k.green(), v.cyan()))
127
127
+
.collect::<Vec<_>>()
128
128
+
.join("\n");
129
129
+
format!(
130
130
+
"{} {}\n{}",
131
131
+
"Stow".blue().bold(),
132
132
+
"(Manage dotfiles via stow)".italic(),
133
133
+
stow_list
134
134
+
)
135
135
+
}
136
136
+
SetupStep::OhMyPosh(theme) => {
137
137
+
format!(
138
138
+
"{} {}\n - Theme: {}",
139
139
+
"OhMyPosh".blue().bold(),
140
140
+
"(Setup Oh My Posh for shell prompt)".italic(),
141
141
+
theme.green()
142
142
+
)
143
143
+
}
144
144
+
SetupStep::Alias(map) => {
145
145
+
let alias_list = map
146
146
+
.iter()
147
147
+
.map(|(k, v)| format!(" - {}: {}", k.green(), v.cyan()))
148
148
+
.collect::<Vec<_>>()
149
149
+
.join("\n");
150
150
+
format!(
151
151
+
"{} {}\n{}",
152
152
+
"Alias".blue().bold(),
153
153
+
"(Setup shell aliases)".italic(),
154
154
+
alias_list
155
155
+
)
156
156
+
}
157
157
+
SetupStep::Paths => {
158
158
+
format!(
159
159
+
"{} {}\n{}",
160
160
+
"Paths".blue().bold(),
161
161
+
"(Setup paths for binaries)".italic(),
162
162
+
" - ~/.local/bin".green()
163
163
+
)
164
164
+
}
165
165
+
}
166
166
+
}
167
167
+
}
168
168
+
169
169
+
fn install_apt(pkgs: &[String]) -> Result<(), Error> {
170
170
+
if pkgs.is_empty() {
171
171
+
return Ok(());
172
172
+
}
173
173
+
174
174
+
run_command("sudo", &["apt-get", "update"]).context("Failed to run apt-get update")?;
175
175
+
if !Path::new("/etc/apt/sources.list.d/vscode.list").exists() {
176
176
+
run_command("sudo", &["apt-get", "install", "-y", "wget", "curl", "gpg"])?;
177
177
+
run_command(
178
178
+
"bash",
179
179
+
&[
180
180
+
"-c",
181
181
+
"wget -qO- https://packages.microsoft.com/keys/microsoft.asc | sudo gpg --dearmor > packages.microsoft.gpg",
182
182
+
],
183
183
+
)?;
184
184
+
run_command(
185
185
+
"sudo",
186
186
+
&[
187
187
+
"install",
188
188
+
"-D",
189
189
+
"-o",
190
190
+
"root",
191
191
+
"-g",
192
192
+
"root",
193
193
+
"-m",
194
194
+
"644",
195
195
+
"packages.microsoft.gpg",
196
196
+
"/etc/apt/keyrings/packages.microsoft.gpg",
197
197
+
],
198
198
+
)?;
199
199
+
run_command(
200
200
+
"bash",
201
201
+
&[
202
202
+
"-c",
203
203
+
"echo 'deb [arch=amd64,arm64,armhf signed-by=/etc/apt/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main' | sudo tee /etc/apt/sources.list.d/vscode.list",
204
204
+
],
205
205
+
)?;
206
206
+
run_command("rm", &["-f", "packages.microsoft.gpg"])?;
207
207
+
run_command("sudo", &["apt-get", "update"]).context("Failed to run apt-get update")?;
208
208
+
}
209
209
+
210
210
+
if !Path::new("/etc/apt/sources.list.d/mise.list").exists() {
211
211
+
run_command("bash", &[
212
212
+
"-c",
213
213
+
"wget -qO - https://mise.jdx.dev/gpg-key.pub | gpg --dearmor | sudo tee /etc/apt/keyrings/mise-archive-keyring.gpg 1> /dev/null
214
214
+
"])?;
215
215
+
run_command(
216
216
+
"bash",
217
217
+
&[
218
218
+
"-c",
219
219
+
"echo 'deb [signed-by=/etc/apt/keyrings/mise-archive-keyring.gpg arch=amd64,arm64] https://mise.jdx.dev/deb stable main' | sudo tee /etc/apt/sources.list.d/mise.list",
220
220
+
],
221
221
+
)?;
222
222
+
run_command("sudo", &["apt-get", "update"]).context("Failed to run apt-get update")?;
223
223
+
}
224
224
+
225
225
+
let mut args: Vec<&str> = vec!["apt-get", "install", "-y"];
226
226
+
args.extend(pkgs.iter().map(|s| s.as_str()));
227
227
+
run_command("sudo", &args).context("Failed to run apt-get install")?;
228
228
+
229
229
+
run_command(
230
230
+
"sudo",
231
231
+
&["rm", "-rf", "/etc/apt/sources.list.d/vscode.list"],
232
232
+
)?;
233
233
+
234
234
+
Ok(())
235
235
+
}
236
236
+
237
237
+
fn install_pkgx(map: &HashMap<String, String>) -> Result<(), Error> {
238
238
+
for (name, ver) in map {
239
239
+
run_command("pkgm", &["install", &format!("{name}@{ver}")])
240
240
+
.context(format!("Failed to install {name} via pkgx"))?;
241
241
+
}
242
242
+
run_command("pkgm", &["uninstall", "curl"]).context("Failed to uninstall curl via pkgx")?;
243
243
+
Ok(())
244
244
+
}
245
245
+
246
246
+
fn run_curl_installers(map: &HashMap<String, String>) -> Result<(), Error> {
247
247
+
for (name, url) in map {
248
248
+
run_command("bash", &["-c", &format!("curl -fsSL {} | bash -s", url)])
249
249
+
.context(format!("Failed to run curl installer for {name}"))?;
250
250
+
}
251
251
+
Ok(())
252
252
+
}
253
253
+
254
254
+
fn setup_mise(map: &HashMap<String, String>) -> Result<(), Error> {
255
255
+
if !Path::new("/usr/bin/mise").exists() {
256
256
+
run_command("sudo", &["apt-get", "install", "-y", "mise"])
257
257
+
.context("Failed to install mise")?;
258
258
+
}
259
259
+
260
260
+
run_command(
261
261
+
"bash",
262
262
+
&[
263
263
+
"-c",
264
264
+
"sed -i '/mise/d' ~/.bashrc || echo 'No existing mise line found in .bashrc'",
265
265
+
],
266
266
+
)?;
267
267
+
run_command(
268
268
+
"bash",
269
269
+
&[
270
270
+
"-c",
271
271
+
"echo '\neval $(mise activate bash)' | tee -a ~/.bashrc",
272
272
+
],
273
273
+
)?;
274
274
+
275
275
+
for (tool, ver) in map {
276
276
+
run_command("mise", &["use", "-g", &format!("{tool}@{ver}")])
277
277
+
.context(format!("Failed to configure {tool} via mise"))?;
278
278
+
}
279
279
+
Ok(())
280
280
+
}
281
281
+
282
282
+
fn enable_blesh(enabled: bool) -> Result<(), Error> {
283
283
+
let home = dirs::home_dir().ok_or_else(|| Error::msg("Failed to get home directory"))?;
284
284
+
let blesh_path = home.join("ble.sh");
285
285
+
if enabled && !blesh_path.exists() {
286
286
+
run_command_without_local_path(
287
287
+
"bash",
288
288
+
&[
289
289
+
"-c", "rm -rf ~/local/bin/gettext* &&git clone --recursive --depth 1 --shallow-submodules https://github.com/akinomyoga/ble.sh.git",
290
290
+
],
291
291
+
)
292
292
+
.context("Failed to clone ble.sh repository")?;
293
293
+
run_command_without_local_path("make", &["-C", "ble.sh"])
294
294
+
.context("Failed to build ble.sh")?;
295
295
+
run_command_without_local_path(
296
296
+
"bash",
297
297
+
&[
298
298
+
"-c",
299
299
+
"grep 'source ble' ~/.bashrc || echo '\nsource ble.sh/out/ble.sh' | tee -a ~/.bashrc",
300
300
+
],
301
301
+
)
302
302
+
.context("Failed to add ble.sh to .bashrc")?;
303
303
+
}
304
304
+
Ok(())
305
305
+
}
306
306
+
307
307
+
fn enable_zoxide(enabled: bool) -> Result<(), Error> {
308
308
+
if enabled {
309
309
+
run_command("bash", &["-c", "curl -sSL https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | bash"])
310
310
+
.context("Failed to install zoxide")?;
311
311
+
run_command(
312
312
+
"bash",
313
313
+
&[
314
314
+
"-c",
315
315
+
"grep zoxide ~/.bashrc || echo '\neval \"$(zoxide init bash)\"' | tee -a ~/.bashrc",
316
316
+
],
317
317
+
)
318
318
+
.context("Failed to add zoxide initialization to .bashrc")?;
319
319
+
}
320
320
+
Ok(())
321
321
+
}
322
322
+
323
323
+
fn setup_nix(_map: &HashMap<String, String>) -> Result<(), Error> {
324
324
+
// nix logic here
325
325
+
Ok(())
326
326
+
}
327
327
+
328
328
+
fn setup_stow(_map: &HashMap<String, String>) -> Result<(), Error> {
329
329
+
// stow logic here
330
330
+
Ok(())
331
331
+
}
332
332
+
333
333
+
fn setup_oh_my_posh(theme: &str) -> Result<(), Error> {
334
334
+
run_command(
335
335
+
"bash",
336
336
+
&[
337
337
+
"-c",
338
338
+
"sed -i '/oh-my-posh/d' ~/.bashrc || echo 'No existing oh-my-posh line found in .bashrc'",
339
339
+
],
340
340
+
)?;
341
341
+
run_command("bash", &["-c", &format!("echo 'eval \"$(oh-my-posh init bash --config $HOME/.cache/oh-my-posh/themes/{}.omp.json)\"' >> ~/.bashrc", theme)])
342
342
+
.context("Failed to set up Oh My Posh")?;
343
343
+
Ok(())
344
344
+
}
345
345
+
346
346
+
fn setup_alias(map: &HashMap<String, String>) -> Result<(), Error> {
347
347
+
for (alias, command) in map {
348
348
+
run_command(
349
349
+
"bash",
350
350
+
&["-c", &format!("sed -i '/alias {}/d' ~/.bashrc", alias)],
351
351
+
)?;
352
352
+
run_command(
353
353
+
"bash",
354
354
+
&[
355
355
+
"-c",
356
356
+
&format!("echo 'alias {}=\"{}\"' >> ~/.bashrc", alias, command),
357
357
+
],
358
358
+
)
359
359
+
.context(format!(
360
360
+
"Failed to set up alias {} for command {}",
361
361
+
alias, command
362
362
+
))?;
363
363
+
}
364
364
+
Ok(())
365
365
+
}
366
366
+
367
367
+
fn setup_paths() -> Result<(), Error> {
368
368
+
let home = dirs::home_dir().ok_or_else(|| Error::msg("Failed to get home directory"))?;
369
369
+
let local_bin = home.join(".local/bin");
370
370
+
if !local_bin.exists() {
371
371
+
std::fs::create_dir_all(&local_bin).context("Failed to create ~/.local/bin directory")?;
372
372
+
}
373
373
+
374
374
+
run_command(
375
375
+
"bash",
376
376
+
&["-c", "grep -q 'export PATH=\"$HOME/.local/bin:$PATH\"' ~/.bashrc || echo 'export PATH=\"$HOME/.local/bin:$PATH\"' >> ~/.bashrc"],
377
377
+
)
378
378
+
.context("Failed to add ~/.local/bin to PATH in .bashrc")?;
379
379
+
380
380
+
Ok(())
381
381
+
}
+15
src/cmd/init.rs
···
1
1
+
use anyhow::Error;
2
2
+
use owo_colors::OwoColorize;
3
3
+
4
4
+
use crate::{config::Configuration, consts::CONFIG_FILE};
5
5
+
6
6
+
pub fn init() -> Result<(), Error> {
7
7
+
let cfg = Configuration::default();
8
8
+
let toml_str = toml::to_string(&cfg)?;
9
9
+
std::fs::write(CONFIG_FILE, toml_str)?;
10
10
+
println!(
11
11
+
"Initial configuration file {} created successfully.",
12
12
+
CONFIG_FILE.green()
13
13
+
);
14
14
+
Ok(())
15
15
+
}
+2
src/cmd/mod.rs
···
1
1
+
pub mod init;
2
2
+
pub mod setup;
+40
src/cmd/setup.rs
···
1
1
+
use anyhow::Error;
2
2
+
use owo_colors::OwoColorize;
3
3
+
4
4
+
use crate::{config::Configuration, consts::CONFIG_FILE};
5
5
+
6
6
+
pub fn setup(dry_run: bool, no_confirm: bool) -> Result<(), Error> {
7
7
+
let mut cfg = Configuration::default();
8
8
+
9
9
+
if std::path::Path::new(CONFIG_FILE).exists() {
10
10
+
let toml_str = std::fs::read_to_string(CONFIG_FILE)?;
11
11
+
cfg = toml::from_str(&toml_str)?;
12
12
+
}
13
13
+
14
14
+
if !no_confirm && !dry_run {
15
15
+
match std::path::Path::new(CONFIG_FILE).exists() {
16
16
+
true => {
17
17
+
println!(
18
18
+
"This will set up your environment with the default configuration from {}.\nDo you want to continue? (y/N)",
19
19
+
CONFIG_FILE.green()
20
20
+
);
21
21
+
}
22
22
+
false => {
23
23
+
println!(
24
24
+
"This wil set up your environment with the default configuration.\nDo you want to continue? (y/N)",
25
25
+
);
26
26
+
}
27
27
+
}
28
28
+
29
29
+
let mut input = String::new();
30
30
+
std::io::stdin().read_line(&mut input)?;
31
31
+
if !input.trim().eq_ignore_ascii_case("y") {
32
32
+
println!("Setup cancelled.");
33
33
+
return Ok(());
34
34
+
}
35
35
+
}
36
36
+
37
37
+
cfg.setup_environment(dry_run)?;
38
38
+
39
39
+
Ok(())
40
40
+
}
+36
src/command.rs
···
1
1
+
use std::process::Command;
2
2
+
3
3
+
use anyhow::Error;
4
4
+
use owo_colors::OwoColorize;
5
5
+
6
6
+
pub fn run_command(cmd: &str, args: &[&str]) -> Result<(), Error> {
7
7
+
println!(
8
8
+
"{} {} {}",
9
9
+
"=>".green(),
10
10
+
cmd.green(),
11
11
+
args.join(" ").green()
12
12
+
);
13
13
+
Command::new(cmd)
14
14
+
.args(args)
15
15
+
.env(
16
16
+
"PATH",
17
17
+
format!(
18
18
+
"{}/.local/bin:{}",
19
19
+
std::env::var("HOME")?,
20
20
+
std::env::var("PATH")?
21
21
+
),
22
22
+
)
23
23
+
.status()?;
24
24
+
Ok(())
25
25
+
}
26
26
+
27
27
+
pub fn run_command_without_local_path(cmd: &str, args: &[&str]) -> Result<(), Error> {
28
28
+
println!(
29
29
+
"{} {} {}",
30
30
+
"=>".green(),
31
31
+
cmd.green(),
32
32
+
args.join(" ").green()
33
33
+
);
34
34
+
Command::new(cmd).args(args).status()?;
35
35
+
Ok(())
36
36
+
}
+143
src/config.rs
···
1
1
+
use anyhow::Result;
2
2
+
use owo_colors::OwoColorize;
3
3
+
use serde::{Deserialize, Serialize};
4
4
+
use std::collections::HashMap;
5
5
+
6
6
+
use crate::apply::SetupStep;
7
7
+
8
8
+
#[derive(Debug, Clone, Serialize, Deserialize)]
9
9
+
pub struct OhMyPosh {
10
10
+
#[serde(skip_serializing_if = "Option::is_none")]
11
11
+
pub theme: Option<String>,
12
12
+
}
13
13
+
14
14
+
#[derive(Debug, Clone, Serialize, Deserialize)]
15
15
+
pub struct Configuration {
16
16
+
#[serde(skip_serializing_if = "Option::is_none")]
17
17
+
pub stow: Option<HashMap<String, String>>,
18
18
+
19
19
+
#[serde(skip_serializing_if = "Option::is_none")]
20
20
+
pub mise: Option<HashMap<String, String>>,
21
21
+
22
22
+
#[serde(skip_serializing_if = "Option::is_none")]
23
23
+
pub nix: Option<HashMap<String, String>>,
24
24
+
25
25
+
#[serde(skip_serializing_if = "Option::is_none")]
26
26
+
#[serde(rename = "apt-get")]
27
27
+
pub apt_get: Option<Vec<String>>,
28
28
+
29
29
+
#[serde(skip_serializing_if = "Option::is_none")]
30
30
+
pub pkgx: Option<HashMap<String, String>>,
31
31
+
32
32
+
#[serde(skip_serializing_if = "Option::is_none")]
33
33
+
pub curl: Option<HashMap<String, String>>,
34
34
+
35
35
+
#[serde(skip_serializing_if = "Option::is_none")]
36
36
+
#[serde(rename = "ble.sh")]
37
37
+
pub blesh: Option<bool>,
38
38
+
39
39
+
#[serde(skip_serializing_if = "Option::is_none")]
40
40
+
pub oh_my_posh: Option<OhMyPosh>,
41
41
+
42
42
+
#[serde(skip_serializing_if = "Option::is_none")]
43
43
+
pub zoxide: Option<bool>,
44
44
+
45
45
+
#[serde(skip_serializing_if = "Option::is_none")]
46
46
+
pub alias: Option<HashMap<String, String>>,
47
47
+
}
48
48
+
49
49
+
impl Configuration {
50
50
+
pub fn setup_environment(&self, dry_run: bool) -> Result<()> {
51
51
+
let steps: Vec<SetupStep> = vec![
52
52
+
Some(SetupStep::Paths),
53
53
+
self.apt_get.as_deref().map(SetupStep::AptGet),
54
54
+
self.curl.as_ref().map(SetupStep::Curl),
55
55
+
self.pkgx.as_ref().map(SetupStep::Pkgx),
56
56
+
self.mise.as_ref().map(SetupStep::Mise),
57
57
+
self.blesh.map(SetupStep::BleSh),
58
58
+
self.zoxide.map(SetupStep::Zoxide),
59
59
+
self.nix.as_ref().map(SetupStep::Nix),
60
60
+
self.stow.as_ref().map(SetupStep::Stow),
61
61
+
self.oh_my_posh
62
62
+
.as_ref()
63
63
+
.map(|omp| SetupStep::OhMyPosh(omp.theme.as_deref().unwrap_or("tokyonight_storm"))),
64
64
+
self.alias.as_ref().map(SetupStep::Alias),
65
65
+
]
66
66
+
.into_iter()
67
67
+
.flatten()
68
68
+
.collect();
69
69
+
70
70
+
if dry_run {
71
71
+
println!("{}", "=== Dry Run: Environment Setup ===".yellow().bold());
72
72
+
println!("Steps to be executed ({} total):", steps.len());
73
73
+
for (i, step) in steps.iter().enumerate() {
74
74
+
println!("\n=> Step {}:\n{}", i + 1, step.format_dry_run());
75
75
+
}
76
76
+
println!("{}", "=== Dry Run Complete ===".yellow().bold());
77
77
+
} else {
78
78
+
for step in steps {
79
79
+
step.run()?;
80
80
+
}
81
81
+
}
82
82
+
Ok(())
83
83
+
}
84
84
+
}
85
85
+
86
86
+
impl Default for Configuration {
87
87
+
fn default() -> Self {
88
88
+
Configuration {
89
89
+
apt_get: Some(
90
90
+
vec![
91
91
+
"build-essential",
92
92
+
"curl",
93
93
+
"git",
94
94
+
"gawk",
95
95
+
"wget",
96
96
+
"unzip",
97
97
+
"autoconf",
98
98
+
"automake",
99
99
+
"cmake",
100
100
+
"tmux",
101
101
+
"openssh-server",
102
102
+
"openssh-client",
103
103
+
"httpie",
104
104
+
"code",
105
105
+
"screenfetch",
106
106
+
]
107
107
+
.into_iter()
108
108
+
.map(String::from)
109
109
+
.collect(),
110
110
+
),
111
111
+
pkgx: Some(HashMap::from([
112
112
+
("tig".into(), "latest".into()),
113
113
+
("rg".into(), "latest".into()),
114
114
+
("jq".into(), "latest".into()),
115
115
+
("neovim.io".into(), "latest".into()),
116
116
+
("fzf".into(), "latest".into()),
117
117
+
("zellij".into(), "latest".into()),
118
118
+
("glow".into(), "latest".into()),
119
119
+
("gh".into(), "latest".into()),
120
120
+
("eza".into(), "latest".into()),
121
121
+
])),
122
122
+
curl: Some(HashMap::from([
123
123
+
(
124
124
+
"oh-my-posh".into(),
125
125
+
"https://ohmyposh.dev/install.sh".into(),
126
126
+
),
127
127
+
("atuin".into(), "https://setup.atuin.sh".into()),
128
128
+
("bun".into(), "https://bun.sh/install".into()),
129
129
+
("deno".into(), "https://deno.land/install.sh".into()),
130
130
+
("pkgx".into(), "https://pkgx.sh".into()),
131
131
+
])),
132
132
+
mise: Some(HashMap::from([("node".into(), "latest".into())])),
133
133
+
blesh: Some(true),
134
134
+
zoxide: Some(true),
135
135
+
nix: None,
136
136
+
stow: None,
137
137
+
oh_my_posh: Some(OhMyPosh {
138
138
+
theme: Some("tokyonight_storm".into()),
139
139
+
}),
140
140
+
alias: Some(HashMap::from([("ls".into(), "eza -lh".into())])),
141
141
+
}
142
142
+
}
143
143
+
}
+1
src/consts.rs
···
1
1
+
pub const CONFIG_FILE: &str = "oh-my-droid.toml";
+68
src/main.rs
···
1
1
+
use anyhow::Error;
2
2
+
use clap::{Command, arg};
3
3
+
use owo_colors::OwoColorize;
4
4
+
5
5
+
use crate::{
6
6
+
cmd::{init::init, setup::setup},
7
7
+
consts::CONFIG_FILE,
8
8
+
};
9
9
+
10
10
+
pub mod apply;
11
11
+
pub mod cmd;
12
12
+
pub mod command;
13
13
+
pub mod config;
14
14
+
pub mod consts;
15
15
+
16
16
+
fn cli() -> Command {
17
17
+
let banner = format!(
18
18
+
"{}\nTurn a fresh {} into a fully-configured, beautiful, and modern web development system by running a single command.",
19
19
+
r#"
20
20
+
______ _________ ______________
21
21
+
_________ /_ _______ ________ __ ______ /_______________(_)_____ /
22
22
+
_ __ \_ __ \ __ __ `__ \_ / / / _ __ /__ ___/ __ \_ /_ __ /
23
23
+
/ /_/ / / / / _ / / / / / /_/ / / /_/ / _ / / /_/ / / / /_/ /
24
24
+
\____//_/ /_/ /_/ /_/ /_/_\__, / \__,_/ /_/ \____//_/ \__,_/
25
25
+
/____/
26
26
+
27
27
+
"#
28
28
+
.green(),
29
29
+
"Android 15+ Linux Terminal".green()
30
30
+
);
31
31
+
32
32
+
Command::new("oh-my-droid")
33
33
+
.version(env!("CARGO_PKG_VERSION"))
34
34
+
.author("Tsiry Sandratraina <tsiry.sndr@rocksky.app>")
35
35
+
.about(&banner)
36
36
+
.subcommand(Command::new("init").about(&format!(
37
37
+
"Write the initial configuration file {}.",
38
38
+
CONFIG_FILE.green()
39
39
+
)))
40
40
+
.subcommand(
41
41
+
Command::new("setup")
42
42
+
.about("Set up the environment with the default configuration.")
43
43
+
.arg(arg!(-d --"dry-run" "Simulate the setup process without making any changes."))
44
44
+
.arg(arg!(-y --"yes" "Skip confirmation prompts during setup.")),
45
45
+
)
46
46
+
.arg(arg!(-d --"dry-run" "Simulate the setup process without making any changes."))
47
47
+
.arg(arg!(-y --"yes" "Skip confirmation prompts during setup."))
48
48
+
}
49
49
+
50
50
+
fn main() -> Result<(), Error> {
51
51
+
let matches = cli().get_matches();
52
52
+
53
53
+
match matches.subcommand() {
54
54
+
Some(("init", _)) => init()?,
55
55
+
Some(("setup", args)) => {
56
56
+
let yes = args.get_flag("yes");
57
57
+
let dry_run = args.get_flag("dry-run");
58
58
+
setup(dry_run, yes)?
59
59
+
}
60
60
+
_ => {
61
61
+
let yes = matches.get_flag("yes");
62
62
+
let dry_run = matches.get_flag("dry-run");
63
63
+
setup(dry_run, yes)?
64
64
+
}
65
65
+
}
66
66
+
67
67
+
Ok(())
68
68
+
}