forked from pantsbuild/pants
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cache files created by (specially designed) annotation processors.
These annotation processors (so far, only twitter.common.args) write a file into META-INF which lists all of the files they created. Make pants process that file to decide which files should go in the artifact cache. Testing Done: Ran integration tests. Bugs closed: 132 Reviewed at https://rbcommons.com/s/twitter/r/1250/
- Loading branch information
1 parent
68c2f6b
commit e556eaa
Showing
7 changed files
with
368 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
src/python/pants/backend/jvm/tasks/jvm_compile/resource_mapping.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# coding=utf-8 | ||
# Copyright 2014 Pants project contributors (see CONTRIBUTORS.md). | ||
# Licensed under the Apache License, Version 2.0 (see LICENSE). | ||
|
||
from __future__ import (nested_scopes, generators, division, absolute_import, with_statement, | ||
print_function, unicode_literals) | ||
|
||
from collections import defaultdict | ||
import os | ||
import re | ||
|
||
|
||
class ResourceMapping(object): | ||
RESOURCES_BY_CLASS_NAME_RE = re.compile(r'^(?P<classname>[\w+.]+) -> (?P<path>.+)$') | ||
|
||
def __init__(self, classes_dir): | ||
self._classes_dir = classes_dir | ||
self._resource_mappings = None | ||
|
||
def _read_resource_mappings(self, mappings, lines): | ||
def parse_items(line): | ||
try: | ||
n, items = line.split(" ") | ||
return int(n) | ||
except ValueError as error: | ||
raise ValueError(dedent(''' | ||
Unable to parse resource mappings. | ||
Expected "N items", got "{line}: {error}"'''.format(line=line, error=error))) | ||
|
||
items_left = 0 | ||
section = None | ||
for line in lines: | ||
line = line.strip() | ||
# Skip comments. | ||
if not line or line.startswith("#"): | ||
continue | ||
|
||
# We have just read a section name and now want to read a number of items | ||
if section: | ||
section = None | ||
items_left = parse_items(line) | ||
continue | ||
|
||
# This is the section we are looking for | ||
if line == "resources by class name:": | ||
section = line | ||
continue | ||
|
||
# Here, we read the individual items. | ||
if items_left: | ||
items_left -= 1 | ||
match = ResourceMapping.RESOURCES_BY_CLASS_NAME_RE.match(line) | ||
if not match: | ||
raise ValueError(dedent(''' | ||
Unable to parse resource mappings. | ||
Expected classname -> path, got "{line}"'''.format(line=line))) | ||
classname, path = match.group('classname'), match.group('path') | ||
mappings[classname].append(path) | ||
|
||
@property | ||
def mappings(self): | ||
"""Returns a dict from class name to file name, from the resource-mappings in META-INF. | ||
The protocol is that annotation processors create files under | ||
META-INF/compiler/resource-mappings to describe any new files that | ||
they create and their relationship to class files. | ||
Each file contains some number of sections. Each section starts | ||
with a section name followed by a colon and a newline. The next | ||
line is an integer N followed by 'items' and a newline. The next | ||
N lines contain [class name] ' -> ' [absolute output file path] | ||
Blank lines and lines with leading # (comment lines) are skipped. | ||
The section this method handles is "resources by class name". | ||
So far, this protocol is only implemented to by | ||
com.twitter.tools.args.apt.CmdLineProcessor from Twitter Commons; | ||
that's not enabled by default in pants. | ||
""" | ||
if self._resource_mappings is not None: | ||
return self._resource_mappings | ||
|
||
mapping_dir = os.path.join(self._classes_dir, "META-INF", "compiler", "resource-mappings") | ||
mappings = defaultdict(list) | ||
if os.path.exists(mapping_dir): | ||
for filename in os.listdir(mapping_dir): | ||
path = os.path.join(mapping_dir, filename) | ||
with open(path) as f: | ||
self._read_resource_mappings(mappings, f.readlines()) | ||
|
||
self._resource_mappings = mappings | ||
return self._resource_mappings | ||
|
||
def __getitem__(self, key): | ||
return self.mappings.get(key) | ||
|
||
def get(self, key, default=None): | ||
return self.mappings.get(key, default) |
13 changes: 13 additions & 0 deletions
13
testprojects/src/java/com/pants/testproject/annotation/main/BUILD
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Copyright 2014 Pants project contributors (see CONTRIBUTORS.md). | ||
# Licensed under the Apache License, Version 2.0 (see LICENSE). | ||
# | ||
# Test project for resource mapping feature | ||
|
||
jvm_binary(name='main', | ||
source='Main.java', | ||
main='com.pants.testproject.annotation.main.Main', | ||
basename = 'annotation-example', | ||
dependencies=[ | ||
'testprojects/src/java/com/pants/testproject/annotation/processor', | ||
], | ||
) |
17 changes: 17 additions & 0 deletions
17
testprojects/src/java/com/pants/testproject/annotation/main/Main.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright 2014 Pants project contributors (see CONTRIBUTORS.md). | ||
// Licensed under the Apache License, Version 2.0 (see LICENSE). | ||
|
||
package com.pants.testproject.annotation.main; | ||
|
||
/** | ||
* We need this so that there is some class that ResourceMappingProcessor can | ||
* put in to the resource-mappings file. It's marked @Deprecated because it | ||
* needs to be annotated with something so that the annotation processor gets | ||
* run, and Deprecated is built-in to java. | ||
*/ | ||
@Deprecated | ||
public class Main { | ||
public static void main(String args[]) { | ||
System.out.println("Hello World!"); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
testprojects/src/java/com/pants/testproject/annotation/processor/BUILD
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Copyright 2014 Pants project contributors (see CONTRIBUTORS.md). | ||
# Licensed under the Apache License, Version 2.0 (see LICENSE). | ||
# | ||
# annotation_processor() target to test resource mapping | ||
|
||
annotation_processor(name='processor', | ||
sources=globs('*.java'), | ||
processors=['com.pants.testproject.annotation.processor.ResourceMappingProcessor'], | ||
dependencies=[ | ||
'3rdparty:guava', | ||
], | ||
) | ||
|
Oops, something went wrong.