Snippets

Adaptavist Ahead Behind Report Stash

Created by Jamie Echlin

File AheadBehindReport.groovy Added

  • Ignore whitespace
  • Hide word diff
+package examples.stash
+
+import com.atlassian.plugin.PluginAccessor
+import com.atlassian.sal.api.component.ComponentLocator
+import com.atlassian.stash.commit.CommitService
+import com.atlassian.stash.internal.branch.LatestChangesetMetadataProvider
+import com.atlassian.stash.internal.branch.list.aheadbehind.AheadBehindRefMetadataProvider
+import com.atlassian.stash.repository.*
+import com.atlassian.stash.scm.ScmService
+import com.atlassian.stash.scm.git.GitCommandBuilderFactory
+import com.atlassian.stash.util.Page
+import com.atlassian.stash.util.PageProvider
+import com.atlassian.stash.util.PageRequest
+import com.atlassian.stash.util.PagedIterable
+import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
+import com.onresolve.scriptrunner.runner.customisers.WithPlugin
+import groovy.transform.Canonical
+import groovy.util.logging.Log4j
+
+@Log4j(category = "com.onresolve.examples")
+@WithPlugin("com.atlassian.stash.stash-branch-utils")
+class AheadBehindReport extends Script {
+
+    def scmService = ComponentLocator.getComponent(ScmService)
+    def repositoryService = ComponentLocator.getComponent(RepositoryService)
+    def repositoryMetadataService = ComponentLocator.getComponent(RepositoryMetadataService)
+    def pluginAccessor = ComponentLocator.getComponent(PluginAccessor)
+    def gitCommandBuilderFactory = pluginAccessor.getEnabledPluginModule(ScriptRunnerImpl.PLUGIN_KEY + ":gitCmdBuilderFactory").getModule() as GitCommandBuilderFactory
+
+    /*
+    Modify these three lines
+     */
+    def projectKey = "SR"
+    def repoSlug = "sr"
+
+    // this is what you are comparing your branches to, to see if they are ahead/behind
+    def baseRefName = "master"
+
+    @Override
+    Object run() {
+
+        def repository = repositoryService.getBySlug(projectKey, repoSlug)
+        def baseRef = repositoryMetadataService.resolveRef(repository, baseRefName)
+        def builder = new RepositoryBranchesRequest.Builder().repository(repository).build()
+
+        def branches = new PagedIterable<Branch>(new PageProvider<Branch>() {
+            @Override
+            Page<Branch> get(PageRequest pageRequest) {
+                repositoryMetadataService.getBranches(builder, pageRequest)
+            }
+        }, PageRequest.MAX_PAGE_LIMIT).findAll {
+            it.displayId != baseRefName
+        }
+
+        def refs =  branches as Set<Ref>
+        def latestChangesetMetadataProvider = new LatestChangesetMetadataProvider(scmService)
+        def latestChangesetData = latestChangesetMetadataProvider.getMetadata(new RefMetadataContextImpl(baseRef, refs, repository))
+        def aheadBehindRefMetadataProvider = new AheadBehindRefMetadataProvider(ComponentLocator.getComponent(CommitService))
+        def metadata = aheadBehindRefMetadataProvider.getMetadata(new RefMetadataContextImpl(baseRef, refs, repository))
+
+        def mergedBranches = metadata.findAll { ref, aheadBehindCount ->
+            aheadBehindCount.ahead == 0 && aheadBehindCount.behind > 0
+        }
+
+        mergedBranches.keySet().each { ref ->
+            log.warn("delete: ${ref.displayId}, last modified: ${latestChangesetData[ref].authorTimestamp.format("dd/MMM/yy")}")
+
+            // uncomment this line to remove the branch
+            // gitCommandBuilderFactory.builder(repository).branch().delete(ref.displayId).build().call()
+        }
+
+        // look for branches without a pull request for which the last commit was greater than six weeks ago
+        Calendar cal = Calendar.getInstance()
+        cal.add(Calendar.DAY_OF_YEAR, -42)
+
+        metadata.findAll { ref, aheadBehindCount ->
+            aheadBehindCount.ahead > 0 &&
+                aheadBehindCount.behind > 0 &&
+                latestChangesetData[ref].authorTimestamp < cal.getTime()
+        }.sort {
+            latestChangesetData[it.key].authorTimestamp
+        }.each { ref, aheadBehindCount ->
+            log.warn("Old branch: ${ref.displayId}, behind: ${latestChangesetData[ref].authorTimestamp.format("dd/MMM/yy")}")
+        }
+    }
+}
+
+@Canonical
+class RefMetadataContextImpl implements RefMetadataContext {
+    Ref baseRef
+    Set<Ref> refs
+    Repository repository
+}
HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.