This patch refactors most of building logic from BuildArchetypes.py to BuildHelpers.py Change-Id: I34526db0cc2dba3b0dc6afddefa7559b5e75b87ctags/7.6.0.alpha2
# python BuildArchetypes.py version fw-repo-id archetype-repo-id plugin-repo-id | # 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 ## | ## DEFAULT VARIABLES ## | ||||
# ArchetypeGroupId | # ArchetypeGroupId | ||||
archetypeGroup = "com.vaadin" | archetypeGroup = "com.vaadin" | ||||
# Staging repo base url | |||||
repo = "http://oss.sonatype.org/content/repositories/comvaadin-%d" | |||||
# List of built archetypes | # List of built archetypes | ||||
archetypes = [ | archetypes = [ | ||||
"vaadin-archetype-widget", | "vaadin-archetype-widget", | ||||
"vaadin-archetype-application-multimodule" | "vaadin-archetype-application-multimodule" | ||||
] | ] | ||||
# Directory where the resulting war files are stored | |||||
# TODO: deploy results | |||||
resultPath = "result" | |||||
# Maven GroupID | # Maven GroupID | ||||
group = "testpkg" | group = "testpkg" | ||||
log = None | |||||
args = None | |||||
## BUILDING METHODS ## | ## BUILDING METHODS ## | ||||
# Generates and modifies a maven pom file | # 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(".", "-")) | artifactId = "test-%s-%s" % (archetype, args.version.replace(".", "-")) | ||||
logFile = open(join(resultPath, "%s.log" % (archetype)), 'w') | |||||
# Generate the required command line for archetype generation | # Generate the required command line for archetype generation | ||||
cmd = [mavenCmd, "archetype:generate"] | cmd = [mavenCmd, "archetype:generate"] | ||||
cmd.append("-DarchetypeGroupId=%s" % (archetypeGroup)) | cmd.append("-DarchetypeGroupId=%s" % (archetypeGroup)) | ||||
cmd.append("-DarchetypeArtifactId=%s" % (archetype)) | cmd.append("-DarchetypeArtifactId=%s" % (archetype)) | ||||
cmd.append("-DarchetypeVersion=%s" % (args.version)) | 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("-DgroupId=%s" % (group)) | ||||
cmd.append("-DartifactId=%s" % (artifactId)) | cmd.append("-DartifactId=%s" % (artifactId)) | ||||
cmd.append("-Dversion=1.0-SNAPSHOT") | cmd.append("-Dversion=1.0-SNAPSHOT") | ||||
# Generate pom.xml | # Generate pom.xml | ||||
print("Generating pom.xml for archetype %s" % (archetype)) | 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) ## | ## DO THIS IF RUN AS A SCRIPT (not import) ## | ||||
if __name__ == "__main__": | 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) |
#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("") |
#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 <version> <framework-repo-id> <archetype-repo-id> <plugin-repo-id> | |||||
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') |