summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock7
-rw-r--r--Cargo.toml1
-rw-r--r--bumper.md30
-rw-r--r--src/errors.rs6
-rw-r--r--src/lib.rs1
-rw-r--r--src/project.rs7
-rw-r--r--src/python.rs45
7 files changed, 93 insertions, 4 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 82f8ba4..d3c7ea2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -123,6 +123,7 @@ version = "0.5.0"
dependencies = [
"anyhow",
"cargo-edit",
+ "glob",
"log",
"pandoc",
"pandoc_ast",
@@ -516,6 +517,12 @@ dependencies = [
]
[[package]]
+name = "glob"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
+
+[[package]]
name = "h2"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 1dfd07c..1b13af0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,6 +13,7 @@ repository = "https://gitlab.com/larswirzenius/bumper"
[dependencies]
anyhow = "1"
cargo-edit = "0.7"
+glob = "0.3"
log = "0.4"
pandoc = "0.8.4"
pandoc_ast = "0.8.0"
diff --git a/bumper.md b/bumper.md
index dafd216..67979ab 100644
--- a/bumper.md
+++ b/bumper.md
@@ -41,6 +41,10 @@ tree, to keep things simple.
package's version number. Bumper assumes the file is otherwise up to
date for the release, and sets the version to `X.Y.Z-1`.
+* Python projects have a `setup.py` file at the root of the source
+ tree, and at least one `version.py` in a sub-directory where the
+ version number is stored in the `__version__` variable.
+
* Releases are marked with signed, annotated git tags named after the
release version with a `v` prefix.
@@ -74,11 +78,10 @@ Some random text file Bumper knows nothing about.
~~~
-## Creates a release tag
+## Sets version for Rust project
-This scenario verifies that Bumper creates a git tag to mark a
-release. For this to work, Bumper needs to recognize the type of
-project. We use a Rust project for simplicity.
+This scenario verifies that Bumper creates a git tag to mark a release
+for a Rust project.
~~~scenario
given an installed Bumper
@@ -124,6 +127,25 @@ dummy (0.1.0-1) unstable; urgency=low
-- Lars Wirzenius <liw@liw.fi> Tue, 30 Mar 2021 08:33:35 +0300
~~~
+## Sets version for Python project
+
+This scenario verifies that Bumper creates a git tag to mark a
+release for a Python project.
+
+~~~scenario
+given an installed Bumper
+given file foo/setup.py from empty
+given file foo/lib/version.py from empty
+given all files in foo are committed to git
+when I run, in foo, bumper 105.12765.42
+then all changes in foo are committed
+then in foo, git tag v105.12765.42 is a signed tag
+then file foo/lib/version.py matches regex /__version__\s*=\s*"105\.12765\.42"/
+~~~
+
+~~~{#empty .file}
+~~~
+
---
diff --git a/src/errors.rs b/src/errors.rs
index bd09eba..97ed8d8 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -49,4 +49,10 @@ pub enum BumperError {
#[error("cargo failed in {0}: {1}")]
Cargo(PathBuf, String),
+
+ #[error("can't find any version.py files in Python project at {0}")]
+ NoVersionPy(PathBuf),
+
+ #[error("couldn't write Python version to {0}: {1}")]
+ PythonWrite(PathBuf, std::io::Error),
}
diff --git a/src/lib.rs b/src/lib.rs
index 51ddd5f..e0c0fca 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,4 +2,5 @@ pub mod debian;
pub mod errors;
pub mod git;
pub mod project;
+pub mod python;
pub mod rust;
diff --git a/src/project.rs b/src/project.rs
index 9f45363..e67fefc 100644
--- a/src/project.rs
+++ b/src/project.rs
@@ -1,11 +1,13 @@
use crate::debian::Debian;
use crate::errors::BumperError;
+use crate::python::Python;
use crate::rust::Rust;
use std::path::Path;
pub enum ProjectKind {
Rust(Rust),
Debian(Debian),
+ Python(Python),
}
impl ProjectKind {
@@ -21,6 +23,10 @@ impl ProjectKind {
kinds.push(ProjectKind::Debian(p));
}
+ if let Ok(p) = Python::new(dirname) {
+ kinds.push(ProjectKind::Python(p));
+ }
+
if kinds.is_empty() {
Err(BumperError::UnknownProjectKind(dirname.to_path_buf()))
} else {
@@ -32,6 +38,7 @@ impl ProjectKind {
match self {
Self::Rust(ref mut rust) => rust.set_version(version)?,
Self::Debian(ref mut debian) => debian.set_version(version)?,
+ Self::Python(ref mut python) => python.set_version(version)?,
}
Ok(())
}
diff --git a/src/python.rs b/src/python.rs
new file mode 100644
index 0000000..2b851f8
--- /dev/null
+++ b/src/python.rs
@@ -0,0 +1,45 @@
+use crate::errors::BumperError;
+use glob::glob;
+use log::{debug, info};
+use std::path::{Path, PathBuf};
+
+pub struct Python {
+ version_pys: Vec<PathBuf>,
+}
+
+impl Python {
+ pub fn new(dirname: &Path) -> Result<Self, BumperError> {
+ debug!("considering {} as a Python project", dirname.display());
+ let setup_py = dirname.join("setup.py");
+ if setup_py.exists() {
+ let files = find_version_py_files(dirname);
+ if files.is_empty() {
+ debug!("no version.py files in {}", dirname.display());
+ Err(BumperError::NoVersionPy(dirname.to_path_buf()))
+ } else {
+ info!("Looks like a Python project: {}", dirname.display());
+ Ok(Self { version_pys: files })
+ }
+ } else {
+ debug!("{} does not exist", setup_py.display());
+ Err(BumperError::UnknownProjectKind(dirname.to_path_buf()))
+ }
+ }
+
+ pub fn set_version(&mut self, version: &str) -> Result<(), BumperError> {
+ for filename in self.version_pys.iter() {
+ info!("writing Python version to {}", filename.display());
+ std::fs::write(filename, format!("__version__ = \"{}\"\n", version))
+ .map_err(|err| BumperError::PythonWrite(filename.to_path_buf(), err))?;
+ }
+ Ok(())
+ }
+}
+
+fn find_version_py_files(dirname: &Path) -> Vec<PathBuf> {
+ glob(&dirname.join("*/version.py").display().to_string())
+ .expect("glob pattern error")
+ .filter(|x| x.is_ok())
+ .map(|x| x.unwrap())
+ .collect()
+}