Skip to content

Commit 55c6b19

Browse files
committed
feat(projects): handle syncing projects according to feature file
1 parent 02ecae3 commit 55c6b19

File tree

2 files changed

+93
-2
lines changed

2 files changed

+93
-2
lines changed

src/commands/projects.rs

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
use super::types::FeatureConfig;
12
use crate::cli::ProgramInfo;
23
use crate::commands::types::{AddProject, ProjectCommand, ProjectInfo, SyncProjectBranch};
34
use crate::config;
45
use crate::git;
6+
use std::fs;
7+
use std::io::prelude::*;
58
use std::io::{stdin, stdout, Write};
6-
use std::path::PathBuf;
9+
use std::path::{Path, PathBuf};
710
use std::process::exit;
811

912
fn projects_help() {
@@ -29,6 +32,58 @@ Examples:
2932
");
3033
}
3134

35+
pub fn sync_feature(program: ProgramInfo) {
36+
let args = match program.args {
37+
None => {
38+
println!("You must specify a sub-command");
39+
exit(1);
40+
}
41+
Some(args) => args,
42+
};
43+
44+
let feature_file = match args.first() {
45+
Some(arg) => arg,
46+
None => {
47+
println!("You must specify a sub-command");
48+
exit(1);
49+
}
50+
};
51+
52+
let file_path = Path::new(&feature_file);
53+
54+
if !file_path.exists() {
55+
println!(
56+
"Please enter a valid path, since this path [{}] does not exist",
57+
feature_file
58+
);
59+
exit(1);
60+
}
61+
62+
let feature_config = read_feature_file(file_path);
63+
let mut config = config::get();
64+
let project = match config.get_project(&feature_config.project) {
65+
Some(project) => project,
66+
None => {
67+
println!("Cannot find project with name: [{}] please make sure that you added it (run 'switcher config -d' to make sure)", feature_config.project);
68+
exit(1);
69+
}
70+
};
71+
72+
for feature in feature_config.feature_specs {
73+
let repository = match project.get_repository_by_name(&feature.repository) {
74+
Some(repository) => repository,
75+
None => {
76+
println!(
77+
"Cannot find repository with this name [{}]",
78+
feature.repository
79+
);
80+
exit(1);
81+
}
82+
};
83+
git::sync_repository_to_branch(repository, &feature.branch);
84+
}
85+
}
86+
3287
pub fn check(program: ProgramInfo) {
3388
let args = match program.args {
3489
None => {
@@ -181,3 +236,21 @@ fn remove(project_info: ProjectInfo) {
181236
config.projects.remove(project_index);
182237
config.save();
183238
}
239+
240+
fn read_feature_file(path: &Path) -> FeatureConfig {
241+
let mut file = match fs::File::open(path) {
242+
Err(err) => panic!("Error reading config file [{}]", err),
243+
Ok(file) => file,
244+
};
245+
246+
let mut content = String::new();
247+
248+
file.read_to_string(&mut content)
249+
.expect("Error reading config file content");
250+
251+
// This will fail here if serde can't serialize config file content to Project
252+
match serde_json::from_str::<FeatureConfig>(&content) {
253+
Err(err) => panic!("Error serializing config file: [{}]", err),
254+
Ok(data) => data,
255+
}
256+
}

src/config.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use crate::cli::ProgramInfo;
22
use crate::git::git_current_branch;
3+
use colored::*;
34
use serde::{Deserialize, Serialize};
45
use std::fs;
56
use std::io::prelude::*;
67
use std::path::Path;
78
use std::path::PathBuf;
8-
use colored::*;
9+
use std::process::exit;
910

1011
const CONFIG_INIT: &str = r#"
1112
{
@@ -28,6 +29,23 @@ impl Project {
2829
repositories: Vec::new(),
2930
}
3031
}
32+
33+
pub fn get_repository_by_name(&self, name: &str) -> Option<PathBuf> {
34+
for repository in &self.repositories {
35+
let repo = match repository.to_str() {
36+
Some(repo) => repo,
37+
None => {
38+
println!("Error converting path to string");
39+
exit(1);
40+
}
41+
};
42+
43+
if repo.contains(name) {
44+
return Some(repository.to_path_buf());
45+
}
46+
}
47+
None
48+
}
3149
}
3250

3351
#[derive(Serialize, Deserialize, Debug)]

0 commit comments

Comments
 (0)