Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add specs to the codebase #74

Merged
merged 19 commits into from
Mar 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# GitHub changelog

[![Continuous Integration status](https://api.travis-ci.org/whitepages/github-changelog.svg?branch=master)](http://travis-ci.org/whitepages/github-changelog)
[![Docker Build Status](https://img.shields.io/docker/build/jrottenberg/ffmpeg.svg)](https://hub.docker.com/r/whitepages/github-changelog/)
[![Docker Build Status](https://img.shields.io/docker/build/whitepages/github-changelog.svg)](https://hub.docker.com/r/whitepages/github-changelog/)
[![Docker pulls](https://img.shields.io/docker/pulls/whitepages/github-changelog.svg)](https://hub.docker.com/r/whitepages/github-changelog/)
[![GitHub license](https://img.shields.io/github/license/whitepages/github-changelog.svg)](https://github.com/whitepages/github-changelog/blob/master/LICENSE)

Expand Down
10 changes: 5 additions & 5 deletions deps.edn
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{:paths ["src"]
:deps {org.clojure/clojure {:mvn/version "1.10.1"}
org.martinklepsch/clj-http-lite {:mvn/version "0.4.3"}
metosin/jsonista {:mvn/version "0.2.4"}
org.clojure/core.async {:mvn/version "0.4.500"} ; clojure spec fixed
metosin/jsonista {:mvn/version "0.2.5"}
org.clojure/core.async {:mvn/version "1.0.567"} ; clojure spec fixed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there still a need for the comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure, but I have not tested.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's safe to remove

throttler {:mvn/version "1.0.0"}
org.slf4j/slf4j-nop {:mvn/version "1.7.28"}
org.slf4j/slf4j-nop {:mvn/version "1.7.30"}
grimradical/clj-semver {:mvn/version "0.3.0"
:exclusions [org.clojure/clojure]}
org.clojure/tools.cli {:mvn/version "0.4.2"}}
org.clojure/tools.cli {:mvn/version "1.0.194"}}
:aliases {:test {:extra-paths ["test"]
:extra-deps {org.clojure/test.check {:mvn/version "0.9.0"}
:extra-deps {org.clojure/test.check {:mvn/version "0.10.0"}
lambdaisland/kaocha {:mvn/version "0.0-541"}
lambdaisland/kaocha-cloverage {:mvn/version "0.0-41"}}}
:metav {:extra-deps {metav {:mvn/version "1.5.4"}}}
Expand Down
5 changes: 2 additions & 3 deletions src/github_changelog/cli.clj
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
(ns github-changelog.cli
(:gen-class)
(:require [clojure
[edn :as edn]
[string :as str]]
(:require [clojure.edn :as edn]
[clojure.string :as str]
[clojure.tools.cli :as cli]
[github-changelog.core :as core]
[github-changelog.formatters.markdown :as md]))
Expand Down
35 changes: 35 additions & 0 deletions src/github_changelog/config.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
(ns github-changelog.config
(:require [clojure.spec.alpha :as s]
[github-changelog.spec :as spec]))

(s/def ::git-url ::spec/url)

(s/def ::github ::spec/url)

(s/def ::github-api ::spec/url)

(s/def ::jira ::spec/url)

(s/def ::user ::spec/non-blank-string)

(s/def ::repo ::spec/non-blank-string)

(s/def ::dir ::spec/non-blank-string)

(s/def ::update? boolean?)

(s/def ::tag-prefix string?)

(s/def ::token ::spec/non-blank-string)

(s/def ::config-map
(s/keys :req-un [::user ::repo]
:opt-un [::token ::github ::github-api ::jira ::dir ::update? ::git-url]))

(def defaults {:github "https://github.com/"
:github-api "https://api.github.com/"
:update? true
:tag-prefix "v"})

(comment
(s/exercise ::config-map))
76 changes: 61 additions & 15 deletions src/github_changelog/conventional.clj
Original file line number Diff line number Diff line change
@@ -1,10 +1,51 @@
(ns github-changelog.conventional
(:require [clojure.string :as str]
(:require [clojure.spec.alpha :as s]
[clojure.spec.gen.alpha :as gen]
[clojure.string :as str]
[github-changelog.config :as config]
[github-changelog.core-spec :as core-spec]
[github-changelog.github :as github]
[github-changelog.spec :as spec]
[github-changelog.util :refer [strip-trailing]]))

; https://help.github.com/articles/closing-issues-via-commit-messages/
(def close-keywords #{"close" "closes" "closed" "fix" "fixes" "fixed" "resolve" "resolves" "resolved" "related to" "relates to"})

(def angular-pattern #"^(\w*)(?:\((.*)\))?\: (.*)$")

(s/def ::type ::spec/non-blank-string)
(s/def ::scope string?)
(s/def ::subject ::spec/non-blank-string)

(s/def ::issue (s/tuple ::spec/non-blank-string ::spec/url))

(s/def ::issues (s/* ::issue))

(defn title-gen []
(gen/fmap (fn [[type scope subject]]
(if (str/blank? scope)
(format "%s: %s" type subject)
(format "%s(%s): %s" type scope subject)))
(s/gen (s/tuple ::type ::scope ::subject))))

(s/def ::title
(s/with-gen
(s/and string? #(re-matches angular-pattern %))
title-gen))

;; (s/def ::revert-pull pos-int?)

;; (s/def ::revert-pr
;; (s/keys :req-un [::revert-pull ::pull-request]))

(s/def ::pull-request ::github/pull)

(s/def ::change (s/keys :req-un [::type ::scope ::subject ::pull-request ::issues]))
(s/def ::changes (s/* ::change))

(s/def ::tag-with-changes
(s/merge ::core-spec/tag-with-pulls (s/keys :req-un [::changes])))

(defn fixes-pattern
([pattern] (fixes-pattern pattern close-keywords))
([pattern closing-words]
Expand All @@ -13,8 +54,6 @@
(str/join \| closing-words)
pattern))))

(def angular-pattern #"^(\w*)(?:\((.*)\))?\: (.*)$")

(defn collect-issues [pull pattern link-fn]
(->> (:body pull)
(str)
Expand Down Expand Up @@ -49,19 +88,17 @@

(defn parse-pull [config {:keys [title] :as pull}]
(if-let [pull-id (parse-revert config pull)]
{:revert-pull pull-id
{:revert-pull pull-id
:pull-request pull}
(if-let [[_ type scope subject] (re-find angular-pattern title)]
{:type type
:scope scope
:subject subject
(when-let [[_ type scope subject] (re-find angular-pattern title)]
{:type type
:scope scope
:subject subject
:pull-request pull
:issues (parse-issues config pull)})))
:issues (parse-issues config pull)})))

(defn reverted-ids [pulls]
(->> (map :revert-pull pulls)
(remove nil?)
(set)))
(set (keep :revert-pull pulls)))

(defn filter-reverted [pulls pull]
(let [reverted-pulls (reverted-ids pulls)
Expand All @@ -70,9 +107,18 @@
pulls
(conj pulls pull))))

(defn parse-changes [config {:keys [pulls] :as tag}]
(->> (map (partial parse-pull config) pulls)
(remove nil?)
(defn ^:no-gen parse-changes [config {:keys [pulls] :as tag}]
(->> (keep (partial parse-pull config) pulls)
(reduce filter-reverted [])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you rewrite filter-reverted to be pred-ish (sorta like (defn reverted? [pulls pull] ,,,)), you could write these 2 lines as (into [] (comp (keep (partial ,,,)) (remove reverted?)) pulls), I think.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also comp in the next line then

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also though that but filter-reverted needs to see the full keep produced seq. Therefore you can't use on it on a single element inside a transducer chain.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I didn't realise pulls is that seq.

(remove :revert-pull)
(assoc tag :changes)))

(s/fdef parse-changes
:args (s/cat :config ::config/config-map :tag ::core-spec/tag-with-pulls)
:ret (s/* ::tag-with-changes))

(comment
(s/exercise-fn `parse-changes)
(s/exercise ::issue)
(s/exercise ::issues)
(s/exercise ::title))
55 changes: 41 additions & 14 deletions src/github_changelog/core.clj
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
(ns github-changelog.core
(:require [github-changelog
[conventional :as conventional]
[git :as git]
[github :as github]
[semver :as semver]]))
(:require [clojure.spec.alpha :as s]
[github-changelog.config :as config]
[github-changelog.conventional :as conventional]
[github-changelog.core-spec :as core-spec]
[github-changelog.git :as git]
[github-changelog.github :as github]
[github-changelog.semver :as semver]))

(defn assoc-semver [prefix {:keys [name] :as tag}]
(assoc tag :version (semver/extract name prefix)))
Expand All @@ -21,26 +23,51 @@
(defn assoc-commits [git-repo {:keys [from sha] :as tag}]
(assoc tag :commits (git/commits git-repo from sha)))

(defn load-tags [config]
(defn map-commits [tags git-repo]
(map (partial assoc-commits git-repo) tags))

(defn ^:no-gen load-tags [config]
(let [git-repo (git/init config)
tags (git/tags git-repo)
prefix (get config :tag-prefix "v")]
(map (partial assoc-commits git-repo) (parse-tags tags prefix))))
(-> (git/tags git-repo)
(parse-tags prefix)
(map-commits git-repo))))

(s/fdef load-tags
:args (s/cat :config ::config/config-map)
:ret (s/* ::core-spec/tag))

(defn find-pull [pulls sha]
(first (filter #(= (:sha %) sha) pulls)))
(first (filter #(= (github/get-sha %) sha) pulls)))

(defn assoc-pulls [pulls {:keys [commits] :as tag}]
(let [related-pulls (remove nil? (map (partial find-pull pulls) commits))]
(assoc tag :pulls related-pulls)))
(->> commits
(keep (partial find-pull pulls))
(assoc tag :pulls)))

(s/fdef assoc-pulls
:args (s/cat :pulls (s/coll-of ::github/pull) :tag ::core-spec/tag)
:ret ::core-spec/tag-with-pulls)

(defn changelog
(defn ^:no-gen collect-tags [config]
(let [pulls (github/fetch-pulls config)]
(->> (load-tags config)
(map (partial assoc-pulls pulls)))))

(s/fdef collect-tags
:args (s/cat :config ::config/config-map)
:ret (s/* ::core-spec/tag-with-pulls))

(defn ^:no-gen changelog
"Fetches the changelog"
[config]
(->> (load-tags config)
(map (partial assoc-pulls (github/fetch-pulls config)))
(->> (collect-tags config)
(map (partial conventional/parse-changes config))))

(s/fdef changelog
:args (s/cat :config ::config/config-map)
:ret (s/* ::conventional/tag-with-changes))

(defn filter-tags [tags {:keys [last since until]}]
(cond->> tags
since (filter #(semver/newer? (:version %) since))
Expand Down
19 changes: 19 additions & 0 deletions src/github_changelog/core_spec.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
(ns github-changelog.core-spec
(:require [clojure.spec.alpha :as s]
[github-changelog.git :as git]
[github-changelog.github :as github]
[github-changelog.semver :as semver]))

(s/def ::commits (s/* ::git/commit))

(s/def ::tag
(s/merge ::git/tag (s/keys :req-un [::semver/version ::commits])))

(s/def ::pulls (s/* ::github/pull))

(s/def ::tag-with-pulls
(s/merge ::tag (s/keys :req-un [::pulls])))

(comment
(s/exercise ::tag)
(s/exercise ::tag-with-pulls))
6 changes: 0 additions & 6 deletions src/github_changelog/defaults.clj

This file was deleted.

19 changes: 9 additions & 10 deletions src/github_changelog/formatters/markdown.clj
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
(ns github-changelog.formatters.markdown
(:require [clojure.string :refer [join]]
[github-changelog
[markdown :as md]
[semver :refer [get-type]]
[util :refer [str-map]]]))
(:require [clojure.string :as str]
[github-changelog.markdown :as md]
[github-changelog.semver :as semver]
[github-changelog.util :as util]))

(defmulti translate-type identity)

Expand Down Expand Up @@ -34,10 +33,10 @@
subject
(format-pull-request pull-request)
(if-let [issues (seq issues)]
(str ", closes " (join ", " (map (partial apply md/link) issues))))))
(str ", closes " (str/join ", " (map (partial apply md/link) issues))))))

(defn- format-entries [changes]
(join (map md/li changes)))
(str/join (map md/li changes)))

(defmulti format-grouped-changes (comp count second))

Expand All @@ -62,7 +61,7 @@
(flatten)
(format-entries))))

(defmulti highlight-fn get-type)
(defmulti highlight-fn semver/get-type)

(defmethod highlight-fn :major [_] (comp md/h2 md/emphasis))
(defmethod highlight-fn :minor [_] md/h2)
Expand All @@ -74,7 +73,7 @@
((highlight-fn version) name))

(defn format-changes [changes]
(str-map format-change-group (group-by :type changes)))
(util/str-map format-change-group (group-by :type changes)))

(defn format-tag [{:keys [version name changes]}]
(str (format-version version name)
Expand All @@ -85,4 +84,4 @@
[tags {:keys [collapse-tags]}]
(if collapse-tags
(format-changes (mapcat :changes tags))
(str-map format-tag tags)))
(util/str-map format-tag tags)))
Loading