diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Cargo.lock | 254 | ||||
-rw-r--r-- | Cargo.toml | 5 | ||||
-rw-r--r-- | src/backup.rs | 28 | ||||
-rw-r--r-- | src/config.rs | 7 | ||||
-rw-r--r-- | src/main.rs | 47 | ||||
-rw-r--r-- | src/packages.rs | 2 | ||||
-rw-r--r-- | src/packages/pacman.rs | 18 | ||||
-rw-r--r-- | src/packages/portage.rs | 5 | ||||
-rw-r--r-- | src/pathinfo.rs | 32 |
10 files changed, 324 insertions, 75 deletions
@@ -1,3 +1,4 @@ | |||
1 | /target | 1 | /target |
2 | /backup* | 2 | /backup* |
3 | tags | 3 | tags |
4 | *.log | ||
@@ -18,12 +18,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" | 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" |
19 | 19 | ||
20 | [[package]] | 20 | [[package]] |
21 | name = "aho-corasick" | ||
22 | version = "1.1.3" | ||
23 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
24 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" | ||
25 | dependencies = [ | ||
26 | "memchr", | ||
27 | ] | ||
28 | |||
29 | [[package]] | ||
21 | name = "anyhow" | 30 | name = "anyhow" |
22 | version = "1.0.86" | 31 | version = "1.0.86" |
23 | source = "registry+https://github.com/rust-lang/crates.io-index" | 32 | source = "registry+https://github.com/rust-lang/crates.io-index" |
24 | checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" | 33 | checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" |
25 | 34 | ||
26 | [[package]] | 35 | [[package]] |
36 | name = "arps" | ||
37 | version = "0.1.0" | ||
38 | dependencies = [ | ||
39 | "anyhow", | ||
40 | "color-eyre", | ||
41 | "config", | ||
42 | "gethostname", | ||
43 | "serde", | ||
44 | "serde_json", | ||
45 | "thiserror", | ||
46 | "toml", | ||
47 | "tracing", | ||
48 | "tracing-appender", | ||
49 | "tracing-subscriber", | ||
50 | "uuid", | ||
51 | ] | ||
52 | |||
53 | [[package]] | ||
27 | name = "async-trait" | 54 | name = "async-trait" |
28 | version = "0.1.82" | 55 | version = "0.1.82" |
29 | source = "registry+https://github.com/rust-lang/crates.io-index" | 56 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -174,6 +201,21 @@ dependencies = [ | |||
174 | ] | 201 | ] |
175 | 202 | ||
176 | [[package]] | 203 | [[package]] |
204 | name = "crossbeam-channel" | ||
205 | version = "0.5.13" | ||
206 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
207 | checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" | ||
208 | dependencies = [ | ||
209 | "crossbeam-utils", | ||
210 | ] | ||
211 | |||
212 | [[package]] | ||
213 | name = "crossbeam-utils" | ||
214 | version = "0.8.20" | ||
215 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
216 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" | ||
217 | |||
218 | [[package]] | ||
177 | name = "crunchy" | 219 | name = "crunchy" |
178 | version = "0.2.2" | 220 | version = "0.2.2" |
179 | source = "registry+https://github.com/rust-lang/crates.io-index" | 221 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -190,6 +232,15 @@ dependencies = [ | |||
190 | ] | 232 | ] |
191 | 233 | ||
192 | [[package]] | 234 | [[package]] |
235 | name = "deranged" | ||
236 | version = "0.3.11" | ||
237 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
238 | checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" | ||
239 | dependencies = [ | ||
240 | "powerfmt", | ||
241 | ] | ||
242 | |||
243 | [[package]] | ||
193 | name = "digest" | 244 | name = "digest" |
194 | version = "0.10.7" | 245 | version = "0.10.7" |
195 | source = "registry+https://github.com/rust-lang/crates.io-index" | 246 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -235,21 +286,6 @@ dependencies = [ | |||
235 | ] | 286 | ] |
236 | 287 | ||
237 | [[package]] | 288 | [[package]] |
238 | name = "fxbaup" | ||
239 | version = "0.1.0" | ||
240 | dependencies = [ | ||
241 | "anyhow", | ||
242 | "color-eyre", | ||
243 | "config", | ||
244 | "gethostname", | ||
245 | "serde", | ||
246 | "serde_json", | ||
247 | "thiserror", | ||
248 | "toml", | ||
249 | "uuid", | ||
250 | ] | ||
251 | |||
252 | [[package]] | ||
253 | name = "generic-array" | 289 | name = "generic-array" |
254 | version = "0.14.7" | 290 | version = "0.14.7" |
255 | source = "registry+https://github.com/rust-lang/crates.io-index" | 291 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -356,6 +392,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
356 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" | 392 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" |
357 | 393 | ||
358 | [[package]] | 394 | [[package]] |
395 | name = "log" | ||
396 | version = "0.4.22" | ||
397 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
398 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" | ||
399 | |||
400 | [[package]] | ||
401 | name = "matchers" | ||
402 | version = "0.1.0" | ||
403 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
404 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" | ||
405 | dependencies = [ | ||
406 | "regex-automata 0.1.10", | ||
407 | ] | ||
408 | |||
409 | [[package]] | ||
359 | name = "memchr" | 410 | name = "memchr" |
360 | version = "2.7.4" | 411 | version = "2.7.4" |
361 | source = "registry+https://github.com/rust-lang/crates.io-index" | 412 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -387,6 +438,22 @@ dependencies = [ | |||
387 | ] | 438 | ] |
388 | 439 | ||
389 | [[package]] | 440 | [[package]] |
441 | name = "nu-ansi-term" | ||
442 | version = "0.46.0" | ||
443 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
444 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" | ||
445 | dependencies = [ | ||
446 | "overload", | ||
447 | "winapi", | ||
448 | ] | ||
449 | |||
450 | [[package]] | ||
451 | name = "num-conv" | ||
452 | version = "0.1.0" | ||
453 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
454 | checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" | ||
455 | |||
456 | [[package]] | ||
390 | name = "object" | 457 | name = "object" |
391 | version = "0.32.2" | 458 | version = "0.32.2" |
392 | source = "registry+https://github.com/rust-lang/crates.io-index" | 459 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -412,6 +479,12 @@ dependencies = [ | |||
412 | ] | 479 | ] |
413 | 480 | ||
414 | [[package]] | 481 | [[package]] |
482 | name = "overload" | ||
483 | version = "0.1.1" | ||
484 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
485 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" | ||
486 | |||
487 | [[package]] | ||
415 | name = "owo-colors" | 488 | name = "owo-colors" |
416 | version = "3.5.0" | 489 | version = "3.5.0" |
417 | source = "registry+https://github.com/rust-lang/crates.io-index" | 490 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -475,6 +548,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
475 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" | 548 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" |
476 | 549 | ||
477 | [[package]] | 550 | [[package]] |
551 | name = "powerfmt" | ||
552 | version = "0.2.0" | ||
553 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
554 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" | ||
555 | |||
556 | [[package]] | ||
478 | name = "proc-macro2" | 557 | name = "proc-macro2" |
479 | version = "1.0.86" | 558 | version = "1.0.86" |
480 | source = "registry+https://github.com/rust-lang/crates.io-index" | 559 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -493,6 +572,50 @@ dependencies = [ | |||
493 | ] | 572 | ] |
494 | 573 | ||
495 | [[package]] | 574 | [[package]] |
575 | name = "regex" | ||
576 | version = "1.10.6" | ||
577 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
578 | checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" | ||
579 | dependencies = [ | ||
580 | "aho-corasick", | ||
581 | "memchr", | ||
582 | "regex-automata 0.4.7", | ||
583 | "regex-syntax 0.8.4", | ||
584 | ] | ||
585 | |||
586 | [[package]] | ||
587 | name = "regex-automata" | ||
588 | version = "0.1.10" | ||
589 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
590 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" | ||
591 | dependencies = [ | ||
592 | "regex-syntax 0.6.29", | ||
593 | ] | ||
594 | |||
595 | [[package]] | ||
596 | name = "regex-automata" | ||
597 | version = "0.4.7" | ||
598 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
599 | checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" | ||
600 | dependencies = [ | ||
601 | "aho-corasick", | ||
602 | "memchr", | ||
603 | "regex-syntax 0.8.4", | ||
604 | ] | ||
605 | |||
606 | [[package]] | ||
607 | name = "regex-syntax" | ||
608 | version = "0.6.29" | ||
609 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
610 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" | ||
611 | |||
612 | [[package]] | ||
613 | name = "regex-syntax" | ||
614 | version = "0.8.4" | ||
615 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
616 | checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" | ||
617 | |||
618 | [[package]] | ||
496 | name = "ron" | 619 | name = "ron" |
497 | version = "0.8.1" | 620 | version = "0.8.1" |
498 | source = "registry+https://github.com/rust-lang/crates.io-index" | 621 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -607,6 +730,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
607 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" | 730 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" |
608 | 731 | ||
609 | [[package]] | 732 | [[package]] |
733 | name = "smallvec" | ||
734 | version = "1.13.2" | ||
735 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
736 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" | ||
737 | |||
738 | [[package]] | ||
610 | name = "syn" | 739 | name = "syn" |
611 | version = "2.0.77" | 740 | version = "2.0.77" |
612 | source = "registry+https://github.com/rust-lang/crates.io-index" | 741 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -648,6 +777,37 @@ dependencies = [ | |||
648 | ] | 777 | ] |
649 | 778 | ||
650 | [[package]] | 779 | [[package]] |
780 | name = "time" | ||
781 | version = "0.3.36" | ||
782 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
783 | checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" | ||
784 | dependencies = [ | ||
785 | "deranged", | ||
786 | "itoa", | ||
787 | "num-conv", | ||
788 | "powerfmt", | ||
789 | "serde", | ||
790 | "time-core", | ||
791 | "time-macros", | ||
792 | ] | ||
793 | |||
794 | [[package]] | ||
795 | name = "time-core" | ||
796 | version = "0.1.2" | ||
797 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
798 | checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" | ||
799 | |||
800 | [[package]] | ||
801 | name = "time-macros" | ||
802 | version = "0.2.18" | ||
803 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
804 | checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" | ||
805 | dependencies = [ | ||
806 | "num-conv", | ||
807 | "time-core", | ||
808 | ] | ||
809 | |||
810 | [[package]] | ||
651 | name = "tiny-keccak" | 811 | name = "tiny-keccak" |
652 | version = "2.0.2" | 812 | version = "2.0.2" |
653 | source = "registry+https://github.com/rust-lang/crates.io-index" | 813 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -697,10 +857,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
697 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" | 857 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" |
698 | dependencies = [ | 858 | dependencies = [ |
699 | "pin-project-lite", | 859 | "pin-project-lite", |
860 | "tracing-attributes", | ||
700 | "tracing-core", | 861 | "tracing-core", |
701 | ] | 862 | ] |
702 | 863 | ||
703 | [[package]] | 864 | [[package]] |
865 | name = "tracing-appender" | ||
866 | version = "0.2.3" | ||
867 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
868 | checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" | ||
869 | dependencies = [ | ||
870 | "crossbeam-channel", | ||
871 | "thiserror", | ||
872 | "time", | ||
873 | "tracing-subscriber", | ||
874 | ] | ||
875 | |||
876 | [[package]] | ||
877 | name = "tracing-attributes" | ||
878 | version = "0.1.27" | ||
879 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
880 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" | ||
881 | dependencies = [ | ||
882 | "proc-macro2", | ||
883 | "quote", | ||
884 | "syn", | ||
885 | ] | ||
886 | |||
887 | [[package]] | ||
704 | name = "tracing-core" | 888 | name = "tracing-core" |
705 | version = "0.1.32" | 889 | version = "0.1.32" |
706 | source = "registry+https://github.com/rust-lang/crates.io-index" | 890 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -721,14 +905,32 @@ dependencies = [ | |||
721 | ] | 905 | ] |
722 | 906 | ||
723 | [[package]] | 907 | [[package]] |
908 | name = "tracing-log" | ||
909 | version = "0.2.0" | ||
910 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
911 | checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" | ||
912 | dependencies = [ | ||
913 | "log", | ||
914 | "once_cell", | ||
915 | "tracing-core", | ||
916 | ] | ||
917 | |||
918 | [[package]] | ||
724 | name = "tracing-subscriber" | 919 | name = "tracing-subscriber" |
725 | version = "0.3.18" | 920 | version = "0.3.18" |
726 | source = "registry+https://github.com/rust-lang/crates.io-index" | 921 | source = "registry+https://github.com/rust-lang/crates.io-index" |
727 | checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" | 922 | checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" |
728 | dependencies = [ | 923 | dependencies = [ |
924 | "matchers", | ||
925 | "nu-ansi-term", | ||
926 | "once_cell", | ||
927 | "regex", | ||
729 | "sharded-slab", | 928 | "sharded-slab", |
929 | "smallvec", | ||
730 | "thread_local", | 930 | "thread_local", |
931 | "tracing", | ||
731 | "tracing-core", | 932 | "tracing-core", |
933 | "tracing-log", | ||
732 | ] | 934 | ] |
733 | 935 | ||
734 | [[package]] | 936 | [[package]] |
@@ -783,6 +985,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
783 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" | 985 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" |
784 | 986 | ||
785 | [[package]] | 987 | [[package]] |
988 | name = "winapi" | ||
989 | version = "0.3.9" | ||
990 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
991 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" | ||
992 | dependencies = [ | ||
993 | "winapi-i686-pc-windows-gnu", | ||
994 | "winapi-x86_64-pc-windows-gnu", | ||
995 | ] | ||
996 | |||
997 | [[package]] | ||
998 | name = "winapi-i686-pc-windows-gnu" | ||
999 | version = "0.4.0" | ||
1000 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1001 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" | ||
1002 | |||
1003 | [[package]] | ||
1004 | name = "winapi-x86_64-pc-windows-gnu" | ||
1005 | version = "0.4.0" | ||
1006 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1007 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" | ||
1008 | |||
1009 | [[package]] | ||
786 | name = "windows-sys" | 1010 | name = "windows-sys" |
787 | version = "0.52.0" | 1011 | version = "0.52.0" |
788 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1012 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1,5 +1,5 @@ | |||
1 | [package] | 1 | [package] |
2 | name = "fxbaup" | 2 | name = "arps" |
3 | version = "0.1.0" | 3 | version = "0.1.0" |
4 | edition = "2021" | 4 | edition = "2021" |
5 | 5 | ||
@@ -12,4 +12,7 @@ serde = { version = "1.0.209", features = ["derive"] } | |||
12 | serde_json = "1.0.128" | 12 | serde_json = "1.0.128" |
13 | thiserror = "1.0.63" | 13 | thiserror = "1.0.63" |
14 | toml = "0.8.19" | 14 | toml = "0.8.19" |
15 | tracing = "0.1.40" | ||
16 | tracing-appender = "0.2.3" | ||
17 | tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } | ||
15 | uuid = { version = "1.10.0", features = ["v4"] } | 18 | uuid = { version = "1.10.0", features = ["v4"] } |
diff --git a/src/backup.rs b/src/backup.rs index 675f020..e463593 100644 --- a/src/backup.rs +++ b/src/backup.rs | |||
@@ -6,6 +6,7 @@ use std::{ | |||
6 | }; | 6 | }; |
7 | 7 | ||
8 | use serde::{Deserialize, Serialize}; | 8 | use serde::{Deserialize, Serialize}; |
9 | use tracing::info; | ||
9 | use uuid::Uuid; | 10 | use uuid::Uuid; |
10 | 11 | ||
11 | use crate::{ | 12 | use crate::{ |
@@ -15,7 +16,7 @@ use crate::{ | |||
15 | pathinfo::PathInfo, | 16 | pathinfo::PathInfo, |
16 | }; | 17 | }; |
17 | 18 | ||
18 | pub type BackupId = String; | 19 | pub type Id = String; |
19 | 20 | ||
20 | #[derive(Debug, Serialize, Deserialize)] | 21 | #[derive(Debug, Serialize, Deserialize)] |
21 | pub struct Backup { | 22 | pub struct Backup { |
@@ -43,13 +44,12 @@ impl Backup { | |||
43 | } | 44 | } |
44 | 45 | ||
45 | pub fn save(&self, config: &Config) -> Result<()> { | 46 | pub fn save(&self, config: &Config) -> Result<()> { |
46 | println!("Save Backup {:?}", self.get_location(config)); | 47 | info!("Save Backup {:?}", self.get_location(config)); |
47 | // println!("{self:#?}"); | ||
48 | self.get_location(config).append_to_root(config)?; | 48 | self.get_location(config).append_to_root(config)?; |
49 | 49 | ||
50 | let backup_root = self.get_location(config).get_absolute_dir(config); | 50 | let backup_root = self.get_location(config).get_absolute_dir(config); |
51 | create_dir_all(&backup_root).unwrap(); | 51 | create_dir_all(&backup_root).unwrap(); |
52 | let path = format!("{}/index.json", backup_root); | 52 | let path = format!("{backup_root}/index.json"); |
53 | let mut f = File::create(path).unwrap(); | 53 | let mut f = File::create(path).unwrap(); |
54 | f.write_all(&serde_json::to_vec(self).unwrap()).unwrap(); | 54 | f.write_all(&serde_json::to_vec(self).unwrap()).unwrap(); |
55 | 55 | ||
@@ -62,7 +62,7 @@ impl Backup { | |||
62 | 62 | ||
63 | pub fn get_last(config: &Config) -> Result<Option<Self>> { | 63 | pub fn get_last(config: &Config) -> Result<Option<Self>> { |
64 | let backup_index_root = format!("{}/index.json", config.root); | 64 | let backup_index_root = format!("{}/index.json", config.root); |
65 | let list: Vec<BackupLocation> = match Self::get_json_content(&backup_index_root) { | 65 | let list: Vec<IndexEntry> = match Self::get_json_content(&backup_index_root) { |
66 | Ok(list) => list, | 66 | Ok(list) => list, |
67 | Err(err) => { | 67 | Err(err) => { |
68 | if err.to_string() == "io: No such file or directory (os error 2)" { | 68 | if err.to_string() == "io: No such file or directory (os error 2)" { |
@@ -78,9 +78,9 @@ impl Backup { | |||
78 | )?)) | 78 | )?)) |
79 | } | 79 | } |
80 | 80 | ||
81 | pub fn from_index(config: &Config, id: &BackupId) -> Result<Self> { | 81 | pub fn from_index(config: &Config, id: &Id) -> Result<Self> { |
82 | let backup_index_root = format!("{}/index.json", config.root); | 82 | let backup_index_root = format!("{}/index.json", config.root); |
83 | let list: Vec<BackupLocation> = Self::get_json_content(&backup_index_root)?; | 83 | let list: Vec<IndexEntry> = Self::get_json_content(&backup_index_root)?; |
84 | let index_loc = list | 84 | let index_loc = list |
85 | .iter() | 85 | .iter() |
86 | .find(|bl| &bl.id == id) | 86 | .find(|bl| &bl.id == id) |
@@ -94,10 +94,10 @@ impl Backup { | |||
94 | Ok(index_file) | 94 | Ok(index_file) |
95 | } | 95 | } |
96 | 96 | ||
97 | pub fn get_location(&self, config: &Config) -> BackupLocation { | 97 | pub fn get_location(&self, config: &Config) -> IndexEntry { |
98 | let rel_location = format!("{}_{}", config.device, self.timestamp); | 98 | let rel_location = format!("{}_{}", config.device, self.timestamp); |
99 | 99 | ||
100 | BackupLocation { | 100 | IndexEntry { |
101 | id: self.id.to_string(), | 101 | id: self.id.to_string(), |
102 | rel_location, | 102 | rel_location, |
103 | } | 103 | } |
@@ -106,7 +106,7 @@ impl Backup { | |||
106 | pub fn get_absolute_file_location(&self, config: &Config, rel_location: &str) -> String { | 106 | pub fn get_absolute_file_location(&self, config: &Config, rel_location: &str) -> String { |
107 | let loc = self.get_location(config).get_absolute_dir(config); | 107 | let loc = self.get_location(config).get_absolute_dir(config); |
108 | 108 | ||
109 | format!("{}/{}", loc, rel_location) | 109 | format!("{loc}/{rel_location}") |
110 | } | 110 | } |
111 | 111 | ||
112 | fn get_json_content<T: for<'a> Deserialize<'a>>(path: &str) -> Result<T> { | 112 | fn get_json_content<T: for<'a> Deserialize<'a>>(path: &str) -> Result<T> { |
@@ -125,12 +125,12 @@ impl Backup { | |||
125 | } | 125 | } |
126 | 126 | ||
127 | #[derive(Debug, Clone, Serialize, Deserialize)] | 127 | #[derive(Debug, Clone, Serialize, Deserialize)] |
128 | pub struct BackupLocation { | 128 | pub struct IndexEntry { |
129 | id: BackupId, | 129 | id: Id, |
130 | rel_location: String, | 130 | rel_location: String, |
131 | } | 131 | } |
132 | 132 | ||
133 | impl BackupLocation { | 133 | impl IndexEntry { |
134 | pub fn get_absolute_dir(&self, config: &Config) -> String { | 134 | pub fn get_absolute_dir(&self, config: &Config) -> String { |
135 | format!("{}/{}", config.root, self.rel_location) | 135 | format!("{}/{}", config.root, self.rel_location) |
136 | } | 136 | } |
@@ -142,7 +142,7 @@ impl BackupLocation { | |||
142 | let mut f = File::open(&path)?; | 142 | let mut f = File::open(&path)?; |
143 | let mut content = String::new(); | 143 | let mut content = String::new(); |
144 | f.read_to_string(&mut content)?; | 144 | f.read_to_string(&mut content)?; |
145 | let mut loc: Vec<BackupLocation> = serde_json::from_str(&content)?; | 145 | let mut loc: Vec<IndexEntry> = serde_json::from_str(&content)?; |
146 | 146 | ||
147 | let mut f = File::create(path)?; | 147 | let mut f = File::create(path)?; |
148 | loc.push(self.clone()); | 148 | loc.push(self.clone()); |
diff --git a/src/config.rs b/src/config.rs index 439c17c..13dd0e4 100644 --- a/src/config.rs +++ b/src/config.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | use config::{File, Map}; | 1 | use config::{File, Map}; |
2 | use serde::{Deserialize, Serialize}; | 2 | use serde::{Deserialize, Serialize}; |
3 | use tracing::{debug, trace}; | ||
3 | 4 | ||
4 | #[derive(Debug, Serialize, Deserialize)] | 5 | #[derive(Debug, Serialize, Deserialize)] |
5 | #[serde(default)] | 6 | #[serde(default)] |
@@ -27,11 +28,15 @@ impl Default for Config { | |||
27 | 28 | ||
28 | impl Config { | 29 | impl Config { |
29 | pub fn load() -> Result<Self, config::ConfigError> { | 30 | pub fn load() -> Result<Self, config::ConfigError> { |
31 | debug!("load config"); | ||
30 | let config = config::Config::builder() | 32 | let config = config::Config::builder() |
31 | .add_source(File::with_name("config.toml").required(false)) | 33 | .add_source(File::with_name("config.toml").required(false)) |
32 | .add_source(config::Environment::with_prefix("FXBAUP").separator("_")) | 34 | .add_source(config::Environment::with_prefix("FXBAUP").separator("_")) |
33 | .build()?; | 35 | .build()?; |
34 | 36 | ||
35 | config.try_deserialize() | 37 | let cfg = config.try_deserialize(); |
38 | trace!(?cfg, "loaded config"); | ||
39 | |||
40 | cfg | ||
36 | } | 41 | } |
37 | } | 42 | } |
diff --git a/src/main.rs b/src/main.rs index e67e535..1284e0c 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -1,6 +1,8 @@ | |||
1 | use backup::Backup; | 1 | use backup::Backup; |
2 | use config::Config; | 2 | use config::Config; |
3 | use packages::{pacman::Pacman, PackageManager}; | 3 | use packages::{pacman::Pacman, PackageManager}; |
4 | use tracing::{debug, info, level_filters::LevelFilter}; | ||
5 | use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; | ||
4 | 6 | ||
5 | mod backup; | 7 | mod backup; |
6 | mod config; | 8 | mod config; |
@@ -11,30 +13,39 @@ mod pathinfo; | |||
11 | fn main() -> color_eyre::Result<()> { | 13 | fn main() -> color_eyre::Result<()> { |
12 | color_eyre::install()?; | 14 | color_eyre::install()?; |
13 | 15 | ||
16 | let file_appender = tracing_appender::rolling::never("./", "arps.log"); | ||
17 | let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender); | ||
18 | |||
19 | tracing_subscriber::registry() | ||
20 | .with( | ||
21 | fmt::layer() | ||
22 | .with_writer(non_blocking) | ||
23 | .with_file(false) | ||
24 | .with_ansi(false) | ||
25 | .without_time(), | ||
26 | ) | ||
27 | .with(fmt::layer().with_file(false).without_time()) | ||
28 | .with( | ||
29 | EnvFilter::builder() | ||
30 | .with_default_directive(LevelFilter::INFO.into()) | ||
31 | .from_env_lossy(), | ||
32 | ) | ||
33 | .init(); | ||
34 | debug!("logging initialized"); | ||
35 | |||
14 | let mut cfg = Config::load()?; | 36 | let mut cfg = Config::load()?; |
15 | cfg.user.push("fx".to_string()); | 37 | cfg.user.push("fx".to_string()); |
16 | cfg.directories.push("~/.config/nvim".to_string()); | 38 | cfg.directories.push("~/.config/nvim".to_string()); |
17 | // cfg.directories.push("~/.config/hypr".to_string()); | ||
18 | cfg.root = "./backup".to_string(); | 39 | cfg.root = "./backup".to_string(); |
19 | // cfg.root = "./backup-test".to_string(); | ||
20 | // cfg.directories.push("u:/code/proj/fxbaup/backup-test-dir".to_string()); | ||
21 | 40 | ||
22 | let pacman = Pacman; | 41 | let pacman = Pacman; |
23 | let pkgs = pacman.get_installed()?; | 42 | let pkgs = pacman.get_installed()?; |
24 | 43 | let backup = Backup::create(&cfg, pkgs); | |
25 | let backup = Backup::create(&cfg, pkgs)?; | 44 | // info!(?backup); |
26 | // println!("{backup:#?}"); | 45 | // pacman.install(vec![Package { |
27 | 46 | // id: "lapce".to_string(), | |
28 | backup.save(&cfg)?; | 47 | // version: "0.4.2-1".to_string(), |
29 | 48 | // explicit: true, | |
30 | // PathInfo::compare_to_last_modified(&cfg, &LocationRoot::User("fx".to_string()), "code/proj/fxbaub/backup-test-dir/size.txt")?; | 49 | // }])?; |
31 | // PathInfo::compare_to_last_modified(&cfg, &LocationRoot::User("fx".to_string()), "code/proj/fxbaub/backup-test-dir/content.txt")?; | ||
32 | |||
33 | // let index = Backup::get_index(&cfg, None)?; | ||
34 | |||
35 | // println!("{index:#?}"); | ||
36 | |||
37 | // let fi = FileInfo::new("~/.config/nvim", &cfg)?; | ||
38 | // println!("{:?}", fi.get_absolute_path()); | ||
39 | Ok(()) | 50 | Ok(()) |
40 | } | 51 | } |
diff --git a/src/packages.rs b/src/packages.rs index e7b4c3d..5ee5664 100644 --- a/src/packages.rs +++ b/src/packages.rs | |||
@@ -15,5 +15,5 @@ pub struct Package { | |||
15 | pub trait PackageManager { | 15 | pub trait PackageManager { |
16 | fn get_installed(&self) -> Result<Vec<Package>>; | 16 | fn get_installed(&self) -> Result<Vec<Package>>; |
17 | 17 | ||
18 | fn install(&self, pkgs: Vec<Package>); | 18 | fn install(&self, pkgs: Vec<Package>) -> Result<()>; |
19 | } | 19 | } |
diff --git a/src/packages/pacman.rs b/src/packages/pacman.rs index b5be4c0..e10c6fb 100644 --- a/src/packages/pacman.rs +++ b/src/packages/pacman.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use std::process::Command; | 1 | use std::process::{Command, Stdio}; |
2 | 2 | ||
3 | use super::{Package, PackageManager}; | 3 | use super::{Package, PackageManager}; |
4 | 4 | ||
@@ -34,13 +34,23 @@ impl PackageManager for Pacman { | |||
34 | id: split[0].to_string(), | 34 | id: split[0].to_string(), |
35 | version: split[1].to_string(), | 35 | version: split[1].to_string(), |
36 | explicit, | 36 | explicit, |
37 | }) | 37 | }); |
38 | } | 38 | } |
39 | 39 | ||
40 | Ok(pkgs) | 40 | Ok(pkgs) |
41 | } | 41 | } |
42 | 42 | ||
43 | fn install(&self, _pkgs: Vec<super::Package>) { | 43 | fn install(&self, pkgs: Vec<super::Package>) -> Result<()> { |
44 | todo!(); | 44 | let mut args = vec!["--noconfirm".to_string(), "-S".to_string()]; |
45 | |||
46 | for pkg in pkgs { | ||
47 | args.push(pkg.id); | ||
48 | } | ||
49 | Command::new("pacman") | ||
50 | .stdout(Stdio::inherit()) | ||
51 | .args(args) | ||
52 | .spawn()? | ||
53 | .wait_with_output()?; | ||
54 | Ok(()) | ||
45 | } | 55 | } |
46 | } | 56 | } |
diff --git a/src/packages/portage.rs b/src/packages/portage.rs index 6b9e508..f9a760b 100644 --- a/src/packages/portage.rs +++ b/src/packages/portage.rs | |||
@@ -1,3 +1,5 @@ | |||
1 | use tracing::error; | ||
2 | |||
1 | use super::PackageManager; | 3 | use super::PackageManager; |
2 | 4 | ||
3 | pub struct Portage; | 5 | pub struct Portage; |
@@ -7,7 +9,8 @@ impl PackageManager for Portage { | |||
7 | todo!() | 9 | todo!() |
8 | } | 10 | } |
9 | 11 | ||
10 | fn install(&self, pkgs: Vec<super::Package>) { | 12 | fn install(&self, pkgs: Vec<super::Package>) -> crate::error::Result<()> { |
13 | error!("Install {pkgs:?}"); | ||
11 | todo!() | 14 | todo!() |
12 | } | 15 | } |
13 | } | 16 | } |
diff --git a/src/pathinfo.rs b/src/pathinfo.rs index 212dd2a..5b9aa21 100644 --- a/src/pathinfo.rs +++ b/src/pathinfo.rs | |||
@@ -6,9 +6,10 @@ use std::{ | |||
6 | }; | 6 | }; |
7 | 7 | ||
8 | use serde::{Deserialize, Serialize}; | 8 | use serde::{Deserialize, Serialize}; |
9 | use tracing::info; | ||
9 | 10 | ||
10 | use crate::{ | 11 | use crate::{ |
11 | backup::{Backup, BackupId}, | 12 | backup::{Backup, Id}, |
12 | config::Config, | 13 | config::Config, |
13 | error::{Error, Result}, | 14 | error::{Error, Result}, |
14 | }; | 15 | }; |
@@ -18,7 +19,7 @@ pub struct PathInfo { | |||
18 | is_file: bool, | 19 | is_file: bool, |
19 | rel_location: String, | 20 | rel_location: String, |
20 | location_root: LocationRoot, | 21 | location_root: LocationRoot, |
21 | last_modified: Option<BackupId>, | 22 | last_modified: Option<Id>, |
22 | children: Vec<PathInfo>, | 23 | children: Vec<PathInfo>, |
23 | } | 24 | } |
24 | 25 | ||
@@ -34,7 +35,7 @@ impl PathInfo { | |||
34 | rel_location: &str, | 35 | rel_location: &str, |
35 | location_root: &LocationRoot, | 36 | location_root: &LocationRoot, |
36 | ) -> Result<Self> { | 37 | ) -> Result<Self> { |
37 | println!("Handling {rel_location}"); | 38 | info!("Handling {rel_location}"); |
38 | let path = Self::get_abs_path(&location_root.to_string(), rel_location); | 39 | let path = Self::get_abs_path(&location_root.to_string(), rel_location); |
39 | Ok(if path.is_dir() { | 40 | Ok(if path.is_dir() { |
40 | let mut last_modified = Some(String::new()); | 41 | let mut last_modified = Some(String::new()); |
@@ -51,7 +52,7 @@ impl PathInfo { | |||
51 | }; | 52 | }; |
52 | let handle = Self::handle_dir(config, rl.1, location_root)?; | 53 | let handle = Self::handle_dir(config, rl.1, location_root)?; |
53 | if let Some(lm) = handle.last_modified.clone() { | 54 | if let Some(lm) = handle.last_modified.clone() { |
54 | if last_modified != None { | 55 | if last_modified.is_some() { |
55 | let ts = Backup::from_index(config, &lm)?.timestamp; | 56 | let ts = Backup::from_index(config, &lm)?.timestamp; |
56 | if ts > last_modified_timestamp { | 57 | if ts > last_modified_timestamp { |
57 | last_modified_timestamp = ts; | 58 | last_modified_timestamp = ts; |
@@ -82,7 +83,7 @@ impl PathInfo { | |||
82 | ) -> Result<Self> { | 83 | ) -> Result<Self> { |
83 | let last_modified = Self::compare_to_last_modified(config, location_root, rel_location)?; | 84 | let last_modified = Self::compare_to_last_modified(config, location_root, rel_location)?; |
84 | 85 | ||
85 | println!("From file {rel_location} ({:?})", last_modified); | 86 | info!("From file {rel_location} ({last_modified:?})"); |
86 | 87 | ||
87 | Ok(Self { | 88 | Ok(Self { |
88 | rel_location: rel_location.to_string(), | 89 | rel_location: rel_location.to_string(), |
@@ -107,7 +108,6 @@ impl PathInfo { | |||
107 | let last_file_opt = Self::find_last_modified(files, rel_location, location_root); | 108 | let last_file_opt = Self::find_last_modified(files, rel_location, location_root); |
108 | let Some(last_file) = last_file_opt else { | 109 | let Some(last_file) = last_file_opt else { |
109 | // File didn't exist last Backup | 110 | // File didn't exist last Backup |
110 | println!("File didn't exist last Backup"); | ||
111 | return Ok(None); | 111 | return Ok(None); |
112 | }; | 112 | }; |
113 | 113 | ||
@@ -120,8 +120,7 @@ impl PathInfo { | |||
120 | let old_path = modified_backup.get_absolute_file_location(config, &last_file.rel_location); | 120 | let old_path = modified_backup.get_absolute_file_location(config, &last_file.rel_location); |
121 | let new_path = format!("{location_root}/{rel_location}"); | 121 | let new_path = format!("{location_root}/{rel_location}"); |
122 | 122 | ||
123 | let mut old = File::open(old_path)?; | 123 | let mut old = File::open(old_path)?; let mut new = File::open(new_path)?; |
124 | let mut new = File::open(new_path)?; | ||
125 | 124 | ||
126 | let old_len = old.metadata()?.len(); | 125 | let old_len = old.metadata()?.len(); |
127 | let new_len = new.metadata()?.len(); | 126 | let new_len = new.metadata()?.len(); |
@@ -147,15 +146,10 @@ impl PathInfo { | |||
147 | ) -> Option<PathInfo> { | 146 | ) -> Option<PathInfo> { |
148 | for path in files { | 147 | for path in files { |
149 | if path.is_file { | 148 | if path.is_file { |
150 | println!("Checking {}", path.rel_location); | ||
151 | println!("File rel: {} ?= {}", path.rel_location, rel_location); | ||
152 | println!("File rot: {} ?= {}", path.location_root, location_root); | ||
153 | if path.rel_location == rel_location && path.location_root == *location_root { | 149 | if path.rel_location == rel_location && path.location_root == *location_root { |
154 | println!("Return Some"); | ||
155 | return Some(path); | 150 | return Some(path); |
156 | }; | 151 | }; |
157 | } else { | 152 | } else { |
158 | println!("Checking all in {path:?}"); | ||
159 | let is_modified = | 153 | let is_modified = |
160 | PathInfo::find_last_modified(path.children, rel_location, location_root); | 154 | PathInfo::find_last_modified(path.children, rel_location, location_root); |
161 | if is_modified.is_some() { | 155 | if is_modified.is_some() { |
@@ -174,11 +168,9 @@ impl PathInfo { | |||
174 | if self.last_modified.is_some() { | 168 | if self.last_modified.is_some() { |
175 | return Ok(()); | 169 | return Ok(()); |
176 | } | 170 | } |
177 | println!("Save File {:?}", self.rel_location); | 171 | info!("Save File {:?}", self.rel_location); |
178 | if self.is_file { | 172 | if self.is_file { |
179 | let new_path = format!("{}/{}", backup_root, self.rel_location); | 173 | let new_path = format!("{}/{}", backup_root, self.rel_location); |
180 | // println!("New Path: {new_path}"); | ||
181 | // println!("Old Path: {:?}", self.get_absolute_path()); | ||
182 | let np = Path::new(&new_path); | 174 | let np = Path::new(&new_path); |
183 | if let Some(parent) = np.parent() { | 175 | if let Some(parent) = np.parent() { |
184 | create_dir_all(parent)?; | 176 | create_dir_all(parent)?; |
@@ -194,7 +186,7 @@ impl PathInfo { | |||
194 | } | 186 | } |
195 | 187 | ||
196 | fn get_abs_path(location_root: &str, rel_location: &str) -> PathBuf { | 188 | fn get_abs_path(location_root: &str, rel_location: &str) -> PathBuf { |
197 | let path = format!("{}/{}", location_root, rel_location); | 189 | let path = format!("{location_root}/{rel_location}"); |
198 | PathBuf::from(path) | 190 | PathBuf::from(path) |
199 | } | 191 | } |
200 | 192 | ||
@@ -383,7 +375,7 @@ mod tests { | |||
383 | config.root = "./backup-test".to_string(); | 375 | config.root = "./backup-test".to_string(); |
384 | config | 376 | config |
385 | .directories | 377 | .directories |
386 | .push("u:fx/code/proj/fxbaup/backup-test-dir".to_string()); | 378 | .push("u:fx/code/proj/arps/backup-test-dir".to_string()); |
387 | 379 | ||
388 | create_dir_all("./backup-test-dir")?; | 380 | create_dir_all("./backup-test-dir")?; |
389 | let mut f = File::create("./backup-test-dir/size.txt")?; | 381 | let mut f = File::create("./backup-test-dir/size.txt")?; |
@@ -403,12 +395,12 @@ mod tests { | |||
403 | let mut f = File::create("./backup-test-dir/content.txt")?; | 395 | let mut f = File::create("./backup-test-dir/content.txt")?; |
404 | f.write_all("unmodefied".as_bytes())?; | 396 | f.write_all("unmodefied".as_bytes())?; |
405 | 397 | ||
406 | let pi = PathInfo::from_path(&config, "u:fx/code/proj/fxbaup/backup-test-dir")?; | 398 | let pi = PathInfo::from_path(&config, "u:fx/code/proj/arps/backup-test-dir")?; |
407 | 399 | ||
408 | let last_backup = Backup::get_last(&config)?.unwrap(); | 400 | let last_backup = Backup::get_last(&config)?.unwrap(); |
409 | for file in pi.children { | 401 | for file in pi.children { |
410 | println!("test rel: {}", file.rel_location); | 402 | println!("test rel: {}", file.rel_location); |
411 | let res = if file.rel_location == "code/proj/fxbaup/backup-test-dir/nothing.txt" { | 403 | let res = if file.rel_location == "code/proj/arps/backup-test-dir/nothing.txt" { |
412 | Some(last_backup.id.clone()) | 404 | Some(last_backup.id.clone()) |
413 | } else { | 405 | } else { |
414 | None | 406 | None |