Created
August 11, 2014 14:58
-
-
Save phillipuniverse/aa917db1cebca1615fb4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Description | |
# Look at versions for our various modules and how they relate to framework versions | |
# | |
# Dependencies: | |
# "octonode": "^0.6.4" | |
# "xml2js": "^0.4.4" | |
# | |
# Configuration: | |
# HUBOT_GITHUB_TOKEN - API token from a GitHub account | |
# | |
# Commands: | |
# versions for <module> - Searches GitHub for a repository with the name of <module> and replies with all of the version info about that module and how it relates to the framework. This will allow for some ambiguity as it uses the GitHub search API | |
# versions for exactly <module> - Same as the non-exact search but works on an exact repository name to reconcile ambiguity (like between 'Enterprise' and 'CommonEnterprise') | |
# | |
# | |
# Author: | |
# Phillip Verheyden (phillipuniverse) | |
api = require("octonode").client(process.env.HUBOT_GITHUB_TOKEN or 'unknown') | |
api.requestDefaults.headers['Accept'] = 'application/vnd.github.v3+json' | |
search = api.search() | |
{parseString} = require 'xml2js' | |
githubOrg = 'BroadleafCommerce' | |
frameworkArtifacts = ['broadleaf-admin-functional-tests', | |
'broadleaf-admin-module', | |
'broadleaf-common', | |
'broadleaf-contentmanagement-module', | |
'broadleaf-framework', | |
'broadleaf-framework-web' | |
'broadleaf-open-admin-platform', | |
'broadleaf-profile', | |
'broadleaf-profile-web'] | |
module.exports = (robot) -> | |
pattern = new RegExp('versions for(?: (exactly))? (.+)', 'i') | |
robot.hear pattern, (msg) -> | |
msg.send "Let me think about that for a sec" | |
exact = msg.match[1] | |
repoTerm = msg.match[2] | |
getRepo repoTerm, exact, robot, msg, (repo) -> | |
# Get all of the branches for this repository on GitHub | |
repo.branches (err, branches, headers) -> | |
for branch in branches | |
robot.logger.debug "Looking at pom on branch #{branch.name}" | |
# The do keyword is required to deal with the asynchronous execution of the subsequent callbacks | |
do (branch, frameworkArtifacts) -> | |
# get the root pom.xml and parse it | |
repo.contents 'pom.xml', branch.name, (err, data, headers) -> | |
if err | |
msg.reply err | |
else | |
# file data comes back from the GitHub API as a base64 encoded string, convert that into a valid UTF-8 string | |
xml = new Buffer(data.content, data.encoding).toString('utf8') | |
parseString xml, (err, result) -> | |
replied = false | |
# handle project -> dependenceyManagent version declarations | |
if result.project.dependencyManagement | |
replied = replyWithDependencies(result.project.dependencyManagement[0].dependencies, result.project, branch, msg) | |
# handle project -> dependencies version declarations if it wasn't in dependencyManagement | |
if not replied | |
replyWithDependencies(result.project.dependencies, result.project, branch, msg) | |
# For each declared dependency, figure out if this is a Broadleaf artifact dependency and reply | |
# | |
# Parameters: | |
# dependencies - (Single-element Array) a <dependencies> element in a pom.xml | |
# project - (Object) the project root of the pom.xml | |
# branch - (Object) the current branch that we are using | |
# msg - (Object) Hubot message object to send replies to | |
# | |
# Return: | |
# true if this method has responded via msg (indicating that version information was found), false otherwise | |
replyWithDependencies = (dependencies, project, branch, msg) -> | |
for dep in dependencies[0].dependency | |
if dep.artifactId.toString() in frameworkArtifacts | |
# the version string might actually be a variable. If so, look it up in the project | |
frameworkVersion = dep.version.toString() | |
if frameworkVersion.indexOf('$') != -1 | |
frameworkVersion = project.properties[0][frameworkVersion.replace /[${}]/g, ''] | |
msg.reply "Current version on the #{branch.name} branch is: #{project.version} targeting framework version #{frameworkVersion}" | |
return true | |
return false | |
# Executes the given 'callback' with a pre-initialized GitHub repo API object ready for querying | |
# Parameters: | |
# repoName - (String) the name of the repository to use | |
# exact - (boolean) whether or not we should treat repoName as the exact name of the repository or do a search for it | |
# robot - (Object) Hubot Robot instance for logging | |
# msg - (Object) Hubot message object used for sending replies | |
# callback - (function(repo)) callback to execute with a single parameter representing the GitHub repo API | |
getRepo = (repoName, exact, robot, msg, callback) -> | |
do (repoName) -> | |
if exact | |
# Assuming this is the exact repo name so try to look it UP | |
repo = api.repo("#{githubOrg}/#{repoName}") | |
do (repo) -> | |
repo.info (err, data, headers) -> | |
if err | |
msg.reply "Yeah... couldn't find a repository that exactly matches #{repoName} {Error code ID10T}" | |
else | |
callback(repo) | |
else | |
robot.logger.debug "Searching for #{repoName}" | |
# Search GitHub for repo names matching | |
search.repos { | |
q: "#{repoName}+in:name+user:#{githubOrg}", | |
sort: 'created', | |
order: 'asc' | |
}, (err, data, headers) -> | |
if err | |
robot.logger.debug JSON.stringify(err, null, 2) | |
msg.reply "There was an internal error searching for #{repoName} :(" | |
else | |
repos = data.items | |
robot.logger.debug "Successful results for #{repoName}, found #{repos.length} matches" | |
if repos.length == 0 | |
msg.reply "Couldn't find a repository for #{repoName} after searching for it on GitHub. Possible ID10T error." | |
else if repos.length > 1 | |
# deal with ambiguity | |
potentialNames = '' | |
for repo in repos | |
potentialNames += repo.name + ', ' | |
msg.reply "Too ambigous, retry with one of these: [#{potentialNames.substring(0, potentialNames.length - 2)}] or prefix the repo with 'exactly' in your message (like 'versions for exactly #{repoName}')" | |
else | |
# got a single result, instantiate a repo object and invoke the callback | |
path = repos[0].full_name | |
robot.logger.debug "Found a repo at #{path}" | |
msg.reply "Ok, gimme a sec to check the version info for #{path}" | |
callback(api.repo(path)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment