From d14bf14d4bb0a7fbbd5ea0b1ac42debbf4b249a4 Mon Sep 17 00:00:00 2001 From: Christine Dodrill Date: Sun, 31 May 2020 12:29:43 -0400 Subject: [PATCH] implement changelog parsing --- CHANGELOG.md | 41 ++++++++++++++++++++++++++ src/changelog.rs | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 1 + 3 files changed, 117 insertions(+) create mode 100644 CHANGELOG.md create mode 100644 src/changelog.rs diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ade8418 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,41 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Unreleased + +## 0.1.0 + +This is the first release of `gitea-release`! + +```console +$ gitea-release release --help +gitea-release-release 0.1.0 +Create a new tag and release on Gitea + +USAGE: + gitea-release release [FLAGS] [OPTIONS] --auth-user --owner --repo --server --token + +FLAGS: + --draft Draft release + -h, --help Prints help information + -p, --pre-release Pre-release (not suitable for production) + -V, --version Prints version information + +OPTIONS: + -a, --auth-user The gitea user to authenticate as [env: GITEA_AUTH_USER=cadey] + -c, --changelog Changelog file to read from to create the release description [default: + ./CHANGELOG.md] + -n, --name Release name + -o, --owner The owner of the gitea repo [env: GITEA_OWNER=] + -r, --repo The gitea repo to operate on [env: GITEA_REPO=] + -s, --server The gitea server to connect to [env: GITEA_SERVER=https://tulpa.dev] + --token The gitea token to authenticate with [env: GITEA_TOKEN=] +``` + +### ADDED + +- Basic functionality + diff --git a/src/changelog.rs b/src/changelog.rs new file mode 100644 index 0000000..2ff75c5 --- /dev/null +++ b/src/changelog.rs @@ -0,0 +1,75 @@ +use anyhow::Result; +use comrak::nodes::{AstNode, NodeValue}; +use comrak::{format_commonmark, parse_document, Arena, ComrakOptions}; +use std::cell::RefCell; +use std::fs::read_to_string; +use std::path::PathBuf; + +pub(crate) fn read(fname: PathBuf, tag: String) -> Result { + let data = read_to_string(fname)?; + let arena = Arena::new(); + let mut root = parse_document(&arena, &data, &ComrakOptions::default()); + + let collect = RefCell::new(false); + let buf = RefCell::new(Vec::::new()); + + iter_nodes(&mut root, &|node| { + let nd = node.data.borrow(); + + match nd.value { + NodeValue::Heading(ref hdr) => { + if hdr.level == 2 { + if *collect.borrow() { + collect.swap(&RefCell::new(false)); + } + + let found_tag = String::from_utf8(nd.content.clone())?; + + if found_tag == tag { + collect.swap(&RefCell::new(true)); + } + } else { + if *collect.borrow() { + let mut apd = buf.borrow_mut(); + let mut new_buf = Vec::::new(); + format_commonmark(&node, &ComrakOptions::default(), &mut new_buf)?; + apd.append(&mut new_buf); + } + } + Ok(()) + } + NodeValue::Item(_) => Ok(()), + _ => { + if *collect.borrow() { + let mut apd = buf.borrow_mut(); + let mut new_buf = Vec::::new(); + format_commonmark(&node, &ComrakOptions::default(), &mut new_buf)?; + apd.append(&mut new_buf); + } + + Ok(()) + } + } + })?; + + Ok(String::from_utf8(buf.into_inner())?) +} + +fn iter_nodes<'a, F>(node: &'a AstNode<'a>, f: &F) -> Result<()> +where + F: Fn(&'a AstNode<'a>) -> Result<()>, +{ + f(node)?; + for c in node.children() { + match c.data.borrow().value { + NodeValue::Text(_) => {} + NodeValue::Item(_) => {} + NodeValue::Code(_) => {} + _ => { + iter_nodes(c, f)?; + } + } + } + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index 46fd936..7bd2bcc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ use reqwest::{header, Client}; use std::path::PathBuf; use structopt::StructOpt; +mod changelog; mod cmd; mod gitea;