import logging
+import subprocess
import sys
import click
from requests.exceptions import HTTPError
import lftools.deploy as deploy_sys
-from lftools.nexus import cmd as nexuscmd
log = logging.getLogger(__name__)
@click.argument('nexus-url', envvar='NEXUS_URL')
@click.argument('repo-id', envvar='REPO_ID')
@click.argument('file-name', envvar='FILE_NAME')
+# Maven Config
+@click.option('-b', '--maven-bin', envvar='MAVEN_BIN',
+ help='Path of maven binary.')
+@click.option('-gs', '--global-settings', envvar='GLOBAL_SETTINGS_FILE',
+ help='Global settings file.')
+@click.option('-s', '--settings', envvar='SETTINGS_FILE',
+ help='Settings file.')
+@click.option('-p', '--maven-params',
+ help='Pass Maven commandline options to the mvn command.')
# Maven Artifact GAV
@click.option('-a', '--artifact-id',
help='Maven Artifact ID.')
help='Pom file to extract GAV information from.')
@click.option('-g', '--group-id',
help='Maven Group ID')
-@click.option('-p', '--packaging',
- help='File packaging type.')
@click.option('-v', '--version',
help='Maven artifact version.')
@click.pass_context
def maven_file(
+ # Maven Config
ctx, nexus_url, repo_id, file_name,
+ maven_bin, global_settings, settings,
+ maven_params,
# Maven GAV
- artifact_id, group_id, classifier, packaging, version,
+ artifact_id, group_id, classifier, version,
pom_file):
"""Deploy a file to a Nexus maven2 repository.
- Uses the local .netrc file for authorization.
+ As this script uses mvn to deploy. The server configuration should be
+ configured in your local settings.xml. By default the script uses the
+ mvn default "~/.m2/settings.xml" for the configuration but this can be
+ overrided in the following order:
+
+ \b
+ 1. Passed through CLI option "-s" ("-gs" for global-settings)
+ 2. Environment variable "$SETTINGS_FILE" ("$GLOBAL_SETTINGS_FILE" for global-settings)
+ 3. Maven default "~/.m2/settings.xml".
If pom-file is passed in via the "-f" option then the Maven GAV parameters
are not necessary. pom-file setting overrides the Maven GAV parameters.
"""
- try:
- nexuscmd.deploy_maven_file(nexus_url, repo_id, file_name, pom_file,
- group_id, artifact_id, packaging, version,
- classifier)
- except HTTPError as e:
- log.error(str(e))
- sys.exit(1)
+ params = ['deploy', 'maven-file']
+
+ # Maven Configuration
+ if maven_bin:
+ params.extend(["-b", maven_bin])
+ if global_settings:
+ params.extend(["-l", global_settings])
+ if settings:
+ params.extend(["-s", settings])
+ if maven_params:
+ params.extend(["-p", maven_params])
+
+ # Maven Artifact GAV
+ if artifact_id:
+ params.extend(["-a", artifact_id])
+ if classifier:
+ params.extend(["-c", classifier])
+ if group_id:
+ params.extend(["-g", group_id])
+ if pom_file:
+ params.extend(["-f", pom_file])
+ if version:
+ params.extend(["-v", version])
+
+ # Set required variables last as getopts get's processed first.
+ params.extend([nexus_url, repo_id, file_name])
+
+ status = subprocess.call(params)
+ sys.exit(status)
@click.command()
_nexus.delete_image(image)
-def deploy_maven_file(nexus_url, nexus_repo_id, file_name, pom_file="",
- group_id="", artifact_id="", packaging="", version="",
- classifier=""):
- """Deploy a file to a Nexus maven2 repository.
-
- :arg str nexus_url: URL of target Nexus server.
- :arg str nexus_repo_id: Name of target Nexus repo.
- :arg str file_name: Path to file that will be uploaded to Nexus.
- :arg str pom_file: Optional path to POM file containing package info.
- :arg str group_id: The artifact's groupId. Necessary if no pom is provided.
- :arg str artifact_id: The artifact's artifactId. Necessary if no pom is
- provided.
- :arg str packaging: The artifact's packaging scheme. If not provided, this
- will be guessed based on the file's extension.
- :arg str version: The artifact's version. Necessary if no pom is provided.
- :arg str classifier: Optional Nexus classifier for the artifact.
- """
- _nexus = Nexus(nexus_url)
-
- if pom_file:
- files = [
- ('file', (pom_file, open(pom_file, 'rb'))),
- ('file', (file_name, open(file_name, 'rb')))
- ]
- log.debug("Files: {}".format(files))
-
- data = {
- 'r': (None, nexus_repo_id),
- 'hasPom': (None, 'true')
- }
- log.debug("Data: {}".format(data))
-
- request_url = "{}/artifact/maven/content".format(_nexus.baseurl)
- response = requests.post(request_url, data=data, files=files)
-
- else:
- packaging = util.find_packaging_from_file_name(file_name)
- log.debug("Packaging found: {}".format(packaging))
-
- info_dict = {}
- if packaging == "rpm":
- info_dict = util.get_info_from_rpm(file_name)
- elif packaging == "deb":
- info_dict = util.get_info_from_deb(file_name)
- if info_dict and not artifact_id:
- artifact_id = info_dict["name"]
- if info_dict and not version:
- version = info_dict["version"]
-
- data = {
- 'r': (None, nexus_repo_id),
- 'p': (None, packaging),
- 'hasPom': (None, 'false')
- }
-
- files = {
- 'file': (file_name, open(file_name, 'rb'))
- }
- log.debug("Files: {}".format(files))
-
- if group_id:
- data['g'] = (None, group_id)
- if artifact_id:
- data['a'] = (None, artifact_id)
- if version:
- data['v'] = (None, version)
- if classifier:
- data['c'] = (None, classifier)
- log.debug("Data: {}".format(data))
-
- request_url = "{}/artifact/maven/content".format(_nexus.baseurl)
- log.debug("Request URL: {}".format(request_url))
- response = requests.post(request_url, data=data, files=files)
-
- if response.status_code != 201:
- raise requests.HTTPError("Upload failed with the following "
- "error:\n{}: {}".format(response.status_code,
- response.text))
- else:
- log.debug("Successfully uploaded {} to {}".format(file_name,
- request_url))
-
-
def release_staging_repos(repos, nexus_url=""):
"""Release one or more staging repos.
__author__ = 'Thanh Ha'
import logging
-import re
-import sys
-
-from deb_pkg_tools.package import inspect_package_fields
-import rpmfile
log = logging.getLogger(__name__)
def create_repo_target_regex(group_id):
"""Create a repo_target for Nexus use."""
return '^/{}/.*'.format(group_id.replace('.', '[/\.]'))
-
-
-def find_packaging_from_file_name(file_name):
- """Find packaging type based on file extension."""
- if file_name.endswith(".tar.gz"):
- packaging = "tar.gz"
- else:
- ext_index = file_name.rfind(".")
- if ext_index == -1:
- log.error("ERROR: Could not determine packaging type. Please "
- "provide an appropriate \"packaging\" parameter.")
- sys.exit(1)
- packaging = file_name[ext_index+1:]
- return packaging
-
-
-def get_info_from_rpm(path):
- """Return data pulled from the headers of an RPM file."""
- info = {}
- rpm = rpmfile.open(path)
- info["name"] = rpm.headers.get("name")
- ver = rpm.headers.get("version")
- if re.search('\.s(rc\.)?rpm', path):
- info["version"] = "{}.{}".format(ver, "src")
- else:
- info["version"] = "{}.{}".format(ver, rpm.headers.get("arch"))
- log.debug("Info from rpm: {}".format(info))
- return info
-
-
-def get_info_from_deb(path):
- """Return data pulled from a deb archive."""
- info = {}
- data = inspect_package_fields(path)
- info["name"] = data["Package"]
- info["version"] = data["Version"]
- log.debug("Info from deb: {}".format(info))
- return info
+++ /dev/null
----
-features:
- - |
- Refactored deploy_maven_file() function from shell/deploy to pure Python to
- be more portable with Windows systems.
-upgrade:
- - |
- The ``deploy maven-file`` command no longer calls maven (relying instead on
- a direct REST call to Nexus). Due to this change, the following options
- have been removed:
-
- * ``-b|--maven-bin``
- * ``-gs|--global-settings``
- * ``-s|--settings``
- * ``-p|--maven-params``
-
- Additionally, the NEXUS_URL argument should now contain only the base URL
- for the Nexus server being used, rather than the full path to the remote
- repository.
-
- Any calls to this command should be updated to reflect the above changes.
- Nexus credentials should be located in the local .netrc file.
-deprecations:
- - |
- ``shell/deploy`` script's deploy_maven_file() function is now deprecated
- and will be removed in a future release.
click
docker
glob2 # Needed for Python < 3.5 recursive glob support
-deb-pkg-tools~=5.2
defusedxml # Needed due to tox complains on parseString not safe
jsonschema~=2.6.0
requests>=2.20.0
-rpmfile~=0.1.4
ruamel.yaml
setuptools>=36.5.0
six~=1.11.0
#Execute test, should not return anything for successful run.
deploy_sys.deploy_nexus_stage (url, staging_profile_id, deploy_dir)
-
-
-@pytest.mark.datafiles(
- os.path.join(FIXTURE_DIR, 'deploy'),
- )
-def test_deploy_maven_file(cli_runner, datafiles, responses):
- """Test deploy_maven_file() command for expected upload cases."""
- os.chdir(str(datafiles))
- test_file = os.path.join(str(datafiles), 'm2repo', '4.0.3-SNAPSHOT',
- 'odlparent-lite-4.0.3-20181120.113136-1.pom')
-
- # Prepare response for Nexus initialization
- responses.add(responses.GET,
- "https://nexus.example.org/service/local/repo_targets",
- json=None, status=200)
- # Test successful upload
- url = 'https://nexus.example.org/service/local/artifact/maven/content'
- responses.add(responses.POST, "{}".format(url),
- json=None, status=201)
- result = cli_runner.invoke(
- cli.cli,
- ["--debug", "deploy", "maven-file", "https://nexus.example.org",
- "releases", test_file],
- obj={})
- assert result.exit_code == 0
-
- # Test failed upload
- responses.add(responses.GET,
- "https://nexus-fail.example.org/service/local/repo_targets",
- json=None, status=200)
- url = 'https://nexus-fail.example.org/service/local/artifact/maven/content'
- responses.add(responses.POST, "{}".format(url), status=404)
- result = cli_runner.invoke(
- cli.cli,
- ["--debug", "deploy", "maven-file", "https://nexus-fail.example.org",
- "releases", test_file],
- obj={})
- assert result.exit_code == 1