Skip to main content
Example scripts
arrow icon
To homepage
Bitbucket
Data centre icon
Data Center

Block Unwanted Files from Being Pushed

Features
Pre hooks
Tags
Created 1 year ago, Updated 3 month(s) ago
App in script
ScriptRunner For Bitbucket
ScriptRunner For Bitbucket
by Adaptavist
Compatibility
compatibility bullet
Bitbucket (6.0 - 7.17)
compatibility bullet
ScriptRunner For Bitbucket (7.10.0)
Language |
groovy
/**
 * Copyright © 2020, StoneX/Gain Capital.
 *
 * This script is released under the BSD 3-clause license: https://opensource.org/licenses/BSD-3-Clause
 *
 * Blocks all binaries in Bitbucket using template .gitignore
 */

import java.nio.file.FileSystems
import java.nio.file.PathMatcher

List<String> getTemplateIgnoreFileContents() {
    def file = new File('path/to/file/gitignore.template.txt')
    file.readLines()
}

Map<String, PathMatcher> getIgnoreMatchers(List<String> ignores) {
    def ignoreMatchers = [:]
    def fileSystem = FileSystems.default

    ignores.unique().any { ignore ->
        if (!(ignore ==~ /^\\s*#.*/)) {
            // We need to normalize some entries
            def newIgnore = ignore
            if (ignore.endsWith('/')) {
                newIgnore += '**'
            }
            if (ignore.startsWith('*.')) {
                newIgnore = '*' + ignore
            }
            def matcher = fileSystem.getPathMatcher("glob:" + newIgnore)
            ignoreMatchers.put(newIgnore, matcher)
        }
    }

    ignoreMatchers
}

try {
    def rejectedFiles = []
    def fileSystem = FileSystems.default
    def gitIgnore = templateIgnoreFileContents
    def matchers = getIgnoreMatchers(gitIgnore)
    def keySet = matchers.keySet()

    refChanges.any { refChange ->
        refChange.getChangesets(repository).each { changeset ->
            changeset.changes.values.each { change ->
                // We do not check for delete operations.
                if (change.type.toString() != 'DELETE') {
                    keySet.each { key ->
                        def filePath = fileSystem.getPath(change.path.toString())
                        def matcher = matchers[key]

                        if (matcher.matches(filePath)) {
                            rejectedFiles.add(changeset.toCommit.displayId + " contains binary " +
                                    change.path.toString() +
                                    " (" +
                                    change.type.toString() +
                                    ") " +
                                    "by " +
                                    changeset.toCommit.author.name +
                                    " in '" +
                                    repository.name +
                                    "' repository. " +
                                    "Blocked by gitignore rule " +
                                    key)
                        }
                    }
                }
            }
        }
    }

    if (rejectedFiles.size() > 0) {
        rejectedFiles.each { line ->
            hookResponse.out().println(line)
        }
        hookResponse.out().println('\n')
        hookResponse.out().println('Binaries are not allowed. See https://.../display/ABC/Binaries+control')
        return false
    }

    return true
}
catch (Exception ex) {
    log.error("Exception: ${ex}")
    return false
}
Having an issue with this script?
Report it here