List of commits:
Subject Hash Author Date (UTC)
Implement `run` and `build` commands. 14e9e25b6a06f587c1a50829e72c829ae59a87c2 Jan Allersma 2018-12-10 20:57:08
Implement non-recursive dependency check. 5ffd40604755d1c2dde9353c74f06a006deea33c Jan Allersma 2018-12-07 20:50:42
Restructure project. c2d98caf7897e87284fb2891e1d4b92d14cf37e1 Jan Allersma 2018-12-06 16:20:46
Initial commit. 4c152d55edc20ac55fd749a2b32b204134a664e3 Jan Allersma 2018-12-05 17:03:08
Commit 14e9e25b6a06f587c1a50829e72c829ae59a87c2 - Implement `run` and `build` commands.
* Replace all std::io::Result<T> with std::result::Result<T, String>.
Author: Jan Allersma
Author date (UTC): 2018-12-10 20:57
Committer name: Jan Allersma
Committer date (UTC): 2018-12-10 20:57
Parent(s): 5ffd40604755d1c2dde9353c74f06a006deea33c
Signing key:
Tree: 1e0c8e8a2f1f9cdfac22772d0a537ced6b84ceed
File Lines added Lines deleted
src/backend/build.rs 57 4
src/backend/check.rs 31 24
src/backend/config.rs 13 5
src/backend/fetch.rs 6 2
src/backend/filesystem.rs 2 2
src/backend/project.rs 60 7
src/main.rs 6 0
File src/backend/build.rs changed (mode: 100644) (index d75299f..db2c6a7)
1 use std::io::Result;
1 extern crate serde_json;
2 2
3 pub fn build(config: String) -> Result<String> {
4 println!("Building project..");
3 use std::result::Result;
4 use std::path::PathBuf;
5 use std::env;
6
7 pub fn build(config_file: PathBuf) -> Result<String, String> {
8 let config;
9
10 match super::config::get_json(config_file) {
11 Ok(result) => config = result,
12 Err(e) => return Err(e)
13 }
5 14
6 match super::check::dep(config) {
15 match super::check::dep(config.clone()) {
16 Ok(result) => println!("{}", result),
17 Err(e) => return Err(e)
18 }
19
20 match build_module(config) {
7 21 Ok(result) => println!("{}", result), Ok(result) => println!("{}", result),
8 22 Err(e) => return Err(e) Err(e) => return Err(e)
9 23 } }
10 24
11 25 Ok(String::from("Build succeeded!")) Ok(String::from("Build succeeded!"))
12 26 } }
27
28 #[cfg(target_os="linux")]
29 fn build_module(config: serde_json::Value) -> Result<String, String> {
30 println!("Building project..");
31
32 let build_cmd = &config["build"]["linux"];
33
34 if !build_cmd.is_string() {
35 return Err(String::from("beheer.json: 'build->linux' should be a string."));
36 }
37
38 super::fetch::fetch(env::current_dir().unwrap(), String::from(build_cmd.as_str().unwrap()))
39 }
40
41 #[cfg(target_os="macos")]
42 fn build_module(config: serde_json::Value) -> Result<String, String> {
43 println!("Building project..");
44
45 let build_cmd = &config["build"]["os-x"];
46
47 if !build_cmd.is_string() {
48 return Err(String::from("beheer.json: 'build->os-x' should be a string."));
49 }
50
51 super::fetch::fetch(env::get_current_dir().unwrap(), String::from(build_cmd.as_str().unwrap()))
52 }
53
54 #[cfg(target_os="windows")]
55 fn build_module(config: serde_json::Value) -> Result<String, String> {
56 println!("Building project..");
57
58 let build_cmd = &config["build"]["windows"];
59
60 if !build_cmd.is_string() {
61 return Err(String::from("beheer.json: 'build->windows' should be a string."));
62 }
63
64 super::fetch::fetch(env::get_current_dir().unwrap(), String::from(build_cmd.as_str().unwrap()))
65 }
File src/backend/check.rs changed (mode: 100644) (index 08d2bca..260e822)
1 1 extern crate serde_json; extern crate serde_json;
2 2
3 use std::io::{Result, Error, ErrorKind};
3 use std::result::Result;
4 4
5 pub fn dep(config: String) -> Result<String> {
5 pub fn json(config: String) -> Result<serde_json::Value, String> {
6 6 let config_json: serde_json::Value; let config_json: serde_json::Value;
7 7
8 println!("Checking dependencies..");
8 println!("Reading module configuration..");
9 9
10 10 match serde_json::from_str(&config) { match serde_json::from_str(&config) {
11 11 Ok(json) => config_json = json, Ok(json) => config_json = json,
 
... ... pub fn dep(config: String) -> Result<String> {
19 19 match e.classify() { match e.classify() {
20 20 serde_json::error::Category::Io => { serde_json::error::Category::Io => {
21 21 error.push_str("Weird error...."); error.push_str("Weird error....");
22 return Err(Error::new(ErrorKind::Other, error));
22 return Err(error);
23 23 }, },
24 24 serde_json::error::Category::Syntax => { serde_json::error::Category::Syntax => {
25 25 error.push_str("Syntax error in 'beheer.json'"); error.push_str("Syntax error in 'beheer.json'");
26 return Err(Error::new(ErrorKind::InvalidInput, error));
26 return Err(error);
27 27 }, },
28 28 serde_json::error::Category::Data => { serde_json::error::Category::Data => {
29 29 error.push_str("Semantic error in 'beheer.json'"); error.push_str("Semantic error in 'beheer.json'");
30 return Err(Error::new(ErrorKind::InvalidData, error));
30 return Err(error);
31 31 }, },
32 32 serde_json::error::Category::Eof => { serde_json::error::Category::Eof => {
33 33 error.push_str("Unexpected end-of-file in 'beheer.json'"); error.push_str("Unexpected end-of-file in 'beheer.json'");
34 return Err(Error::new(ErrorKind::UnexpectedEof, error));
34 return Err(error);
35 35 } }
36 36 } }
37 37 } }
38 38 } }
39 39
40 config_check(config_json)
40 Ok(config_json)
41 41 } }
42 42
43 43 #[cfg(target_os="linux")] #[cfg(target_os="linux")]
44 fn config_check(config: serde_json::Value) -> Result<String> {
44 pub fn dep(config: serde_json::Value) -> Result<String, String> {
45 println!("Checking dependencies..");
46
45 47 match config["deps"]["linux"] { match config["deps"]["linux"] {
46 48 json!(null) => return Ok(String::from("No dependencies found!")), json!(null) => return Ok(String::from("No dependencies found!")),
47 49 ref deps => { ref deps => {
48 50 if !deps.is_object() { if !deps.is_object() {
49 return Err(Error::new(ErrorKind::InvalidData, "beheer.json: 'deps->linux' should be an object."));
51 return Err(String::from("beheer.json: 'deps->linux' should be an object."));
50 52 } }
51 53
52 54 for dep in deps.as_object().unwrap().iter() { for dep in deps.as_object().unwrap().iter() {
53 55
54 56 if !dep.1.is_string() { if !dep.1.is_string() {
55 return Err(Error::new(ErrorKind::InvalidData, "beheer.json: all deps should be strings!"));
57 return Err(String::from("beheer.json: all deps should be strings!"));
56 58 } }
57 59
58 60 println!("Checking for {}..\n\t{}", dep.0, dep.1); println!("Checking for {}..\n\t{}", dep.0, dep.1);
 
... ... fn config_check(config: serde_json::Value) -> Result<String> {
68 70 } }
69 71
70 72 #[cfg(target_os="macos")] #[cfg(target_os="macos")]
71 fn config_check(config: serde_json::Value) -> Result<String> {
73 pub fn dep(config: serde_json::Value) -> Result<String, String> {
74 println!("Checking dependencies..");
75
72 76 match config["deps"]["os-x"] { match config["deps"]["os-x"] {
73 77 json!(null) => return Ok(String::from("No dependencies found!")), json!(null) => return Ok(String::from("No dependencies found!")),
74 78 ref sys_deps => { ref sys_deps => {
75 79 if !sys_deps.is_object() { if !sys_deps.is_object() {
76 return Err(Error::new(ErrorKind::InvalidData, "beheer.json: 'deps->os-x' should be an object."));
80 return Err(String::from("beheer.json: 'deps->os-x' should be an object."));
77 81 } }
78 82
79 83 for dep in deps.as_object().unwrap().iter() { for dep in deps.as_object().unwrap().iter() {
80 84
81 85 if !dep.1.is_string() { if !dep.1.is_string() {
82 return Err(Error::new(ErrorKind::InvalidData, "beheer.json: all deps should be strings!"));
86 return Err(String::from("beheer.json: all deps should be strings!"));
83 87 } }
84 88
85 89 println!("Checking for {}..\n\t{}", dep.0, dep.1); println!("Checking for {}..\n\t{}", dep.0, dep.1);
 
... ... fn config_check(config: serde_json::Value) -> Result<String> {
94 98 } }
95 99
96 100 #[cfg(target_os="windows")] #[cfg(target_os="windows")]
97 fn config_check(config: serde_json::Value) -> Result<String> {
101 pub fn dep(config: serde_json::Value) -> Result<String, String> {
102 println!("Checking dependencies..");
103
98 104 match config["deps"]["windows"] { match config["deps"]["windows"] {
99 105 json!(null) => return Ok(String::from("No dependencies found!")), json!(null) => return Ok(String::from("No dependencies found!")),
100 106 ref sys_deps => { ref sys_deps => {
101 107 if !sys_deps.is_object() { if !sys_deps.is_object() {
102 return Err(Error::new(ErrorKind::InvalidData, "beheer.json: 'deps->windows' should be an object."));
108 return Err(String::from("beheer.json: 'deps->windows' should be an object."));
103 109 } }
104 110
105 111 for dep in deps.as_object().unwrap().iter() { for dep in deps.as_object().unwrap().iter() {
106 112 if !dep.1.is_string() { if !dep.1.is_string() {
107 return Err(Error::new(ErrorKind::InvalidData, "beheer.json: all deps should be strings!"));
113 return Err(String::from("beheer.json: all deps should be strings!"));
108 114 } }
109 115
110 116 println!("Checking for {}..\n\t{}", dep.0, dep.1); println!("Checking for {}..\n\t{}", dep.0, dep.1);
111 117
112 if dir_check(dep.0.to_string(), String::from(dep.1.as_str().unwrap())) == Err(e) {
113 return Err(e);
118 match dir_check(dep.0.to_string(), String::from(dep.1.as_str().unwrap())) {
119 Ok(output) => println!("{}", output),
120 Err(e) => return Err(e)
114 121 } }
115 122 } }
116 123 } }
 
... ... fn config_check(config: serde_json::Value) -> Result<String> {
118 125 Ok(String::from("Dependencies OK!")) Ok(String::from("Dependencies OK!"))
119 126 } }
120 127
121 fn dir_check(dependency: String, command: String) -> Result<()> {
128 fn dir_check(dependency: String, command: String) -> Result<String, String> {
122 129 let dir = super::filesystem::get_dep_dir(); let dir = super::filesystem::get_dep_dir();
123 130
124 131 match dir { match dir {
125 132 Ok(mut dep_dir) => { Ok(mut dep_dir) => {
126 133 dep_dir.push(dependency); dep_dir.push(dependency);
127 if !dep_dir.is_dir() {
134 if !dep_dir.exists() {
128 135 dep_dir.pop(); dep_dir.pop();
129 super::fetch::fetch(dep_dir, command);
136 return super::fetch::fetch(dep_dir, command);
130 137 } }
131 Ok(())
138 Ok(String::from("Dependency found."))
132 139 }, },
133 Err(e) => Err(e)
140 Err(e) => Err(e.to_string())
134 141 } }
135 142 } }
File src/backend/config.rs changed (mode: 100644) (index 28e0742..20ae5d1)
1 1 extern crate serde_json; extern crate serde_json;
2 2
3 use std::io::{Result, Error, ErrorKind, Write, Read};
3 use std::io::{Error, ErrorKind, Write, Read};
4 4 use std::fs::File; use std::fs::File;
5 5 use std::path::PathBuf; use std::path::PathBuf;
6 use std::result::Result;
6 7
7 pub fn create(mut path: PathBuf) -> Result<()> {
8 pub fn create(mut path: PathBuf) -> Result<(), Error> {
8 9 let content = json!({ let content = json!({
9 10 "project-name": path.file_name().unwrap().to_str().unwrap(), "project-name": path.file_name().unwrap().to_str().unwrap(),
10 11 "version": 0.1, "version": 0.1,
 
... ... pub fn create(mut path: PathBuf) -> Result<()> {
37 38 Ok(()) Ok(())
38 39 } }
39 40
40 pub fn read(mut path: PathBuf) -> Result<String> {
41 fn read(mut path: PathBuf) -> Result<String, String> {
41 42 let mut config = String::new(); let mut config = String::new();
42 43
43 44 path.push("beheer.json"); path.push("beheer.json");
44 45
45 46 match File::open(path.to_str().unwrap()) { match File::open(path.to_str().unwrap()) {
46 47 Ok(mut file) => { Ok(mut file) => {
47 file.read_to_string(&mut config)?;
48 file.read_to_string(&mut config).unwrap();
48 49 }, },
49 Err(e) => return Err(e)
50 Err(e) => return Err(e.to_string())
50 51 } }
51 52
52 53 Ok(config) Ok(config)
53 54 } }
55
56 pub fn get_json(path: PathBuf) -> Result<serde_json::Value, String> {
57 match read(path) {
58 Ok(config) => super::check::json(config),
59 Err(e) => Err(e.to_string())
60 }
61 }
File src/backend/fetch.rs changed (mode: 100644) (index 613e432..2ef99f1)
1 1 use std::process::Command; use std::process::Command;
2 2 use std::path; use std::path;
3 use std::result::Result;
3 4
4 pub fn fetch(dep: path::PathBuf, command: String) {
5 pub fn fetch(dep: path::PathBuf, command: String) -> Result<String, String> {
5 6 let mut args: Vec<&str> = command.split(' ').collect(); let mut args: Vec<&str> = command.split(' ').collect();
6 7 let command = args.remove(0); let command = args.remove(0);
7 8 let out = Command::new(command).current_dir(dep).args(args).output().expect(""); let out = Command::new(command).current_dir(dep).args(args).output().expect("");
8 9
9 println!("{:#?}", out.stderr);
10 match out.status.success() {
11 true => Ok(String::from_utf8_lossy(&out.stdout).to_string()),
12 false => Err(String::from_utf8_lossy(&out.stderr).to_string())
13 }
10 14 } }
File src/backend/filesystem.rs changed (mode: 100644) (index 71578e5..7b57573)
... ... pub fn get_dep_dir() -> Result<path::PathBuf> {
43 43 Some(mut path) => { Some(mut path) => {
44 44 path.push("dep"); path.push("dep");
45 45 if !path.is_dir() { if !path.is_dir() {
46 println!("No dep folder found. Creating folder..");
46 println!("\tNo dep folder found. Creating folder..");
47 47 match fs::create_dir(path.clone()) { match fs::create_dir(path.clone()) {
48 Ok(_) => println!("Created dir {}.", path.clone().to_str().unwrap()),
48 Ok(_) => println!("\tCreated dir {}.", path.clone().to_str().unwrap()),
49 49 Err(e) => return Err(e) Err(e) => return Err(e)
50 50 } }
51 51 } }
File src/backend/project.rs changed (mode: 100644) (index 38495ac..8640ea4)
1 1 use std::env; use std::env;
2 use std::io::{Result, Error, ErrorKind};
2 use std::result::Result;
3 use std::process::{Command, Stdio};
3 4
4 5 pub fn init(args: &mut env::Args) { pub fn init(args: &mut env::Args) {
5 6 let mut directory = env::current_dir().unwrap(); let mut directory = env::current_dir().unwrap();
 
... ... pub fn init(args: &mut env::Args) {
14 15 } }
15 16 } }
16 17
17 pub fn build() -> Result<String> {
18 pub fn build() -> Result<String, String> {
18 19 match super::filesystem::get_project_root() { match super::filesystem::get_project_root() {
19 Some(dir) => {
20 match super::config::read(dir) {
21 Ok(configfile) => return super::build::build(configfile),
22 Err(e) => Err(e)
20 Some(dir) => super::build::build(dir),
21 None => Err(String::from("not in a project (sub)directory."))
22 }
23 }
24
25 pub fn run(args: &mut env::Args) -> Result<String, String> {
26 let output_dir;
27 let mut args = String::new();
28
29 println!("Building project..");
30
31 match build() {
32 Ok(output) => println!("{}", output),
33 Err(e) => return Err(e)
34 }
35
36 match super::filesystem::get_project_root() {
37 Some(dir) => output_dir = dir,
38 None => return Err(String::from("not in a project (sub)directory."))
39 }
40
41 match super::config::get_json(output_dir) {
42 Ok(config) => {
43 if cfg!(target_os = "linux") {
44 match config["run"]["linux"].as_str() {
45 Some(string) => args = String::from(string),
46 None => return Err(String::from("beheer.json: 'run->linux' should be a string."))
47 }
48 }
49 if cfg!(target_os = "macos") {
50 match config["run"]["os-x"].as_str() {
51 Some(string) => args = String::from(string),
52 None => return Err(String::from("beheer.json: 'run->os-x' should be a string."))
53 }
54 }
55 if cfg!(target_os = "windows") {
56 match config["run"]["windows"].as_str() {
57 Some(string) => args = String::from(string),
58 None => return Err(String::from("beheer.json: 'run->windows' should be a string."))
59 }
23 60 } }
24 61 }, },
25 None => Err(Error::new(ErrorKind::NotFound, "not in a project (sub)directory."))
62 Err(e) => return Err(e)
63 }
64
65 println!("Running project..");
66
67 let mut arguments: Vec<&str> = args.split(' ').collect();
68 let command = arguments.remove(0);
69 let out = Command::new(command)
70 .args(arguments)
71 .stdin(Stdio::inherit())
72 .stdout(Stdio::inherit())
73 .output()
74 .expect("");
75
76 match out.status.success() {
77 true => Ok(String::from_utf8_lossy(&out.stdout).to_string()),
78 false => Err(String::from_utf8_lossy(&out.stderr).to_string())
26 79 } }
27 80 } }
28 81
File src/main.rs changed (mode: 100644) (index 103a172..fa8f0d6)
... ... fn parse() {
32 32 Err(e) => println!("Build failed: {}", e) Err(e) => println!("Build failed: {}", e)
33 33 } }
34 34 } }
35 else if &argument == "run" {
36 match backend::project::run(&mut argv) {
37 Ok(_) => {},
38 Err(e) => println!("Running project failed: {}", e)
39 }
40 }
35 41 }, },
36 42 None => backend::project::help() None => backend::project::help()
37 43 } }
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/kapstok/NHL-Beheer

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/kapstok/NHL-Beheer

Clone this repository using git:
git clone git://git.rocketgit.com/user/kapstok/NHL-Beheer

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main