From f6eec7ec231bdb49ff0dacbfe39ea03ef05e60e8 Mon Sep 17 00:00:00 2001 From: Vitalii Guzeev Date: Thu, 23 Aug 2018 17:30:51 +0300 Subject: [PATCH 1/4] Separate git hosting dependent logics --- src/Changelogged/Changelog/Check.hs | 7 ++--- src/Changelogged/Changelog/Common.hs | 32 ++++++++++++++++++----- src/Changelogged/Changelog/Interactive.hs | 2 +- src/Changelogged/Common/Types/Common.hs | 3 +++ src/Changelogged/Git.hs | 23 ++++++++++------ src/Changelogged/Pattern.hs | 15 ++++++++--- 6 files changed, 60 insertions(+), 22 deletions(-) diff --git a/src/Changelogged/Changelog/Check.hs b/src/Changelogged/Changelog/Check.hs index 224b5f4..7faa7fd 100644 --- a/src/Changelogged/Changelog/Check.hs +++ b/src/Changelogged/Changelog/Check.hs @@ -16,7 +16,7 @@ import Changelogged.Changelog.Interactive import Changelogged.Changelog.Dry import Changelogged.Common import Changelogged.Pattern -import Changelogged.Git (retrieveCommitMessage) +import Changelogged.Git (retrieveCommitMessage, parseHostingType) checkChangelog :: GitInfo -> ChangelogConfig -> Appl () checkChangelog gitInfo@GitInfo{..} config@ChangelogConfig{..} = do @@ -50,6 +50,7 @@ checkChangelog gitInfo@GitInfo{..} config@ChangelogConfig{..} = do extractCommitMetadata :: GitInfo -> ChangelogConfig -> SHA1 -> Appl (Maybe Commit) extractCommitMetadata GitInfo{..} ChangelogConfig{..} commitSHA = do + let hosting = parseHostingType gitRemoteUrl ignoreChangeReasoned <- sequence $ [ commitNotWatched changelogWatchFiles commitSHA , allFilesIgnored changelogIgnoreFiles commitSHA @@ -58,7 +59,7 @@ extractCommitMetadata GitInfo{..} ChangelogConfig{..} commitSHA = do then return Nothing else do -- FIXME: impossible. - commitIsPR <- fmap (PR . fromJustCustom "Cannot find commit hash in git log entry" . githubRefMatch . lineToText) <$> - fold (grep githubRefGrep (grep (has (text (getSHA1 commitSHA))) (select gitHistory))) Fold.head + commitIsPR <- fmap (PR . fromJustCustom "Cannot find commit hash in git log entry" . refMatch hosting . lineToText) <$> + fold (grep (refGrep hosting) (grep (has (text (getSHA1 commitSHA))) (select gitHistory))) Fold.head commitMessage <- retrieveCommitMessage commitIsPR commitSHA return $ Just Commit{..} diff --git a/src/Changelogged/Changelog/Common.hs b/src/Changelogged/Changelog/Common.hs index 7e6f713..53ad8d1 100644 --- a/src/Changelogged/Changelog/Common.hs +++ b/src/Changelogged/Changelog/Common.hs @@ -13,22 +13,40 @@ import qualified Data.Text as Text import System.Console.ANSI (Color (..)) import Changelogged.Common -import Changelogged.Git (getCommitTag) +import Changelogged.Git (getCommitTag, parseHostingType) -- $setup -- >>> :set -XOverloadedStrings +prLink :: Link -> PR -> Link +prLink link pr = + let hostingType = parseHostingType link in + case hostingType of + GitHub -> githubPrLink link pr + -- FIXME: add builders for Bitbucket and Gitlab links. + BitBucket -> githubPrLink link pr + GitLab -> githubPrLink link pr + -- | --- >>> prLink (Link "https://github.com/GetShopTV/changelogged") (PR "#13") +-- >>> githubPrLink (Link "https://github.com/GetShopTV/changelogged") (PR "#13") -- Link {getLink = " https://github.com/GetShopTV/changelogged/pull/13 "} -prLink :: Link -> PR -> Link -prLink (Link link) (PR num) = Link $ " " <> link <> "/pull/" <> Text.drop 1 num <> " " +githubPrLink :: Link -> PR -> Link +githubPrLink (Link link) (PR num) = Link $ " " <> link <> "/pull/" <> Text.drop 1 num <> " " + +commitLink :: Link -> SHA1 -> Link +commitLink link hash = + let hostingType = parseHostingType link in + case hostingType of + GitHub -> githubCommitLink link hash + -- FIXME: add builders for Bitbucket and Gitlab links. + BitBucket -> githubCommitLink link hash + GitLab -> githubCommitLink link hash -- | --- >>> commitLink (Link "https://github.com/GetShopTV/changelogged") (SHA1 "9e14840") +-- >>> githubCommitLink (Link "https://github.com/GetShopTV/changelogged") (SHA1 "9e14840") -- Link {getLink = " https://github.com/GetShopTV/changelogged/commit/9e14840 "} -commitLink :: Link -> SHA1 -> Link -commitLink (Link link) (SHA1 sha) = Link $ " " <> link <> "/commit/" <> sha <> " " +githubCommitLink :: Link -> SHA1 -> Link +githubCommitLink (Link link) (SHA1 sha) = Link $ " " <> link <> "/commit/" <> sha <> " " printCommitTag :: SHA1 -> Appl () printCommitTag sha = getCommitTag sha >>= \tag -> case tag of diff --git a/src/Changelogged/Changelog/Interactive.hs b/src/Changelogged/Changelog/Interactive.hs index 96360bd..cd5c52d 100644 --- a/src/Changelogged/Changelog/Interactive.hs +++ b/src/Changelogged/Changelog/Interactive.hs @@ -37,7 +37,7 @@ interactiveSession prompt entryPrefix repoUrl changelog (current@Commit{..}:rest addMissing entryPrefix repoUrl current changelog if (isMerge commitMessage || isJust commitIsPR) then do - subChanges <- listPRCommits commitSHA + subChanges <- listPRCommits commitSHA repoUrl interactiveSession prompt (" " <> entryPrefix) repoUrl changelog subChanges else return () interactiveSession prompt entryPrefix repoUrl changelog rest diff --git a/src/Changelogged/Common/Types/Common.hs b/src/Changelogged/Common/Types/Common.hs index e6b7746..bde39c9 100644 --- a/src/Changelogged/Common/Types/Common.hs +++ b/src/Changelogged/Common/Types/Common.hs @@ -27,6 +27,9 @@ data Commit = Commit data Level = App | Major | Minor | Fix | Doc deriving (Generic, Show, Enum, Bounded, ToJSON) +data GitHosting = GitHub | BitBucket | GitLab + deriving (Generic, Show, Enum, Bounded, ToJSON) + showHumanReadableLevel :: Level -> Text showHumanReadableLevel App = "application level changes" showHumanReadableLevel Major = "major changes" diff --git a/src/Changelogged/Git.hs b/src/Changelogged/Git.hs index 4f7da6e..d8e22e1 100644 --- a/src/Changelogged/Git.hs +++ b/src/Changelogged/Git.hs @@ -1,7 +1,7 @@ --- | This module is intended to be pure git interface. {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE MultiWayIf #-} module Changelogged.Git where import qualified System.Process as Proc @@ -67,19 +67,26 @@ retrieveCommitMessage isPR (SHA1 commit) = do Just _ -> summary !! 2 Nothing -> summary !! 0 -messageToCommitData :: Line -> Appl Commit -messageToCommitData message = do +parseHostingType :: Link -> GitHosting +parseHostingType (Link url) = if + | "://github.com/" `Text.isInfixOf` url -> GitHub + | "://gitlab.com/" `Text.isInfixOf` url -> GitLab + | "://bitbucket.org/" `Text.isInfixOf` url -> BitBucket + +messageToCommitData :: Link -> Line -> Appl Commit +messageToCommitData repoUrl message = do + let hosting = parseHostingType repoUrl --FIXME: departed proofs? - commitIsPR <- fmap (PR . fromJustCustom "Cannot find commit hash in git log entry" . githubRefMatch . lineToText) <$> - fold (grep githubRefGrep (select [message])) Fold.head + commitIsPR <- fmap (PR . fromJustCustom "Cannot find commit hash in git log entry" . refMatch hosting . lineToText) <$> + fold (grep (refGrep hosting) (select [message])) Fold.head let commitSHA = SHA1 . fst . Text.breakOn " " . lineToText $ message commitMessage <- retrieveCommitMessage commitIsPR commitSHA return Commit{..} -listPRCommits :: SHA1 -> Appl [Commit] -listPRCommits (SHA1 sha) = do +listPRCommits :: SHA1 -> Link -> Appl [Commit] +listPRCommits (SHA1 sha) repoUrl = do messages <- fold (inproc "git" ["log", "--oneline", sha <> "^1..." <> sha <> "^2"] empty) Fold.list - commits <- mapM messageToCommitData messages + commits <- mapM (messageToCommitData repoUrl) messages return . reverse $ commits getCommitTag :: SHA1 -> Appl (Maybe Text) diff --git a/src/Changelogged/Pattern.hs b/src/Changelogged/Pattern.hs index c317684..95b3c75 100644 --- a/src/Changelogged/Pattern.hs +++ b/src/Changelogged/Pattern.hs @@ -74,10 +74,19 @@ githubRefRegex = has $ "#" <> plus digit githubRefGrep :: Pattern Text githubRefGrep = has (text "pull request #") --- >>> githubRefMatch "text #444 text" +--FIXME: add regexps for Gitlab and Bitbucket. + +refGrep :: GitHosting -> Pattern Text +refGrep GitHub = githubRefGrep +refGrep GitLab = githubRefGrep +refGrep BitBucket = githubRefGrep + +-- >>> refMatch GitHub "text #444 text" -- Just "#444" -githubRefMatch :: Text -> Maybe Text -githubRefMatch str = maxByLen $ match githubRefRegex str +refMatch :: GitHosting -> Text -> Maybe Text +refMatch GitHub str = maxByLen $ match githubRefRegex str +refMatch GitLab str = maxByLen $ match githubRefRegex str +refMatch BitBucket str = maxByLen $ match githubRefRegex str -- >>> isMerge "Merge branch 'release-v1.0'" -- True From 6ebf4efa9b9e07c5468299904950be01f6a79387 Mon Sep 17 00:00:00 2001 From: Vitalii Guzeev Date: Thu, 23 Aug 2018 18:16:41 +0300 Subject: [PATCH 2/4] Do not print suggestions outside of interactive mode since editor is open --- src/Changelogged/Changelog/Check.hs | 1 - src/Changelogged/Changelog/Interactive.hs | 29 ++++++++++++----------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Changelogged/Changelog/Check.hs b/src/Changelogged/Changelog/Check.hs index 7faa7fd..aa32918 100644 --- a/src/Changelogged/Changelog/Check.hs +++ b/src/Changelogged/Changelog/Check.hs @@ -46,7 +46,6 @@ checkChangelog gitInfo@GitInfo{..} config@ChangelogConfig{..} = do else simpleWalk gitRemoteUrl changelogChangelog) $ checkableCommits success $ showPath changelogChangelog <> " is updated.\n" - <> "You can edit it manually now.\n" extractCommitMetadata :: GitInfo -> ChangelogConfig -> SHA1 -> Appl (Maybe Commit) extractCommitMetadata GitInfo{..} ChangelogConfig{..} commitSHA = do diff --git a/src/Changelogged/Changelog/Interactive.hs b/src/Changelogged/Changelog/Interactive.hs index cd5c52d..0795b02 100644 --- a/src/Changelogged/Changelog/Interactive.hs +++ b/src/Changelogged/Changelog/Interactive.hs @@ -5,6 +5,7 @@ module Changelogged.Changelog.Interactive where import Prelude hiding (FilePath) import Turtle hiding (stdout) +import Control.Monad (when) import qualified Control.Foldl as Fold import Data.Maybe (fromMaybe, isJust) @@ -23,38 +24,38 @@ import Changelogged.Pattern (isMerge) -- >>> :set -XOverloadedStrings -- It cannot be folded since we have 'Remind' option. -interactiveSession :: Appl Interaction -> Text -> Link -> FilePath -> [Commit] -> Appl () -interactiveSession _ _ _ _ [] = return () -interactiveSession prompt entryPrefix repoUrl changelog (current@Commit{..}:rest) = do - suggestMissing entryPrefix repoUrl current +interactiveSession :: Appl Interaction -> Bool -> Text -> Link -> FilePath -> [Commit] -> Appl () +interactiveSession _ _ _ _ _ [] = return () +interactiveSession prompt printSug entryPrefix repoUrl changelog (current@Commit{..}:rest) = do + when printSug $ suggestMissing entryPrefix repoUrl current action <- prompt Options{..} <- gets envOptions case action of Write -> do addMissing entryPrefix repoUrl current changelog - interactiveSession prompt entryPrefix repoUrl changelog rest + interactiveSession prompt printSug entryPrefix repoUrl changelog rest Expand -> do addMissing entryPrefix repoUrl current changelog if (isMerge commitMessage || isJust commitIsPR) then do subChanges <- listPRCommits commitSHA repoUrl - interactiveSession prompt (" " <> entryPrefix) repoUrl changelog subChanges + interactiveSession prompt printSug (" " <> entryPrefix) repoUrl changelog subChanges else return () - interactiveSession prompt entryPrefix repoUrl changelog rest - Skip -> interactiveSession prompt entryPrefix repoUrl changelog rest - Remind -> showDiff commitSHA >> interactiveSession prompt "" repoUrl changelog (current:rest) + interactiveSession prompt printSug entryPrefix repoUrl changelog rest + Skip -> interactiveSession prompt printSug entryPrefix repoUrl changelog rest + Remind -> showDiff commitSHA >> interactiveSession prompt printSug "" repoUrl changelog (current:rest) IgnoreAlways -> do debug (showText changelog) addCommitToIgnored commitSHA changelog - interactiveSession prompt entryPrefix repoUrl changelog rest - Quit -> interactiveSession promptSkip "" repoUrl changelog rest - WriteRest -> interactiveSession promptSimple "" repoUrl changelog (current:rest) + interactiveSession prompt printSug entryPrefix repoUrl changelog rest + Quit -> interactiveSession promptSkip False "" repoUrl changelog rest + WriteRest -> interactiveSession promptSimple False "" repoUrl changelog (current:rest) interactiveWalk :: Link -> FilePath -> [Commit] -> Appl () -interactiveWalk = interactiveSession promptInteractive "" +interactiveWalk = interactiveSession promptInteractive True "" simpleWalk :: Link -> FilePath -> [Commit] -> Appl () -simpleWalk = interactiveSession promptSimple "" +simpleWalk = interactiveSession promptSimple False "" -- | suggestMissing :: Text -> Link -> Commit -> Appl () From 97a607b891c82ed9c1ab52f08323b04be4ca5b00 Mon Sep 17 00:00:00 2001 From: Vitalii Guzeev Date: Thu, 23 Aug 2018 18:19:47 +0300 Subject: [PATCH 3/4] Use $EDITOR as editor in default config --- src/Changelogged/Config.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Changelogged/Config.hs b/src/Changelogged/Config.hs index 2b16e41..173e28e 100644 --- a/src/Changelogged/Config.hs +++ b/src/Changelogged/Config.hs @@ -24,7 +24,7 @@ defaultConfig = Config } , configBranch = Nothing , configEntryFormat = Nothing - , configEditorCommand = Just "vim" + , configEditorCommand = Just "$EDITOR" } addCommitToIgnored :: SHA1 -> Turtle.FilePath -> Appl () From 478b846a76e14d1aa64c1dca67d82521277f0f1f Mon Sep 17 00:00:00 2001 From: Vitalii Guzeev Date: Thu, 23 Aug 2018 18:23:58 +0300 Subject: [PATCH 4/4] Warn user of trial to run editor --- README.md | 3 +++ src/Changelogged/Changelog/Check.hs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0732f03..590d194 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,9 @@ changelogged ``` After you refuse to do to interactive mode it will add missing entries to your changelogs and open editor for each if them. + +By default editor is set by `$EDITOR` variable. + After you can bummp versions over whole project (usable if you have more than one version file). That's it! Now you have a proper changelog with no forgotten changes. diff --git a/src/Changelogged/Changelog/Check.hs b/src/Changelogged/Changelog/Check.hs index aa32918..1de7b78 100644 --- a/src/Changelogged/Changelog/Check.hs +++ b/src/Changelogged/Changelog/Check.hs @@ -45,7 +45,7 @@ checkChangelog gitInfo@GitInfo{..} config@ChangelogConfig{..} = do then interactiveWalk gitRemoteUrl changelogChangelog else simpleWalk gitRemoteUrl changelogChangelog) $ checkableCommits - success $ showPath changelogChangelog <> " is updated.\n" + success $ showPath changelogChangelog <> " is updated.\nTrying to run editor." extractCommitMetadata :: GitInfo -> ChangelogConfig -> SHA1 -> Appl (Maybe Commit) extractCommitMetadata GitInfo{..} ChangelogConfig{..} commitSHA = do