Skip to content

Commit

Permalink
Add support for extra publication metadata.
Browse files Browse the repository at this point in the history
In particular this change adds support for OSSRH required metadata for
publishing to maven central.  An object is exposed for pantsbuild/pants
use that encapsulates the boilerplate common to all jars it will publish
to maven central and this object is used to prepare all publishable java
targets for maven central publishing.

Testing Done:
Local publishes and verification of most permutations of
OSSRHPublicationMetadata in the existing
JarPublishIntegrationTest#test_scala_publish test via new golden data.

CI went green here:
  https://travis-ci.org/pantsbuild/pants/builds/61845618

Bugs closed: 1411, 1511

Reviewed at https://rbcommons.com/s/twitter/r/2184/
  • Loading branch information
jsirois committed May 9, 2015
1 parent bcaec38 commit b6d09b1
Show file tree
Hide file tree
Showing 20 changed files with 524 additions and 140 deletions.
2 changes: 2 additions & 0 deletions pants-plugins/src/python/internal_backend/repositories/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ python_library(
dependencies = [
'src/python/pants/base:build_file_aliases',
'src/python/pants/base:build_manual',
'src/python/pants/backend/jvm:artifact',
'src/python/pants/backend/jvm:ossrh_publication_metadata',
'src/python/pants/backend/jvm:repository',
]
)
Expand Down
27 changes: 27 additions & 0 deletions pants-plugins/src/python/internal_backend/repositories/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import os

from pants.backend.jvm.ossrh_publication_metadata import (Developer, License,
OSSRHPublicationMetadata, Scm)
from pants.backend.jvm.repository import Repository
from pants.base.build_file_aliases import BuildFileAliases
from pants.base.build_manual import manual
Expand All @@ -21,6 +23,30 @@
push_db_basedir=os.path.join('testprojects', 'ivy', 'pushdb'))


def org_pantsbuild_publication_metadata(description):
return OSSRHPublicationMetadata(
description=description,
url='http://pantsbuild.github.io/',
licenses=[
License(
name='Apache License, Version 2.0',
url='http://www.apache.org/licenses/LICENSE-2.0'
)
],
developers=[
Developer(
name='The pants developers',
email='[email protected]',
url='https://github.com/pantsbuild/pants'
)
],
scm=Scm.github(
user='pantsbuild',
repo='pants'
)
)


# Your repositories don't need this manual.builddict magic.
# It keeps these examples out of http://pantsbuild.github.io/build_dictionary.html
manual.builddict(suppress=True)(public_repo)
Expand All @@ -32,5 +58,6 @@ def build_file_aliases():
objects={
'public': public_repo, # key 'public' must match name='public' above
'testing': testing_repo,
'pants_library': org_pantsbuild_publication_metadata
},
)
3 changes: 3 additions & 0 deletions src/java/org/pantsbuild/args4j/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,8 @@ java_library(
org='org.pantsbuild',
name='args4j',
repo=public,
publication_metadata=pants_library("""
Utilities to make args4j more like com.twitter.common#args
""")
),
)
3 changes: 3 additions & 0 deletions src/java/org/pantsbuild/junit/annotations/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ java_library(
org='org.pantsbuild',
name='junit-runner-annotations',
repo=public,
publication_metadata=pants_library("""
Annotations for use with org.pantsbuild#junit-runner that support running tests in parallel.
""")
),
sources=globs('*.java')
)
3 changes: 3 additions & 0 deletions src/java/org/pantsbuild/tools/jar/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ java_library(
org='org.pantsbuild',
name='jar-tool',
repo=public,
publication_metadata=pants_library("""
A command line tool for creating jars given a set of rules.
""")
),
)

Expand Down
4 changes: 4 additions & 0 deletions src/java/org/pantsbuild/tools/junit/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ java_library(
org='org.pantsbuild',
name='junit-runner',
repo=public,
publication_metadata=pants_library("""
A command line tool for running junit tests that provides functionality above and beyond
that provided by org.junit.runner.JUnitCore.
""")
),
dependencies=[
'3rdparty:args4j',
Expand Down
3 changes: 3 additions & 0 deletions src/java/org/pantsbuild/tools/junit/withretry/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ java_library(
org='org.pantsbuild',
name='junit-runner-withretry',
repo=public,
publication_metadata=pants_library("""
Provides an org.junit.runner.Runner that supports retries of failing tests.
""")
),
dependencies=[
'3rdparty:junit',
Expand Down
35 changes: 23 additions & 12 deletions src/python/pants/backend/jvm/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@


python_library(
name = 'artifact',
sources = ['artifact.py'],
dependencies = [
name='artifact',
sources=['artifact.py'],
dependencies=[
'3rdparty/python:six',
':repository',
'src/python/pants/base:payload_field',
],
)

python_library(
name = 'plugin',
sources = ['__init__.py', 'register.py'],
dependencies = [
name='plugin',
sources=['__init__.py', 'register.py'],
dependencies=[
':artifact',
':ossrh_publication_metadata',
':repository',
'src/python/pants/backend/core/tasks:group_task',
'src/python/pants/backend/jvm/targets:all',
Expand All @@ -28,10 +29,10 @@ python_library(
)

python_library(
name = 'ivy_utils',
sources = ['ivy_utils.py'],
resources = globs('tasks/templates/ivy_resolve/*.mustache'),
dependencies = [
name='ivy_utils',
sources=['ivy_utils.py'],
resources=globs('tasks/templates/ivy_resolve/*.mustache'),
dependencies=[
'3rdparty/python/twitter/commons:twitter.common.collections',
'src/python/pants/backend/jvm/targets:jvm',
'src/python/pants/base:build_environment',
Expand All @@ -45,6 +46,16 @@ python_library(
)

python_library(
name = 'repository',
sources = ['repository.py'],
name='repository',
sources=['repository.py'],
)

python_library(
name='ossrh_publication_metadata',
sources=['ossrh_publication_metadata.py'],
dependencies=[
'3rdparty/python:six',
':artifact',
'src/python/pants/base:validation',
],
)
35 changes: 24 additions & 11 deletions src/python/pants/backend/jvm/artifact.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,28 @@
from __future__ import (absolute_import, division, generators, nested_scopes, print_function,
unicode_literals, with_statement)

from hashlib import sha1

from six import string_types

from pants.backend.jvm.repository import Repository
from pants.base.payload_field import PayloadField, stable_json_sha1


class PublicationMetadata(PayloadField):
"""Extra metadata required to publish an artifact beyond its coordinates."""


class Artifact(PayloadField):
"""Represents a jvm artifact ala maven or ivy.
"""Represents a publishable jvm artifact ala maven or ivy.
Used in the ``provides`` parameter to *jvm*\_library targets.
"""

def __init__(self, org, name, repo, description=None):
def __init__(self, org, name, repo, publication_metadata=None):
"""
:param string org: Organization of this artifact, or groupId in maven parlance.
:param string name: Name of the artifact, or artifactId in maven parlance.
:param repo: The ``repo`` this artifact is published to.
:param string description: Description of this artifact.
:param publication_metadata: Optional extra publication metadata required by the ``repo``.
"""
if not isinstance(org, string_types):
raise ValueError("org must be {} but was {}".format(string_types, org))
Expand All @@ -33,15 +35,15 @@ def __init__(self, org, name, repo, description=None):
if not isinstance(repo, Repository):
raise ValueError("repo must be an instance of Repository")

if description is not None and not isinstance(description, string_types):
raise ValueError("description must be None or {} but was {}"
.format(string_types, description))
if (publication_metadata is not None
and not isinstance(publication_metadata, PublicationMetadata)):
raise ValueError("publication_metadata must be a {} but was a {}"
.format(PublicationMetadata, type(publication_metadata)))

self.org = org
self.name = name
self.rev = None
self.repo = repo
self.description = description
self.publication_metadata = publication_metadata

def __eq__(self, other):
return (type(other) == Artifact and
Expand All @@ -52,7 +54,18 @@ def __hash__(self):
return hash((self.org, self.name))

def _compute_fingerprint(self):
return stable_json_sha1((self.org, self.name, self.rev))
data = (self.org, self.name)

# NB: The None occupies the legacy rev 3rd slot. The rev was never populated and always None,
# so maintaining the slot and its value just serve to preserve the fingerprint and thus
# containing targets in caches out in the world.
data += (None,)

if self.publication_metadata:
fingerprint = self.publication_metadata.fingerprint()
if fingerprint:
data += (fingerprint,)
return stable_json_sha1(data)

def __ne__(self, other):
return not self.__eq__(other)
Expand Down
Loading

0 comments on commit b6d09b1

Please sign in to comment.