From f50b536d99cae402a604550a3493f111bab955da Mon Sep 17 00:00:00 2001 From: Teemu Suo-Anttila Date: Wed, 10 Jun 2015 13:45:09 +0300 Subject: [PATCH] Add python script for validating demos This patch refactors most of building logic from BuildArchetypes.py to BuildHelpers.py Change-Id: I34526db0cc2dba3b0dc6afddefa7559b5e75b87c --- scripts/BuildArchetypes.py | 153 +++++------------------------------ scripts/BuildDemos.py | 41 ++++++++++ scripts/BuildHelpers.py | 160 +++++++++++++++++++++++++++++++++++++ 3 files changed, 220 insertions(+), 134 deletions(-) create mode 100644 scripts/BuildDemos.py create mode 100644 scripts/BuildHelpers.py diff --git a/scripts/BuildArchetypes.py b/scripts/BuildArchetypes.py index 0218659f68..80dd745bfb 100644 --- a/scripts/BuildArchetypes.py +++ b/scripts/BuildArchetypes.py @@ -10,21 +10,14 @@ # python BuildArchetypes.py version fw-repo-id archetype-repo-id plugin-repo-id # -import platform, subprocess, sys, argparse -from xml.etree import ElementTree -from os.path import join, isdir, isfile, basename -from os import listdir, getcwd, mkdir -from glob import glob -from shutil import copy +import subprocess +from BuildHelpers import mavenValidate, copyWarFiles, repo, getLogFile, parseArgs, mavenCmd, updateRepositories ## DEFAULT VARIABLES ## # ArchetypeGroupId archetypeGroup = "com.vaadin" -# Staging repo base url -repo = "http://oss.sonatype.org/content/repositories/comvaadin-%d" - # List of built archetypes archetypes = [ "vaadin-archetype-widget", @@ -33,28 +26,25 @@ archetypes = [ "vaadin-archetype-application-multimodule" ] -# Directory where the resulting war files are stored -# TODO: deploy results -resultPath = "result" - # Maven GroupID group = "testpkg" +log = None +args = None + ## BUILDING METHODS ## # Generates and modifies a maven pom file -def buildArchetype(archetype): - global args, archetypeGroup, resultPath, group, mavenCmd - +def generateArchetype(archetype): artifactId = "test-%s-%s" % (archetype, args.version.replace(".", "-")) - logFile = open(join(resultPath, "%s.log" % (archetype)), 'w') - + # Generate the required command line for archetype generation cmd = [mavenCmd, "archetype:generate"] cmd.append("-DarchetypeGroupId=%s" % (archetypeGroup)) cmd.append("-DarchetypeArtifactId=%s" % (archetype)) cmd.append("-DarchetypeVersion=%s" % (args.version)) - cmd.append("-DarchetypeRepository=%s" % (repo % (args.archetype))) + if hasattr(args, "archetype") and args.archetype != None: + cmd.append("-DarchetypeRepository=%s" % (repo % (args.archetype))) cmd.append("-DgroupId=%s" % (group)) cmd.append("-DartifactId=%s" % (artifactId)) cmd.append("-Dversion=1.0-SNAPSHOT") @@ -62,123 +52,18 @@ def buildArchetype(archetype): # Generate pom.xml print("Generating pom.xml for archetype %s" % (archetype)) - subprocess.check_call(cmd, stdout=logFile) - - print("Add staging repositories to pom.xml") - updateRepositories(artifactId) - - print("Do maven clean package validate") - subprocess.check_call([mavenCmd, "clean", "package", "validate"], cwd=join(getcwd(), artifactId), stdout=logFile) + subprocess.check_call(cmd, stdout=log) - # Find resulting .war files - warFiles = glob(join(getcwd(), artifactId, "target", "*.war")) - warFiles.extend(glob(join(getcwd(), artifactId, "*", "target", "*.war"))) - for warFile in warFiles: - if len(warFiles) == 1: - deployName = "%s.war" % (archetype) - else: - deployName = "%s-%d" % (archetype, warFiles.index(warFile)) - print("Copying .war file %s as %s to result folder" % (basename(warFile), deployName)) - copy(warFile, join(resultPath, "%s" % (deployName))) - -# Recursive pom.xml update script -def updateRepositories(path): - global args, repo - - # Read pom.xml - pomXml = join(path, "pom.xml") - if isfile(pomXml): - # pom.xml namespace workaround - root = ElementTree.parse(pomXml).getroot() - nameSpace = root.tag[1:root.tag.index('}')] - ElementTree.register_namespace('', nameSpace) - - # Read the pom.xml correctly - tree = ElementTree.parse(pomXml) - - # NameSpace needed for finding the repositories node - repoNode = tree.getroot().find("{%s}repositories" % (nameSpace)) - else: - return - - if repoNode is not None: - # Add framework staging repository - addRepo(repoNode, "repository", "vaadin-%s-staging" % (args.version), repo % (args.framework)) - - # Find the correct pluginRepositories node - pluginRepo = tree.getroot().find("{%s}pluginRepositories" % (nameSpace)) - if pluginRepo is None: - # Add pluginRepositories node if needed - pluginRepo = ElementTree.SubElement(tree.getroot(), "pluginRepositories") - - # Add plugin staging repository - addRepo(pluginRepo, "pluginRepository", "vaadin-%s-plugin-staging" % (args.version), repo % (args.plugin)) - - # Overwrite the modified pom.xml - tree.write(pomXml, encoding='UTF-8') - - # Recursive pom.xml search. - for i in listdir(path): - file = join(path, i) - if isdir(file): - updateRepositories(join(path, i)) - -# Add a repository of repoType to given repoNode with id and URL -def addRepo(repoNode, repoType, id, url): - newRepo = ElementTree.SubElement(repoNode, repoType) - idElem = ElementTree.SubElement(newRepo, "id") - idElem.text = id - urlElem = ElementTree.SubElement(newRepo, "url") - urlElem.text = url - -# Function for determining the path for maven executable -def getMavenCommand(): - # This method uses .split("\n")[0] which basically chooses the first result where/which returns. - # Fixes the case with multiple maven installations available on PATH - if platform.system() == "Windows": - try: - return subprocess.check_output(["where", "mvn.cmd"], universal_newlines=True).split("\n")[0] - except: - try: - return subprocess.check_output(["where", "mvn.bat"], universal_newlines=True).split("\n")[0] - except: - print("Unable to locate mvn with where. Is the maven executable in your PATH?") - else: - try: - return subprocess.check_output(["which", "mvn"], universal_newlines=True).split("\n")[0] - except: - print("Unable to locate maven executable with which. Is the maven executable in your PATH?") - return None + # Return the artifactId so we know the name in the future + return artifactId ## DO THIS IF RUN AS A SCRIPT (not import) ## if __name__ == "__main__": - mavenCmd = getMavenCommand() - if mavenCmd is None: - sys.exit(1) + args = parseArgs() + for archetype in archetypes: + log = getLogFile(archetype) + artifactId = generateArchetype(archetype) + updateRepositories(artifactId) + mavenValidate(artifactId, logFile=log) + copyWarFiles(artifactId, name=archetype) - # Command line arguments for this script - parser = argparse.ArgumentParser(description="Automated staging validation") - parser.add_argument("version", type=str, help="Vaadin version to use") - parser.add_argument("framework", type=int, help="Framework repo id (comvaadin-XXXX)") - parser.add_argument("archetype", type=int, help="Archetype repo id (comvaadin-XXXX)") - parser.add_argument("plugin", type=int, help="Maven Plugin repo id (comvaadin-XXXX)") - - # If no args, give help - if len(sys.argv) == 1: - args = parser.parse_args(["-h"]) - else: - args = parser.parse_args() - - # Argument parsing error. - if hasattr(args, "echo"): - print(args.echo) - exit(1) - - # Create the result folder - if not isdir(resultPath): - mkdir(resultPath) - - # TODO: Clean up old builds ? - - for a in archetypes: - buildArchetype(a) diff --git a/scripts/BuildDemos.py b/scripts/BuildDemos.py new file mode 100644 index 0000000000..f9f2ed1b48 --- /dev/null +++ b/scripts/BuildDemos.py @@ -0,0 +1,41 @@ +#coding=UTF-8 + +# See BuildArchetypes for details on environment +# BuildDemos needs git in PATH and depends on gitpython library +# gitpython can be installed with python installer script "pip": +# pip install gitpython + +from git import Repo +from BuildHelpers import updateRepositories, mavenValidate, copyWarFiles, VersionObject, getLogFile, parseArgs + +## Example of a non-staging test. +#version = VersionObject() +#version.version = "7.4.8" + +# Uncomment lines before this, and comment following line to make a non-staging test +version = None + +demos = { + "dashboard" : "https://github.com/vaadin/dashboard-demo.git", + "parking" : "https://github.com/vaadin/parking-demo.git", + "addressbook" : "https://github.com/vaadin/addressbook.git", + "confirmdialog" : "https://github.com/samie/Vaadin-ConfirmDialog.git" +} + +def checkout(folder, url): + Repo.clone_from(url, folder) + +if __name__ == "__main__": + if version is None: + version = parseArgs() + for demo in demos: + print("Validating demo %s" % (demo)) + try: + checkout(demo, demos[demo]) + updateRepositories(demo, repoIds = version) + mavenValidate(demo, repoIds = version, logFile = getLogFile(demo)) + copyWarFiles(demo) + print("%s demo validation succeeded!" % (demo)) + except: + print("%s demo validation failed" % (demo)) + print("") diff --git a/scripts/BuildHelpers.py b/scripts/BuildHelpers.py new file mode 100644 index 0000000000..be21c0f721 --- /dev/null +++ b/scripts/BuildHelpers.py @@ -0,0 +1,160 @@ +#coding=UTF-8 + +## Collection of helpers for Build scripts ## + +import sys, argparse, subprocess, platform +from xml.etree import ElementTree +from os.path import join, isdir, isfile, basename, exists +from os import listdir, getcwd, mkdir +from shutil import copy +from glob import glob + +class VersionObject(object): + pass + +# Staging repo base url +repo = "http://oss.sonatype.org/content/repositories/comvaadin-%d" + +# Directory where the resulting war files are stored +# TODO: deploy results +resultPath = "result" + +if not exists(resultPath): + mkdir(resultPath) +elif not isdir(resultPath): + print("Result path is not a directory.") + sys.exit(1) + +args = None + +# Parse command line arguments +def parseArgs(): + # Command line arguments for this script + parser = argparse.ArgumentParser(description="Automated staging validation") + parser.add_argument("version", type=str, help="Vaadin version to use") + parser.add_argument("framework", type=int, help="Framework repo id (comvaadin-XXXX)", nargs='?') + parser.add_argument("archetype", type=int, help="Archetype repo id (comvaadin-XXXX)", nargs='?') + parser.add_argument("plugin", type=int, help="Maven Plugin repo id (comvaadin-XXXX)", nargs='?') + + # If no args, give help + if len(sys.argv) == 1: + args = parser.parse_args(["-h"]) + else: + args = parser.parse_args() + + return args + +# Function for determining the path for maven executable +def getMavenCommand(): + # This method uses .split("\n")[0] which basically chooses the first result where/which returns. + # Fixes the case with multiple maven installations available on PATH + if platform.system() == "Windows": + try: + return subprocess.check_output(["where", "mvn.cmd"], universal_newlines=True).split("\n")[0] + except: + try: + return subprocess.check_output(["where", "mvn.bat"], universal_newlines=True).split("\n")[0] + except: + print("Unable to locate mvn with where. Is the maven executable in your PATH?") + else: + try: + return subprocess.check_output(["which", "mvn"], universal_newlines=True).split("\n")[0] + except: + print("Unable to locate maven executable with which. Is the maven executable in your PATH?") + return None + +mavenCmd = getMavenCommand() + +# Get command line arguments. Parses arguments if needed. +def getArgs(): + global args + if args is None: + args = parseArgs() + return args + +# Maven Package and Validation +def mavenValidate(artifactId, mvnCmd = mavenCmd, logFile = sys.stdout, repoIds = None): + if repoIds is None: + repoIds = getArgs() + + print("Do maven clean package validate") + cmd = [mvnCmd] + if hasattr(repoIds, "version") and repoIds.version is not None: + cmd.append("-Dvaadin.version=%s" % (repoIds.version)) + cmd.extend(["clean", "package", "validate"]) + print("executing: %s" % (" ".join(cmd))) + subprocess.check_call(cmd, cwd=join(getcwd(), artifactId), stdout=logFile) + +# Collect .war files to given folder with given naming +def copyWarFiles(artifactId, resultDir = resultPath, name = None): + if name is None: + name = artifactId + warFiles = glob(join(getcwd(), artifactId, "target", "*.war")) + warFiles.extend(glob(join(getcwd(), artifactId, "*", "target", "*.war"))) + for warFile in warFiles: + if len(warFiles) == 1: + deployName = "%s.war" % (name) + else: + deployName = "%s-%d.war" % (name, warFiles.index(warFile)) + print("Copying .war file %s as %s to result folder" % (basename(warFile), deployName)) + copy(warFile, join(resultDir, "%s" % (deployName))) + +# Recursive pom.xml update script +def updateRepositories(path, repoIds = None, repoUrl = repo): + # If versions are not supplied, parse arguments + if repoIds is None: + repoIds = getArgs() + + # Read pom.xml + pomXml = join(path, "pom.xml") + if isfile(pomXml): + # pom.xml namespace workaround + root = ElementTree.parse(pomXml).getroot() + nameSpace = root.tag[1:root.tag.index('}')] + ElementTree.register_namespace('', nameSpace) + + # Read the pom.xml correctly + tree = ElementTree.parse(pomXml) + + # NameSpace needed for finding the repositories node + repoNode = tree.getroot().find("{%s}repositories" % (nameSpace)) + else: + return + + if repoNode is not None: + print("Add staging repositories to " + pomXml) + + if hasattr(repoIds, "framework") and repoIds.framework is not None: + # Add framework staging repository + addRepo(repoNode, "repository", "vaadin-%s-staging" % (repoIds.version), repoUrl % (repoIds.framework)) + + # Find the correct pluginRepositories node + pluginRepo = tree.getroot().find("{%s}pluginRepositories" % (nameSpace)) + if pluginRepo is None: + # Add pluginRepositories node if needed + pluginRepo = ElementTree.SubElement(tree.getroot(), "pluginRepositories") + + if hasattr(repoIds, "plugin") and repoIds.plugin is not None: + # Add plugin staging repository + addRepo(pluginRepo, "pluginRepository", "vaadin-%s-plugin-staging" % (repoIds.version), repoUrl % (repoIds.plugin)) + + # Overwrite the modified pom.xml + tree.write(pomXml, encoding='UTF-8') + + # Recursive pom.xml search. + for i in listdir(path): + file = join(path, i) + if isdir(file): + updateRepositories(join(path, i), repoIds, repoUrl) + +# Add a repository of repoType to given repoNode with id and URL +def addRepo(repoNode, repoType, id, url): + newRepo = ElementTree.SubElement(repoNode, repoType) + idElem = ElementTree.SubElement(newRepo, "id") + idElem.text = id + urlElem = ElementTree.SubElement(newRepo, "url") + urlElem.text = url + +# Get a logfile for given artifact +def getLogFile(artifact, resultDir = resultPath): + return open(join(resultDir, "%s.log" % (artifact)), 'w') -- 2.39.5