diff options
author | Julio Capote <jcapote@gmail.com> | 2023-01-24 03:20:47 +0000 |
---|---|---|
committer | Julio Capote <jcapote@gmail.com> | 2023-01-24 03:20:47 +0000 |
commit | f24f2d15275961f1c0144e68fde75a60aeaaa165 (patch) | |
tree | 38be1626f3ade436fbd17eadb2753fa2f0effb37 /content/blog/2012-11-13-automatic-high-quality-releases.markdown | |
parent | bf04383b34c4a4fdfe239de2805a30a051921002 (diff) | |
download | capotej.com-f24f2d15275961f1c0144e68fde75a60aeaaa165.tar.gz |
move to bear theme
Diffstat (limited to 'content/blog/2012-11-13-automatic-high-quality-releases.markdown')
-rw-r--r-- | content/blog/2012-11-13-automatic-high-quality-releases.markdown | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/content/blog/2012-11-13-automatic-high-quality-releases.markdown b/content/blog/2012-11-13-automatic-high-quality-releases.markdown new file mode 100644 index 0000000..ed62c90 --- /dev/null +++ b/content/blog/2012-11-13-automatic-high-quality-releases.markdown @@ -0,0 +1,117 @@ +--- +title: "Automatic High Quality Releases" +date: 2012-11-13T21:31:00Z +comments: true +tags: ["shell scripting", "finatra"] +--- + +Recently, I invested some time into automating some of the work that goes into a [Finatra](http://github.com/capotej/finatra#readme) release. + +<!--more--> + +The work consists of updating: + +* The version in the XML fragment of the main [README.markdown](https://github.com/finatra/https://github.com/capotej/finatra/blob/master/README.markdown) + +* The version in the [pom.xml](https://github.com/capotej/finatra-example/blob/master/pom.xml) of the [example app](http://github.com/capotej/finatra-example) + +* Any API changes in the [example app](http://github.com/capotej/finatra-example) + +* The version in the template pom.xml of the app generator + +* The generated unit test of the app generator that demonstrates testing any new API features + +* Any API changes inside the app template of the app generator + +Using [sub](https://github.com/37signals/sub#readme), I was able to create a `finatra` [command](https://github.com/capotej/finatra/tree/master/script/finatra) that automated all of the above based on a single template, which also happens to be the [main unit test](https://github.com/capotej/finatra/blob/master/src/test/scala/com/twitter/finatra/ExampleSpec.scala). This ensures that the README, the example app, and the app generator never fall out of sync with the frameworks API. + + +Last week we released [1.1.0](https://github.com/capotej/finatra/commit/37c81957271dde77d4c3f6361bbae705a5142c89), and the README was [completely generated](https://github.com/capotej/finatra/commit/913d0ed5bfa18c903feb5779d4d8b9d87703b6c5), as was the [example app](https://github.com/capotej/finatra-example/commit/dbc82908360f3cb4cfc4388c28f593f17258fab2). Not to mention, all generated apps would also contain the latest templates and examples! + +![](https://i0.kym-cdn.com/photos/images/original/000/021/073/1254172884282.jpg?1254173845) + +Let's dive into how it all works: + +## The source of truth + +I annotated our main unit test with special tokens, like so: + +```scala ExampleAppSpec.scala +class ExampleSpec extends SpecHelper { + + /* ###BEGIN_APP### */ + + class ExampleApp extends Controller { + + /** + * Basic Example + * + * curl http://localhost:7070/hello => "hello world" + */ + get("/") { request => + render.plain("hello world").toFuture + } + + } + + val app = new ExampleApp + + /* ###END_APP### */ + + + /* ###BEGIN_SPEC### */ + + "GET /hello" should "respond with hello world" in { + get("/") + response.body should equal ("hello world") + } + + /* ###END_SPEC### */ +} +``` + +Using the special `/* ### */` comments, the main app and its test can be extracted from the code of our test. + +## The app generator + +Now that we have our "template", we can build our app generator to use it. I customized [base](http://capotej.com/blog/2012/11/01/base-a-scala-project-generator/) and ended up with: [script/finatra/libexec/finatra-new](https://github.com/capotej/finatra/blob/master/script/finatra/libexec/finatra-new) + +You can then run: + +```sh +$ ./finatra new com.example.myapp +``` + +and it will generate ```myapp/``` based on the tested example code from the test suite above. + +## The example app + +The [example app](https://github.com/capotej/finatra-example#readme) is just a generated app using the latest app generator: + +```sh + +#!/bin/bash +# Usage: finatra update-example +# Summary: generates the example app from the template + +set -e + +source $_FINATRA_ROOT/lib/base.sh + +tmpdir=$(mktemp -d /tmp/finatra_example.XXX) + +$_FINATRA_ROOT/bin/finatra new com.twitter.finatra_example $tmpdir + +cp -Rv $tmpdir/finatra_example/ $EXAMPLE_REPO + +rm -rf $tmpdir + +cd $EXAMPLE_REPO && mvn test + +``` + +This also tests the app generator and the generated app! + +## Updating the README + +Lastly, there's a [command](https://github.com/capotej/finatra/blob/master/script/finatra/libexec/finatra-update-readme) for updating the README with the new example and version number. |