summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordiogo464 <[email protected]>2025-08-08 19:26:07 +0100
committerdiogo464 <[email protected]>2025-08-08 19:26:07 +0100
commitfb701e68633189a14594c66300a06b51ffd74711 (patch)
treec72b682dffc5ec51cad82b12c5266776a8b02dd0
parent455147e7db46c509abf6cb6debff5029c9b7971e (diff)
added common flags and refactored some code
-rw-r--r--fctdrive/src/main.rs110
1 files changed, 77 insertions, 33 deletions
diff --git a/fctdrive/src/main.rs b/fctdrive/src/main.rs
index 1d1e174..4f8f85f 100644
--- a/fctdrive/src/main.rs
+++ b/fctdrive/src/main.rs
@@ -659,6 +659,12 @@ struct Cli {
659 cmd: Cmd, 659 cmd: Cmd,
660} 660}
661 661
662#[derive(Debug, Parser)]
663struct CliCommon {
664 #[clap(long, default_value = "./", env = "FCTDRIVE_PATH")]
665 drive: PathBuf,
666}
667
662#[derive(Debug, Subcommand)] 668#[derive(Debug, Subcommand)]
663enum Cmd { 669enum Cmd {
664 CreateFile(CreateFileArgs), 670 CreateFile(CreateFileArgs),
@@ -671,6 +677,9 @@ enum Cmd {
671 677
672#[derive(Debug, Args)] 678#[derive(Debug, Args)]
673struct CreateFileArgs { 679struct CreateFileArgs {
680 #[clap(flatten)]
681 common: CliCommon,
682
674 #[clap(long)] 683 #[clap(long)]
675 timestamp: Option<u64>, 684 timestamp: Option<u64>,
676 685
@@ -686,6 +695,9 @@ struct CreateFileArgs {
686 695
687#[derive(Debug, Args)] 696#[derive(Debug, Args)]
688struct CreateDirArgs { 697struct CreateDirArgs {
698 #[clap(flatten)]
699 common: CliCommon,
700
689 #[clap(long)] 701 #[clap(long)]
690 timestamp: Option<u64>, 702 timestamp: Option<u64>,
691 703
@@ -698,6 +710,9 @@ struct CreateDirArgs {
698 710
699#[derive(Debug, Args)] 711#[derive(Debug, Args)]
700struct RemoveArgs { 712struct RemoveArgs {
713 #[clap(flatten)]
714 common: CliCommon,
715
701 #[clap(long)] 716 #[clap(long)]
702 timestamp: Option<u64>, 717 timestamp: Option<u64>,
703 718
@@ -710,6 +725,9 @@ struct RemoveArgs {
710 725
711#[derive(Debug, Args)] 726#[derive(Debug, Args)]
712struct RenameArgs { 727struct RenameArgs {
728 #[clap(flatten)]
729 common: CliCommon,
730
713 #[clap(long)] 731 #[clap(long)]
714 timestamp: Option<u64>, 732 timestamp: Option<u64>,
715 733
@@ -725,6 +743,9 @@ struct RenameArgs {
725 743
726#[derive(Debug, Args)] 744#[derive(Debug, Args)]
727struct LsArgs { 745struct LsArgs {
746 #[clap(flatten)]
747 common: CliCommon,
748
728 #[clap(short, long)] 749 #[clap(short, long)]
729 recursive: bool, 750 recursive: bool,
730 751
@@ -733,6 +754,9 @@ struct LsArgs {
733 754
734#[derive(Debug, Args)] 755#[derive(Debug, Args)]
735struct ImportArgs { 756struct ImportArgs {
757 #[clap(flatten)]
758 common: CliCommon,
759
736 #[clap(long)] 760 #[clap(long)]
737 timestamp: Option<u64>, 761 timestamp: Option<u64>,
738 762
@@ -757,11 +781,11 @@ fn main() {
757 781
758fn cmd_create_file(args: CreateFileArgs) { 782fn cmd_create_file(args: CreateFileArgs) {
759 let file_blob_id = blob_hash_file(&args.file).unwrap(); 783 let file_blob_id = blob_hash_file(&args.file).unwrap();
760 let _lock = write_lock();
761 784
785 let _lock = common_write_lock(&args.common);
762 let mut fs = Fs::default(); 786 let mut fs = Fs::default();
763 let mut ops = read_log_file(); 787 let mut ops = common_read_log_file(&args.common);
764 let store = BlobStore::new("blobs"); 788 let store = common_create_blob_store(&args.common);
765 ops.iter().for_each(|op| apply(&mut fs, op).unwrap()); 789 ops.iter().for_each(|op| apply(&mut fs, op).unwrap());
766 790
767 let timestamp = args.timestamp.unwrap_or_else(get_timestamp); 791 let timestamp = args.timestamp.unwrap_or_else(get_timestamp);
@@ -781,13 +805,13 @@ fn cmd_create_file(args: CreateFileArgs) {
781 }; 805 };
782 apply(&mut fs, &new_op).unwrap(); 806 apply(&mut fs, &new_op).unwrap();
783 ops.push(new_op); 807 ops.push(new_op);
784 write_log_file(&ops); 808 common_write_log_file(&args.common, &ops);
785} 809}
786 810
787fn cmd_create_dir(args: CreateDirArgs) { 811fn cmd_create_dir(args: CreateDirArgs) {
788 let _lock = write_lock(); 812 let _lock = common_write_lock(&args.common);
789 let mut fs = Fs::default(); 813 let mut fs = Fs::default();
790 let mut ops = read_log_file(); 814 let mut ops = common_read_log_file(&args.common);
791 ops.iter().for_each(|op| apply(&mut fs, op).unwrap()); 815 ops.iter().for_each(|op| apply(&mut fs, op).unwrap());
792 816
793 let timestamp = args.timestamp.unwrap_or_else(get_timestamp); 817 let timestamp = args.timestamp.unwrap_or_else(get_timestamp);
@@ -803,13 +827,13 @@ fn cmd_create_dir(args: CreateDirArgs) {
803 }; 827 };
804 apply(&mut fs, &new_op).unwrap(); 828 apply(&mut fs, &new_op).unwrap();
805 ops.push(new_op); 829 ops.push(new_op);
806 write_log_file(&ops); 830 common_write_log_file(&args.common, &ops);
807} 831}
808 832
809fn cmd_remove(args: RemoveArgs) { 833fn cmd_remove(args: RemoveArgs) {
810 let _lock = write_lock(); 834 let _lock = common_write_lock(&args.common);
811 let mut fs = Fs::default(); 835 let mut fs = Fs::default();
812 let mut ops = read_log_file(); 836 let mut ops = common_read_log_file(&args.common);
813 ops.iter().for_each(|op| apply(&mut fs, op).unwrap()); 837 ops.iter().for_each(|op| apply(&mut fs, op).unwrap());
814 838
815 let timestamp = args.timestamp.unwrap_or_else(get_timestamp); 839 let timestamp = args.timestamp.unwrap_or_else(get_timestamp);
@@ -825,13 +849,13 @@ fn cmd_remove(args: RemoveArgs) {
825 }; 849 };
826 apply(&mut fs, &new_op).unwrap(); 850 apply(&mut fs, &new_op).unwrap();
827 ops.push(new_op); 851 ops.push(new_op);
828 write_log_file(&ops); 852 common_write_log_file(&args.common, &ops);
829} 853}
830 854
831fn cmd_rename(args: RenameArgs) { 855fn cmd_rename(args: RenameArgs) {
832 let _lock = write_lock(); 856 let _lock = common_write_lock(&args.common);
833 let mut fs = Fs::default(); 857 let mut fs = Fs::default();
834 let mut ops = read_log_file(); 858 let mut ops = common_read_log_file(&args.common);
835 ops.iter().for_each(|op| apply(&mut fs, op).unwrap()); 859 ops.iter().for_each(|op| apply(&mut fs, op).unwrap());
836 860
837 let timestamp = args.timestamp.unwrap_or_else(get_timestamp); 861 let timestamp = args.timestamp.unwrap_or_else(get_timestamp);
@@ -851,7 +875,7 @@ fn cmd_rename(args: RenameArgs) {
851 875
852 apply(&mut fs, &new_op).unwrap(); 876 apply(&mut fs, &new_op).unwrap();
853 ops.push(new_op); 877 ops.push(new_op);
854 write_log_file(&ops); 878 common_write_log_file(&args.common, &ops);
855} 879}
856 880
857type FsNodeWriter<'a> = std::io::BufWriter<std::io::StdoutLock<'a>>; 881type FsNodeWriter<'a> = std::io::BufWriter<std::io::StdoutLock<'a>>;
@@ -860,7 +884,7 @@ fn cmd_ls(args: LsArgs) {
860 let stdout = std::io::stdout().lock(); 884 let stdout = std::io::stdout().lock();
861 let mut writer = BufWriter::new(stdout); 885 let mut writer = BufWriter::new(stdout);
862 let mut fs = Fs::default(); 886 let mut fs = Fs::default();
863 let ops = read_log_file(); 887 let ops = common_read_log_file(&args.common);
864 ops.iter().for_each(|op| apply(&mut fs, op).unwrap()); 888 ops.iter().for_each(|op| apply(&mut fs, op).unwrap());
865 let node_id = match args.path { 889 let node_id = match args.path {
866 Some(path) => find_node(&fs, &path), 890 Some(path) => find_node(&fs, &path),
@@ -941,9 +965,9 @@ impl<T> Queue<T> {
941} 965}
942 966
943fn cmd_import(args: ImportArgs) { 967fn cmd_import(args: ImportArgs) {
944 let _lock = write_lock(); 968 let _lock = common_write_lock(&args.common);
945 969
946 let mut ops = read_log_file(); 970 let mut ops = common_read_log_file(&args.common);
947 971
948 let store = BlobStore::new("blobs"); 972 let store = BlobStore::new("blobs");
949 let timestamp = args.timestamp.unwrap_or_else(get_timestamp); 973 let timestamp = args.timestamp.unwrap_or_else(get_timestamp);
@@ -993,7 +1017,7 @@ fn cmd_import(args: ImportArgs) {
993 ops.extend(task_ops); 1017 ops.extend(task_ops);
994 } 1018 }
995 ops.iter().for_each(|op| apply(&mut fs, op).unwrap()); 1019 ops.iter().for_each(|op| apply(&mut fs, op).unwrap());
996 write_log_file(&ops); 1020 common_write_log_file(&args.common, &ops);
997} 1021}
998 1022
999fn collect_all_file_paths(root: &Path) -> Vec<PathBuf> { 1023fn collect_all_file_paths(root: &Path) -> Vec<PathBuf> {
@@ -1013,10 +1037,23 @@ fn collect_all_file_paths(root: &Path) -> Vec<PathBuf> {
1013 files 1037 files
1014} 1038}
1015 1039
1016fn read_log_file() -> Vec<Operation> { 1040fn common_create_blob_store(common: &CliCommon) -> BlobStore {
1041 BlobStore::new(common.drive.join("blobs"))
1042}
1043
1044fn common_log_file_path(common: &CliCommon) -> PathBuf {
1045 common.drive.join("log.txt")
1046}
1047
1048fn common_log_temp_file_path(common: &CliCommon) -> PathBuf {
1049 common.drive.join("log.txt.tmp")
1050}
1051
1052fn common_read_log_file(common: &CliCommon) -> Vec<Operation> {
1053 let log_file_path = common_log_file_path(common);
1017 let mut operations = Vec::default(); 1054 let mut operations = Vec::default();
1018 if std::fs::exists("log.txt").unwrap() { 1055 if std::fs::exists(&log_file_path).unwrap() {
1019 let contents = std::fs::read_to_string("log.txt").unwrap(); 1056 let contents = std::fs::read_to_string(&log_file_path).unwrap();
1020 for line in contents.lines() { 1057 for line in contents.lines() {
1021 let operation = line.parse().unwrap(); 1058 let operation = line.parse().unwrap();
1022 operations.push(operation); 1059 operations.push(operation);
@@ -1025,13 +1062,15 @@ fn read_log_file() -> Vec<Operation> {
1025 operations 1062 operations
1026} 1063}
1027 1064
1028fn write_log_file(ops: &[Operation]) { 1065fn common_write_log_file(common: &CliCommon, ops: &[Operation]) {
1066 let log_file_path = common_log_file_path(common);
1067 let log_temp_file_path = common_log_temp_file_path(common);
1029 { 1068 {
1030 let file = File::options() 1069 let file = File::options()
1031 .create(true) 1070 .create(true)
1032 .write(true) 1071 .write(true)
1033 .truncate(true) 1072 .truncate(true)
1034 .open("log.txt.tmp") 1073 .open(&log_temp_file_path)
1035 .unwrap(); 1074 .unwrap();
1036 let mut writer = BufWriter::new(file); 1075 let mut writer = BufWriter::new(file);
1037 for op in ops { 1076 for op in ops {
@@ -1039,7 +1078,22 @@ fn write_log_file(ops: &[Operation]) {
1039 } 1078 }
1040 writer.flush().unwrap(); 1079 writer.flush().unwrap();
1041 } 1080 }
1042 std::fs::rename("log.txt.tmp", "log.txt").unwrap(); 1081 std::fs::rename(&log_temp_file_path, &log_file_path).unwrap();
1082}
1083
1084fn common_write_lock_path(common: &CliCommon) -> PathBuf {
1085 common.drive.join("write.lock")
1086}
1087
1088fn common_write_lock(common: &CliCommon) -> File {
1089 let lock_path = common_write_lock_path(common);
1090 let file = std::fs::OpenOptions::new()
1091 .write(true)
1092 .create(true)
1093 .open(lock_path)
1094 .unwrap();
1095 file.lock().unwrap();
1096 file
1043} 1097}
1044 1098
1045fn get_timestamp() -> u64 { 1099fn get_timestamp() -> u64 {
@@ -1055,13 +1109,3 @@ fn get_next_revision(ops: &[Operation]) -> u64 {
1055 None => 0, 1109 None => 0,
1056 } 1110 }
1057} 1111}
1058
1059fn write_lock() -> File {
1060 let file = std::fs::OpenOptions::new()
1061 .write(true)
1062 .create(true)
1063 .open("write.lock")
1064 .unwrap();
1065 file.lock().unwrap();
1066 file
1067}