From ecdbc0b100cc50adffb1262ab485837d5dd2f709 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Tue, 13 Apr 2021 10:46:37 +0300 Subject: feat: support Python projects --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + bumper.md | 30 ++++++++++++++++++++++++++---- src/errors.rs | 6 ++++++ src/lib.rs | 1 + src/project.rs | 7 +++++++ src/python.rs | 45 +++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 src/python.rs 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", @@ -515,6 +516,12 @@ dependencies = [ "url", ] +[[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" 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 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, +} + +impl Python { + pub fn new(dirname: &Path) -> Result { + 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 { + glob(&dirname.join("*/version.py").display().to_string()) + .expect("glob pattern error") + .filter(|x| x.is_ok()) + .map(|x| x.unwrap()) + .collect() +} -- cgit v1.2.1 From 297521aab3d48f12b09d1b3071c1e13ed7cafdb4 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Tue, 13 Apr 2021 11:37:09 +0300 Subject: refactor: split scenario for Rust+Debian to separate scenarios --- bumper.md | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/bumper.md b/bumper.md index 67979ab..1082997 100644 --- a/bumper.md +++ b/bumper.md @@ -85,10 +85,9 @@ for a Rust project. ~~~scenario given an installed Bumper -given file foo/src/main.rs from main.rs given file foo/Cargo.toml from Cargo.toml -given file foo/Cargo.lock from Cargo.lock -given file foo/debian/changelog from changelog +given file foo/Cargo.lock from empty +given file foo/src/main.rs 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 @@ -96,14 +95,9 @@ then in foo, git tag v105.12765.42 is a signed tag then file foo/Cargo.toml matches regex /version\s*=\s*"105\.12765\.42"/ then file foo/Cargo.lock is newer than foo/Cargo.toml then file foo/Cargo.lock is committed to git -then file foo/debian/changelog matches regex / \(0\.1\.0-1\) / -then file foo/debian/changelog matches regex / \(105\.12765\.42-1\) / ~~~ -~~~{#main.rs .file .rust} -fn main() { - println!("Hello, world!"); -} +~~~{#empty .file} ~~~ ~~~{#Cargo.toml .file .ini} @@ -117,8 +111,22 @@ edition = "2018" anyhow = "1" ~~~ -~~~{#Cargo.lock .file .ini} +## Sets version for project with Debian packaging + +This scenario verifies that Bumper creates a git tag to mark a release +for a project with Debian packaging. + +~~~scenario +given an installed Bumper +given file foo/debian/changelog from changelog +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/debian/changelog matches regex / \(0\.1\.0-1\) / +then file foo/debian/changelog matches regex / \(105\.12765\.42-1\) / ~~~ + ~~~{#changelog .file} dummy (0.1.0-1) unstable; urgency=low @@ -143,10 +151,6 @@ 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} -~~~ - - --- title: bumper – set version number for a project -- cgit v1.2.1