I'm trying to implement a pre-receive hook in Bitbucket Server using the Custom Script Hook feature. I'm not the most savvy with Groovy, but I was fairly sure I'd got the syntax right. However, on trying to add the hook it gives the error:
[Static type checking] - Cannot find matching method com.atlassian.bitbucket.content.ContentServce#streamFile
import com.atlassian.sal.api.component.ComponentLocator import com.atlassian.bitbucket.hook.HookResponse import com.atlassian.bitbucket.repository.RefChange import com.atlassian.bitbucket.repository.Repository import com.atlassian.bitbucket.content.ContentService import com.atlassian.bitbucket.content.FileContentCallback if(repository.getProject().getName() == "Constellation" && repository.getName() == "apollo" && refChanges.pathsMatch('glob:apollo/ui/**')) { def contentService = ComponentLocator.getComponent(ContentService) def filePath = "apollo/ui/dist/js/app.js" def searchFragment = "WSURL=window.location.hostname" def fragmentFound = false contentService.streamFile(repository, refChanges.first().getToHash(), filePath, new FileContentCallback() { @Override boolean onLine(int lineNumber, String line, boolean truncated) throws IOException { if(line.toLowerCase().contains(searchFragment.toLowerCase())) fragmentFound = true return true; } }); if(!fragmentFound) { //reject push with note hookResponse.out().print("Push rejected!\nAre you sure you ran `npm run build`?\n\n") return true } else { //allow push return false } }
I've imported ContentService and it does seem to recognize ContentService when obtained with ComponentLocator. So why doesn't it recognize the streamFile method?
Any other comments on my code are welcome as well. The purpose of the pre-receive hook is to only accept pushes that have edits to files in a certain folder if a specific file has a certain substring. The API seems to say that ContentService.streamFile is the correct method to read a whole source file, as opposed to just reading changes from a given commit.
Thanks in advance!
Community moderators have prevented the ability to post new answers.
Theres a siimilar question here regarding reading files in a repository using ScriptRunner: https://answers.atlassian.com/questions/39450211
Your code should look like this:
import com.atlassian.bitbucket.content.ContentService import com.atlassian.bitbucket.io.TypeAwareOutputSupplier import com.atlassian.sal.api.component.ComponentLocator import javax.annotation.Nonnull import java.nio.charset.StandardCharsets if(repository.getProject().getName() == "Constellation" && repository.getName() == "apollo" && refChanges.pathsMatch('glob:apollo/ui/**')) { def contentService = ComponentLocator.getComponent(ContentService) def filePath = "apollo/ui/dist/js/app.js" def searchFragment = "WSURL=window.location.hostname" def supplier = new ByteArrayStreamOutputSupplier() contentService.streamFile(repository, refChanges.first().getToHash(), filePath, supplier) supplier.stream.close() // convert byte array to UTF-8 encoded string which has the file contents def content = new String(supplier.baos.toByteArray(), StandardCharsets.UTF_8) // process each line in the content def fragmentFound = content.readLines().any { line -> line.toLowerCase().contains(searchFragment.toLowerCase()) } if(!fragmentFound) { //reject push with note hookResponse.out().print("Push rejected!\nAre you sure you ran `npm run build`?\n\n") return false } } return true class ByteArrayStreamOutputSupplier implements TypeAwareOutputSupplier { ByteArrayOutputStream baos BufferedOutputStream stream ByteArrayStreamOutputSupplier() { this.baos = new ByteArrayOutputStream() this.stream = new BufferedOutputStream(baos) } @Override OutputStream getStream(@Nonnull String contentType) throws IOException { stream } }
Issues I can see are:
You'll see a static type checking error in the inline code editor but its safe to ignore, it just can't work out where the pathsMatch method comes from, which is one ScriptRunner provides.
For future reference if you tag your question with: com.onresolve.jira.stash.groovyrunner its easier for us to respond and means your question will be found by the right person.
Thanks for the response! I'll try out your changes and see if they work. The misspelled error message was my bad, not related to the code.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.