Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
S
shift
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Eduardo Trujillo
shift
Commits
89e5d59e
Commit
89e5d59e
authored
4 years ago
by
Eduardo Trujillo
Browse files
Options
Downloads
Patches
Plain Diff
feat(Rendering): Render to an cmark tree before printing
parent
ffdb6152
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
shift.cabal
+1
-0
1 addition, 0 deletions
shift.cabal
src/Shift/Git.hs
+28
-14
28 additions, 14 deletions
src/Shift/Git.hs
src/Shift/Rendering.hs
+114
-75
114 additions, 75 deletions
src/Shift/Rendering.hs
src/Shift/Types.hs
+0
-1
0 additions, 1 deletion
src/Shift/Types.hs
with
143 additions
and
90 deletions
shift.cabal
+
1
−
0
View file @
89e5d59e
...
@@ -47,6 +47,7 @@ library
...
@@ -47,6 +47,7 @@ library
, vector
, vector
, exceptions
, exceptions
, semigroups
, semigroups
, cmark-gfm
default-language: Haskell2010
default-language: Haskell2010
executable shift
executable shift
...
...
This diff is collapsed.
Click to expand it.
src/Shift/Git.hs
+
28
−
14
View file @
89e5d59e
...
@@ -14,8 +14,15 @@ import qualified Data.ByteString.Char8 as BS
...
@@ -14,8 +14,15 @@ import qualified Data.ByteString.Char8 as BS
import
Data.Default
(
def
)
import
Data.Default
(
def
)
import
Data.Either
(
rights
)
import
Data.Either
(
rights
)
import
Data.Git
import
Data.Git
(
tagList
,
getObject
,
withRepo
,
RefName
(
refNameRaw
),
Ref
,
Git
,
Commit
(
commitMessage
)
)
import
Data.Git.Ref
(
HashAlgorithm
,
fromHex
,
isHex
)
import
Data.Git.Ref
(
HashAlgorithm
,
fromHex
,
isHex
)
import
Data.Git.Storage.Object
import
Data.Git.Storage.Object
(
Object
(
ObjCommit
)
)
import
Data.List
(
sortBy
)
import
Data.List
(
sortBy
)
import
Data.Maybe
(
catMaybes
)
import
Data.Maybe
(
catMaybes
)
import
Data.Set
as
S
(
toList
)
import
Data.Set
as
S
(
toList
)
...
@@ -30,13 +37,14 @@ import GitHub.Auth (Auth (OAuth))
...
@@ -30,13 +37,14 @@ import GitHub.Auth (Auth (OAuth))
import
Network.HTTP.Client
(
newManager
)
import
Network.HTTP.Client
(
newManager
)
import
Network.HTTP.Client.TLS
(
tlsManagerSettings
)
import
Network.HTTP.Client.TLS
(
tlsManagerSettings
)
import
Shift.CLI
import
Shift.CLI
import
Shift.Processing
import
Shift.Processing
(
generateReport
,
parseCommit
)
import
Shift.Rendering
import
Shift.Rendering
(
printReport
)
import
Shift.Types
import
Shift.Types
import
Shift.Utilities
(
orError
,
pairs
)
import
Shift.Utilities
(
orError
,
pairs
)
import
System.Process
import
System.Process
(
readCreateProcess
,
shell
)
import
Text.Megaparsec
(
ParseError
)
import
Text.Megaparsec
(
ParseError
)
import
Text.Megaparsec.Error
(
ParseErrorBundle
)
import
Text.Megaparsec.Error
(
ParseErrorBundle
)
import
CMarkGFM
(
NodeType
(
DOCUMENT
),
NodeType
(
DOCUMENT
),
nodeToCommonmark
,
nodeToCommonmark
,
Node
(
Node
))
parseTag
::
RefName
->
Either
(
ParseErrorBundle
Text
Void
)
TagRef
parseTag
::
RefName
->
Either
(
ParseErrorBundle
Text
Void
)
TagRef
parseTag
ref
=
case
versioning
.
cs
.
refNameRaw
$
ref
of
parseTag
ref
=
case
versioning
.
cs
.
refNameRaw
$
ref
of
...
@@ -44,23 +52,31 @@ parseTag ref = case versioning . cs . refNameRaw $ ref of
...
@@ -44,23 +52,31 @@ parseTag ref = case versioning . cs . refNameRaw $ ref of
Right
v
->
Right
(
TagRef
ref
v
)
Right
v
->
Right
(
TagRef
ref
v
)
tempMain
::
ShiftOptions
->
IO
()
tempMain
::
ShiftOptions
->
IO
()
tempMain
opts
=
withRepo
".git"
$
\
repo
->
do
tempMain
opts
=
do
node
<-
renderToNode
opts
liftIO
$
TIO
.
putStr
$
nodeToCommonmark
[]
Nothing
node
renderToNode
::
ShiftOptions
->
IO
Node
renderToNode
opts
=
withRepo
".git"
$
\
repo
->
do
tags
<-
tagList
repo
tags
<-
tagList
repo
let
sortedVersions
=
sortBy
(
flip
compare
)
.
rights
$
parseTag
<$>
toList
tags
let
sortedVersions
=
sortBy
(
flip
compare
)
.
rights
$
parseTag
<$>
toList
tags
pairedTags
=
swap
<$>
pairs
sortedVersions
pairedTags
=
swap
<$>
pairs
sortedVersions
case
opts
^.
soHostingType
of
nodes
<-
case
opts
^.
soHostingType
of
GitHubType
->
do
GitHubType
->
do
state
<-
initGitHubState
state
<-
initGitHubState
runReaderT
fst
<$>
runReaderT
(
void
$
runStateT
(
mapM
_
(
renderDiff
repo
)
pairedTags
)
state
)
(
runStateT
(
mapM
(
renderDiff
repo
)
pairedTags
)
state
)
opts
opts
GitType
->
GitType
->
runReaderT
fst
<$>
runReaderT
(
void
$
runStateT
(
mapM
_
(
renderDiff
repo
)
pairedTags
)
GitClientState
)
(
runStateT
(
mapM
(
renderDiff
repo
)
pairedTags
)
GitClientState
)
opts
opts
pure
(
Node
Nothing
DOCUMENT
(
concat
nodes
))
where
where
initGitHubState
=
do
initGitHubState
=
do
manager
<-
newManager
tlsManagerSettings
manager
<-
newManager
tlsManagerSettings
...
@@ -80,15 +96,13 @@ tempMain opts = withRepo ".git" $ \repo -> do
...
@@ -80,15 +96,13 @@ tempMain opts = withRepo ".git" $ \repo -> do
_gcsRepository
=
cs
repositoryName
_gcsRepository
=
cs
repositoryName
}
}
renderDiff
::
(
ClientState
s
,
HashAlgorithm
hash
)
=>
Git
hash
->
(
TagRef
,
TagRef
)
->
GitM
s
()
renderDiff
::
(
ClientState
s
,
HashAlgorithm
hash
)
=>
Git
hash
->
(
TagRef
,
TagRef
)
->
GitM
s
[
Node
]
renderDiff
repo
(
tx
,
ty
)
=
do
renderDiff
repo
(
tx
,
ty
)
=
do
liftIO
.
TIO
.
putStrLn
.
headerOne
$
renderRange
tx
ty
diff
<-
lookupCommitsDiff
repo
tx
ty
diff
<-
lookupCommitsDiff
repo
tx
ty
case
diff
of
case
diff
of
[]
->
throwM
SEUnableToComputeDiff
[]
->
throwM
SEUnableToComputeDiff
diff_
->
printReport
(
generateReport
.
rights
$
parseCommit
<$>
diff_
)
diff_
->
printReport
(
tx
,
ty
)
(
generateReport
.
rights
$
parseCommit
<$>
diff_
)
lookupCommitsDiff
::
(
HashAlgorithm
hash
)
=>
Git
hash
->
TagRef
->
TagRef
->
GitM
s
[(
Ref
hash
,
Commit
hash
)]
lookupCommitsDiff
::
(
HashAlgorithm
hash
)
=>
Git
hash
->
TagRef
->
TagRef
->
GitM
s
[(
Ref
hash
,
Commit
hash
)]
lookupCommitsDiff
repo
x
y
=
do
lookupCommitsDiff
repo
x
y
=
do
...
...
This diff is collapsed.
Click to expand it.
src/Shift/Rendering.hs
+
114
−
75
View file @
89e5d59e
{-# LANGUAGE FlexibleContexts
#-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE OverloadedStrings #-}
module
Shift.Rendering
where
module
Shift.Rendering
where
import
CMarkGFM
as
M
import
Control.Lens
((
^.
))
import
Control.Monad.Catch
(
MonadThrow
)
import
Control.Monad.IO.Class
(
MonadIO
,
liftIO
)
import
Control.Monad.State
(
MonadState
)
import
Control.Monad.Trans.Writer
(
WriterT
(
runWriterT
),
execWriterT
,
runWriter
)
import
Control.Monad.Trans.Writer.Lazy
(
tell
)
import
Data.Git
(
Commit
,
Ref
,
commitAuthor
)
import
Data.List
(
sortOn
)
import
Data.List
(
sortOn
)
import
Data.Maybe
(
catMaybes
)
import
Control.Lens
((
^.
))
import
Data.Monoid
((
<>
))
import
Control.Monad.Catch
(
MonadThrow
)
import
Data.String.Conversions
(
cs
)
import
Control.Monad.IO.Class
(
MonadIO
,
liftIO
)
import
Data.Text
(
Text
)
import
Control.Monad.State
(
MonadState
)
import
qualified
Data.Text
as
T
(
take
)
import
Data.Git
(
Commit
,
Ref
,
commitAuthor
)
import
qualified
Data.Text.IO
as
TIO
(
putStr
,
putStrLn
)
import
Data.Monoid
((
<>
))
import
Data.Versions
(
prettyV
)
import
Data.String.Conversions
(
cs
)
import
Data.Text
(
Text
)
import
qualified
Data.Text
as
T
(
take
)
import
qualified
Data.Text.IO
as
TIO
(
putStrLn
)
import
Data.Versions
(
prettyV
)
import
Shift.Types
import
Shift.Types
renderRef
renderRef
::
::
(
MonadIO
m
,
MonadState
s
m
,
ClientState
s
,
MonadThrow
m
)
(
MonadIO
m
,
MonadState
s
m
,
ClientState
s
,
MonadThrow
m
)
=>
=>
Ref
hash
Ref
hash
->
->
m
Text
m
[
Node
]
renderRef
ref
=
do
renderRef
ref
=
do
url
<-
getRefURL
ref
url
<-
getRefURL
ref
let
shortRef
=
T
.
take
7
.
cs
.
show
$
ref
let
shortRef
=
T
.
take
7
.
cs
.
show
$
ref
let
shortRefNode
=
leafNode
(
CODE
shortRef
)
pure
$
case
url
of
pure
$
case
url
of
Just
url_
->
"[[`"
<>
shortRef
<>
"`]("
<>
url_
<>
"
)
]"
Just
url_
->
[
textNode
"["
,
parentNode
(
LINK
url_
shortRef
)
[
shortRefNode
],
textNode
"]"
]
Nothing
->
"[`"
<>
shortRef
<>
"
`
]"
Nothing
->
[
textNode
"["
,
shortRefNode
,
textNode
"]"
]
renderConventionalCommit
renderConventionalCommit
::
::
(
MonadIO
m
,
MonadState
s
m
,
ClientState
s
,
MonadThrow
m
)
(
MonadIO
m
,
MonadState
s
m
,
ClientState
s
,
MonadThrow
m
)
=>
=>
ConventionalGroup
hash
ConventionalGroup
hash
->
->
m
Text
m
Node
renderConventionalCommit
(
ref
,
commit
,
pc
)
=
do
renderConventionalCommit
(
ref
,
commit
,
pc
)
=
do
renderedRef
<-
renderRef
ref
renderedRef
<-
renderRef
ref
authorText
<-
renderAuthor
commit
ref
authorText
<-
renderAuthor
commit
ref
pure
.
mconcat
$
pure
$
[
"- "
listItemNode
,
renderedRef
[
paragraphNode
$
,
" "
renderedRef
,
bold
$
pc
^.
ccScope
<>
":"
<>
catMaybes
,
" "
[
Just
$
textNode
" "
,
,
pc
^.
ccSubject
Just
.
bold
$
pc
^.
ccScope
<>
":"
,
,
authorText
Just
$
textNode
" "
,
]
Just
.
textNode
$
pc
^.
ccSubject
,
Just
$
textNode
" "
,
renderAuthor
authorText
::
(
MonadIO
m
,
MonadState
s
m
,
ClientState
s
,
MonadThrow
m
)
]
=>
Commit
hash
]
->
Ref
hash
->
m
Text
renderAuthor
::
(
MonadIO
m
,
MonadState
s
m
,
ClientState
s
,
MonadThrow
m
)
=>
Commit
hash
->
Ref
hash
->
m
(
Maybe
Node
)
renderAuthor
commit
ref
=
do
renderAuthor
commit
ref
=
do
authorInfo
<-
getAuthorInfo
(
commitAuthor
commit
)
ref
authorInfo
<-
getAuthorInfo
(
commitAuthor
commit
)
ref
pure
$
case
authorInfo
of
pure
$
case
authorInfo
of
Just
(
username
,
authorUrl
)
->
" [("
<>
username
<>
")]("
<>
authorUrl
<>
")"
Just
(
username
,
authorUrl
)
->
Just
$
parentNode
(
LINK
authorUrl
username
)
[
textNode
username
]
Nothing
->
""
Nothing
->
Nothing
renderMiscCommit
renderMiscCommit
::
::
(
MonadIO
m
,
MonadState
s
m
,
ClientState
s
,
MonadThrow
m
)
(
MonadIO
m
,
MonadState
s
m
,
ClientState
s
,
MonadThrow
m
)
=>
=>
MiscGroup
hash
MiscGroup
hash
->
->
m
Text
m
Node
renderMiscCommit
(
ref
,
commit
,
MiscCommit
subject
)
=
do
renderMiscCommit
(
ref
,
commit
,
MiscCommit
subject
)
=
do
renderedRef
<-
renderRef
ref
renderedRef
<-
renderRef
ref
authorText
<-
renderAuthor
commit
ref
authorText
<-
renderAuthor
commit
ref
pure
$
"- "
<>
renderedRef
<>
" "
<>
subject
<>
authorText
pure
$
listItemNode
renderMergeCommit
[
paragraphNode
$
::
(
MonadIO
m
,
MonadState
s
m
,
ClientState
s
,
MonadThrow
m
)
renderedRef
=>
MergeGroup
hash
<>
catMaybes
->
m
Text
[
Just
$
textNode
subject
,
Just
$
textNode
" "
,
authorText
]
]
renderMergeCommit
::
(
MonadIO
m
,
MonadState
s
m
,
ClientState
s
,
MonadThrow
m
)
=>
MergeGroup
hash
->
m
Node
renderMergeCommit
(
ref
,
commit
,
MergeCommit
subject
)
=
do
renderMergeCommit
(
ref
,
commit
,
MergeCommit
subject
)
=
do
renderedRef
<-
renderRef
ref
renderedRef
<-
renderRef
ref
authorText
<-
renderAuthor
commit
ref
authorText
<-
renderAuthor
commit
ref
pure
$
"- "
<>
renderedRef
<>
" Merge "
<>
subject
<>
authorText
pure
$
listItemNode
[
paragraphNode
$
renderedRef
<>
catMaybes
[
Just
$
textNode
$
"Merge "
<>
subject
,
authorText
]
]
renderRange
::
TagRef
->
TagRef
->
Text
renderRange
::
TagRef
->
TagRef
->
Text
renderRange
tx
ty
=
mconcat
renderRange
tx
ty
=
[
prettyV
.
_tVersioning
$
tx
,
" to "
,
prettyV
.
_tVersioning
$
ty
]
mconcat
[
prettyV
.
_tVersioning
$
tx
,
" to "
,
prettyV
.
_tVersioning
$
ty
]
bold
::
Text
->
Text
bold
::
Text
->
Node
bold
x
=
"**"
<>
x
<>
"**"
bold
x
=
parentNode
STRONG
[
textNode
x
]
indented
::
Int
->
Text
->
Text
indented
::
Int
->
Text
->
Text
indented
levels
x
=
foldl
(
\
acc
_
->
acc
<>
" "
)
""
[
1
..
levels
]
<>
x
indented
levels
x
=
foldl
(
\
acc
_
->
acc
<>
" "
)
""
[
1
..
levels
]
<>
x
indentedL
::
Int
->
Text
->
Text
indentedL
::
Int
->
Text
->
Text
indentedL
levels
x
=
"
\\
"
<>
foldl
(
\
acc
_
->
acc
<>
"-"
)
""
[
1
..
levels
]
<>
x
indentedL
levels
x
=
"
\\
"
<>
foldl
(
\
acc
_
->
acc
<>
"-"
)
""
[
1
..
levels
]
<>
x
headerOne
::
Text
->
Node
headerOne
t
=
parentNode
(
HEADING
1
)
[
textNode
t
]
headerTwo
::
Text
->
Node
headerTwo
t
=
parentNode
(
HEADING
2
)
[
textNode
t
]
linePadded
::
Text
->
Text
headerThree
::
Text
->
Node
linePadded
x
=
"
\n
"
<>
x
<>
"
\n
"
headerThree
t
=
parentNode
(
HEADING
3
)
[
textNode
t
]
headerOn
e
::
Text
->
Text
textNod
e
::
Text
->
Node
headerOne
=
linePadded
.
(
<>
)
"# "
textNode
t
=
Node
Nothing
(
TEXT
t
)
[]
h
ea
derTwo
::
Text
->
Text
l
ea
fNode
::
NodeType
->
Node
h
ea
derTwo
=
linePadded
.
(
<>
)
"## "
l
ea
fNode
n
=
Node
Nothing
n
[]
headerThree
::
Text
->
Text
parentNode
::
NodeType
->
[
Node
]
->
Node
headerThree
=
linePadded
.
(
<>
)
"### "
parentNode
=
Node
Nothing
listItemNode
::
[
Node
]
->
Node
listItemNode
=
parentNode
ITEM
paragraphNode
::
[
Node
]
->
Node
paragraphNode
=
parentNode
PARAGRAPH
printReport
::
(
MonadIO
m
,
MonadState
s
m
,
ClientState
s
,
MonadThrow
m
)
=>
(
TagRef
,
TagRef
)
->
ChangeReport
hash
->
m
[
Node
]
printReport
(
rangeStart
,
rangeEnd
)
report
=
execWriterT
$
do
tell
[
headerOne
$
renderRange
rangeStart
rangeEnd
]
printReport
::
(
MonadIO
m
,
MonadState
s
m
,
ClientState
s
,
MonadThrow
m
)
=>
ChangeReport
hash
->
m
()
printReport
report
=
do
-- Print conventional commits
-- Print conventional commits
conventionalSection
"New features:"
crFeatures
conventionalSection
"New features:"
crFeatures
conventionalSection
"Fixes:"
crFixes
conventionalSection
"Fixes:"
crFixes
...
@@ -129,7 +169,7 @@ printReport report = do
...
@@ -129,7 +169,7 @@ printReport report = do
textSection
"Merge commits:"
mergeCommits
textSection
"Merge commits:"
mergeCommits
where
where
conventionalSection
label
sectionLens
=
do
conventionalSection
label
sectionLens
=
do
let
rawCommits
=
sortOn
(
\
(
_
,
_
,
pc
)
->
pc
^.
ccScope
)
(
report
^.
sectionLens
)
let
rawCommits
=
sortOn
(
\
(
_
,
_
,
pc
)
->
pc
^.
ccScope
)
(
report
^.
sectionLens
)
commits
<-
mapM
renderConventionalCommit
rawCommits
commits
<-
mapM
renderConventionalCommit
rawCommits
textSection
label
commits
textSection
label
commits
...
@@ -137,7 +177,6 @@ printReport report = do
...
@@ -137,7 +177,6 @@ printReport report = do
textSection
label
commits
=
case
commits
of
textSection
label
commits
=
case
commits
of
[]
->
pure
()
[]
->
pure
()
_
->
do
_
->
do
liftIO
.
TIO
.
putStrLn
.
headerTwo
$
label
tell
[
headerTwo
label
]
liftIO
$
mapM_
(
TIO
.
putStrLn
.
indented
1
)
commits
tell
[
parentNode
(
LIST
(
ListAttributes
BULLET_LIST
False
0
PAREN_DELIM
))
commits
]
This diff is collapsed.
Click to expand it.
src/Shift/Types.hs
+
0
−
1
View file @
89e5d59e
...
@@ -43,7 +43,6 @@ import GitHub (URL(URL))
...
@@ -43,7 +43,6 @@ import GitHub (URL(URL))
import
GitHub
(
getUrl
)
import
GitHub
(
getUrl
)
import
GitHub
(
getUrl
)
import
GitHub
(
getUrl
)
import
Data.Aeson
(
FromJSON
)
import
Data.Aeson
(
FromJSON
)
import
Data.Aeson
(
FromJSON
)
class
ClientState
s
where
class
ClientState
s
where
getRefURL
getRefURL
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment