Skip to content
This repository has been archived by the owner on Dec 10, 2020. It is now read-only.

Commit

Permalink
Fix for idea-plugin goal that generates too long project filename
Browse files Browse the repository at this point in the history
Earlier in order to generate meaningful names for intellij, idea-plugin concatenates all target specs. However it will easily exceed the limit of UNIX filename length given a few target specs. This fix limits the name to up to 200 characters.

Testing Done:
https://travis-ci.org/pantsbuild/pants/builds/159747876

Bugs closed: 3863

Reviewed at https://rbcommons.com/s/twitter/r/4231/
  • Loading branch information
wisechengyi committed Sep 14, 2016
1 parent b1de54a commit 424929b
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ class IdeaPluginGen(ConsoleTask):
existing skeleton project into a Pants project as if user is importing these targets.
"""

PROJECT_NAME_LIMIT = 200

@classmethod
def register_options(cls, register):
super(IdeaPluginGen, cls).register_options(register)
Expand Down Expand Up @@ -105,7 +107,8 @@ def __init__(self, *args, **kwargs):

@classmethod
def get_project_name(cls, target_specs):
return re.sub('[^0-9a-zA-Z:_]+', '.', '__'.join(target_specs))
# take up to PROJECT_NAME_LIMIT chars as project file name due to filesystem constraint.
return re.sub('[^0-9a-zA-Z:_]+', '.', '__'.join(target_specs))[:cls.PROJECT_NAME_LIMIT]

# TODO: https://github.com/pantsbuild/pants/issues/3198
def generate_project(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@

from pants.backend.project_info.tasks.idea_plugin_gen import IDEA_PLUGIN_VERSION, IdeaPluginGen
from pants.base.build_environment import get_buildroot
from pants.base.cmd_line_spec_parser import CmdLineSpecParser
from pants.util.contextutil import temporary_file
from pants_test.pants_run_integration_test import PantsRunIntegrationTest


class IdeaPluginIntegrationTest(PantsRunIntegrationTest):

def _do_check(self, project_dir_path, expected_project_path, expected_targets):
"""Check to see that the project contains the expected source folders."""

Expand Down Expand Up @@ -49,46 +49,62 @@ def _get_project_dir(self, output_file):
with open(output_file, 'r') as result:
return result.readlines()[0]

def _run_and_check(self, project_path, targets):
def _run_and_check(self, target_specs):
"""
Invoke idea-plugin goal and check for target specs and project in the
generated project and workspace file.
:param target_specs: list of target specs
:return: n/a
"""
self.assertTrue("targets are empty", target_specs)
spec_parser = CmdLineSpecParser(get_buildroot())
# project_path is always the directory of the first target,
# which is where intellij is going to zoom in under project view.
project_path = spec_parser.parse_spec(target_specs[0]).directory

with self.temporary_workdir() as workdir:
with temporary_file(root_dir=workdir, cleanup=True) as output_file:
pants_run = self.run_pants_with_workdir(
['idea-plugin', '--output-file={}'.format(output_file.name), '--no-open'] + targets, workdir)
['idea-plugin', '--output-file={}'.format(output_file.name), '--no-open'] + target_specs, workdir)
self.assert_success(pants_run)

project_dir = self._get_project_dir(output_file.name)
self.assertTrue(os.path.exists(project_dir), "{} does not exist".format(project_dir))
self._do_check(project_dir, project_path, targets)
self._do_check(project_dir, project_path, target_specs)

def test_idea_plugin_single_target(self):

target = 'examples/src/scala/org/pantsbuild/example/hello:hello'
project_path = "examples/src/scala/org/pantsbuild/example/hello"

self._run_and_check(project_path, [target])
self._run_and_check([target])

def test_idea_plugin_single_directory(self):
target = 'testprojects/src/python/antlr::'
project_path = "testprojects/src/python/antlr"

self._run_and_check(project_path, [target])
self._run_and_check([target])

def test_idea_plugin_multiple_targets(self):
target_a = 'examples/src/scala/org/pantsbuild/example/hello:'
target_b = 'testprojects/src/python/antlr::'

# project_path is always the directory of the first target,
# which is where intellij is going to zoom in at project view.
project_path = 'examples/src/scala/org/pantsbuild/example/hello'

self._run_and_check(project_path, [target_a, target_b])
self._run_and_check([target_a, target_b])

def test_idea_plugin_project_name(self):
self.assertEqual(
'examples.src.scala.org.pantsbuild.example.hello:__testprojects.src.python.antlr::',
IdeaPluginGen.get_project_name([
'examples/src/scala/org/pantsbuild/example/hello:',
'testprojects/src/python/antlr::'
]
'examples/src/scala/org/pantsbuild/example/hello:',
'testprojects/src/python/antlr::'
]
)
)

def test_idea_plugin_long_project_name(self):
list_run = self.run_pants(['-q', 'list', 'testprojects/tests/java/org/pantsbuild/testproject/::'])
self.assert_success(list_run)
self.assertGreater(len(list_run.stdout_data), IdeaPluginGen.PROJECT_NAME_LIMIT)

a_lot_of_targets = [l for l in list_run.stdout_data.splitlines() if l]

self.assertEqual(IdeaPluginGen.PROJECT_NAME_LIMIT, len(IdeaPluginGen.get_project_name(a_lot_of_targets)))
self._run_and_check(a_lot_of_targets)

0 comments on commit 424929b

Please sign in to comment.