#!/usr/bin/env python """ Copyright 2018-present Open Networking Foundation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ ##### Templates for features.xml FEATURES_HEADER = '''\ ''' FEATURE_HEADER= '''\ ''' EXISTING_FEATURE = ' %s\n' BUNDLE = ' %s\n' FEATURE_FOOTER = ' \n' FEATURES_FOOTER = '\n' ##### Templates for app.xml APP_HEADER = '''\ %(description)s ''' ARTIFACT = ' %s\n' SECURITY = '''\ %s \n''' APP_FOOTER = '\n' NON_OSGI_TAG = 'NON-OSGI' def mvnUrl(bundle): #mvn-uri := 'mvn:' [ repository-url '!' ] group-id '/' artifact-id [ '/' [version] [ '/' [type] [ '/' classifier ] ] ] ] parts = bundle.split(':')[1:] prefix = 'mvn:' suffix = '' if len(parts) > 3: parts.insert(2, parts.pop()) # move version to the 3rd position if len(parts) >= 5: # check classifier for special non-OSGi tag i = parts[4].find(NON_OSGI_TAG) if i == 0: prefix = 'wrap:' + prefix suffix = '$Bundle-SymbolicName=%s.%s&Bundle-Version=%s' % tuple(parts[0:3]) if len(parts[4]) == len(NON_OSGI_TAG): parts.pop() # pop off empty classifier if parts[3].lower() == 'jar': parts.pop() # pop off default extension: jar else: parts[4] = parts[4][len(NON_OSGI_TAG):] return prefix + '/'.join(parts) + suffix def generateFeatureFile(feature_repo_name, features = [], **kwargs): values = { 'feature_repo_name' : '-'.join(feature_repo_name.split(':')[1:3]), } output = FEATURES_HEADER % values for feature in features: output += feature output += FEATURES_FOOTER return output def generateFeature(feature_name, version, title, features = [], bundles = [], **kwargs): values = { 'feature_name' : feature_name, 'version' : version, 'title' : title, } output = FEATURE_HEADER % values if features: for feature in features: output += EXISTING_FEATURE % feature if bundles: for bundle in bundles: output += BUNDLE % mvnUrl(bundle) output += FEATURE_FOOTER return output def generateAppFile(app_name, origin, version, title, category, url, feature_repo_name, feature_name, description = None, apps = [], artifacts = [], security= None, **kwargs): values = { 'app_name' : app_name, 'origin' : origin, 'version' : version, 'title' : title, 'category' : category, 'url' : url, 'feature_repo_name' : mvnUrl(feature_repo_name) + '/xml/features', 'feature_name' : feature_name, } values['description'] = description if description else title values['apps'] = ','.join(apps) if apps else '' output = APP_HEADER % values for artifact in artifacts: output += ARTIFACT % mvnUrl(artifact) if security is not None: output += SECURITY % security output += APP_FOOTER return output def write(name, msg): if name is not None: with open(name, "w") as file: file.write(msg) else: print(msg) if __name__ == '__main__': import sys, optparse parser = optparse.OptionParser() parser.add_option("-O", "--output", dest="output", help="Output file") parser.add_option("-n", "--name", dest="feature_coords", help="Feature MVN Coords") parser.add_option("-a", "--app", dest="app_name", help="App Name") parser.add_option("-o", "--origin", dest="origin", help="Origin") parser.add_option("-c", "--category", dest="category", help="Category") parser.add_option("-u", "--url", dest="url", help="URL") parser.add_option("-v", "--version", dest="version", help="Version") parser.add_option("-t", "--title", dest="title", help="Title") parser.add_option("-r", "--repo", dest="repo_name", help="Repo Name") parser.add_option('-D', '--desc', dest='desc', help='Application description') parser.add_option('-s', '--security', dest='security', help='Application security') parser.add_option('-b', '--bundle', action="append", dest='included_bundles', metavar="BUNDLE", help='Included Bundle (multiple allowed)') parser.add_option('-e', '--excluded-bundle', action="append", dest='excluded_bundles', metavar="BUNDLE", help='Excluded Bundle (multiple allowed)') parser.add_option('-f', '--feature', action="append", dest='features', metavar="FEATURE", help='Existing Feature (multiple allowed)') parser.add_option('-d', '--apps', action="append", dest='apps', metavar="FEATURE", help='Required App (multiple allowed)') parser.add_option("-A", "--write-app", dest="write_app", action="store_true") parser.add_option("-F", "--write-features", dest="write_features", action="store_true") parser.add_option("-E", "--write-feature", dest="write_feature", action="store_true") (options, args) = parser.parse_args() values = {} if options.feature_coords and options.version and options.title: parts = options.feature_coords.split(':') values['feature_name'] = parts[2] if len(parts) > 2 else parts[0] values['version'] = options.version values['title'] = options.title else: sys.stderr.write('ERROR: Feature Name, Version, and Title are required\n') sys.stderr.flush() sys.exit(1) if options.app_name and options.origin and options.category and options.url: values['app_name'] = options.app_name values['origin'] = options.origin values['category'] = options.category values['url'] = options.url elif options.write_app: sys.stderr.write('ERROR: Feature Name, Version, and Title are required\n') sys.stderr.flush() sys.exit(1) values['feature_repo_name'] = options.repo_name if options.repo_name \ else options.feature_coords bundles = [] if options.included_bundles: bundles += options.included_bundles if options.excluded_bundles: bundles += options.excluded_bundles if options.desc: values['description'] = options.desc feature = generateFeature(bundles=bundles, features=options.features, **values) if options.write_feature: write(options.output, feature) if options.write_features: write(options.output, generateFeatureFile(features=[ feature ], **values)) if options.write_app: write(options.output, generateAppFile(artifacts=options.included_bundles, apps=options.apps, security=options.security, **values))