1use std::io;
2use std::process::Command;
3
4mod bump_level;
5pub use bump_level::{BumpLevel, BumpLevelError};
6
7mod toml;
8use toml::{TomlSemverExtensions, TomlError};
9
10mod derive_next_version;
11use derive_next_version::derive_next_version;
12
13extern crate semver;
14
15use semver::Version;
16pub use semver::SemVerError;
17
18pub enum CargoVersionError {
19 GitNotClean,
20 IoError(io::Error),
21 NoVersionFound,
22 SemVerError(semver::SemVerError),
23}
24
25impl From<TomlError> for CargoVersionError {
26 fn from(err: TomlError) -> CargoVersionError {
27 match err {
28 TomlError::NoVersionFound => CargoVersionError::NoVersionFound,
29 TomlError::IoError(err) => CargoVersionError::IoError(err),
30 TomlError::SemVerError(err) => CargoVersionError::SemVerError(err),
31 }
32 }
33}
34
35fn require_clean_git() -> Result<(), ()> {
36 Command::new("git")
37 .arg("status")
38 .arg("--porcelain=v1")
39 .arg("--untracked-files=no")
40 .output()
41 .map(|output| output.stdout.len() > 0)
42 .map(|dirty| if dirty { Err(()) } else { Ok(()) })
43 .expect("Failed to read git status")
44}
45
46pub fn create_version(level: BumpLevel) -> Result<(), CargoVersionError> {
47 try!(require_clean_git().map_err(|_| CargoVersionError::GitNotClean));
49
50 let current_version = try!(Version::read_from_toml("Cargo.toml"));
52
53 let next_version = derive_next_version(current_version, level);
55
56 try!(next_version.write_to_toml("Cargo.toml"));
58
59 Command::new("cargo")
61 .arg("generate-lockfile")
62 .spawn()
63 .expect("Failed to regenerate lockfile")
64 .wait()
65 .expect("Failed to regenerate lockfile");
66
67 Command::new("cargo")
69 .arg("build")
70 .arg("--release")
71 .spawn()
72 .expect("Failed to build package")
73 .wait()
74 .expect("Failed to build package");
75
76 Command::new("git")
78 .arg("add")
79 .arg("Cargo.toml")
80 .arg("Cargo.lock")
81 .spawn()
82 .expect("Failed to add files to the git staging area")
83 .wait()
84 .expect("Failed to add files to the git staging area");
85
86 Command::new("git")
88 .arg("commit")
89 .arg("-m")
90 .arg(format!("🚢 {}", next_version))
91 .spawn()
92 .expect("Failed to create a git commit")
93 .wait()
94 .expect("Failed to create a git commit");
95
96 Command::new("git")
98 .arg("tag")
99 .arg(format!("v{}", next_version))
100 .arg("-am")
101 .arg(format!("🚢 {}", next_version))
102 .spawn()
103 .expect("Failed to create a git tag")
104 .wait()
105 .expect("Failed to create a git tag");
106
107 Ok(())
108}