Introduce `idea-plugin` goal to invoke intellij pants plugin via CLI

Review Request #3664 — Created April 8, 2016 and submitted

benjyw, nhoward_tw, peiyu, stuhood, zundel

This change enables calling intellij pants plugin from cli to import the targets/directories specified.

Similar to idea goal, idea-plugin goal makes a skeleton ipr project file, and in addition fill in the workspace iws file with target specs and project path, so the plugin will know how to continue to import the project as if the user is doing so.

Only dep is bootstrap.

[tw-mbp-yic pants (from_cli)]$ ./pants --explain idea-plugin 
Goal Execution Order:

bootstrap -> idea-plugin

Goal [TaskRegistrar->Task] Order:

bootstrap [jar-dependency-management->JarDependencyManagementSetup_bootstrap_jar_dependency_management, bootstrap-jvm-tools->BootstrapJvmTools_bootstrap_bootstrap_jvm_tools]
idea-plugin [idea-plugin->PluginGen_idea_plugin]

./pants idea-plugin --no-open examples/src/python/example/hello/main/ examples/tests/java/org/pantsbuild/example/hello/greet/ will generate a iws file containing targets and project path. (only one project path because that's the directory intellij is going to zoom into):

<?xml version="1.0"?>
<project version="4">
  <component name="PropertiesComponent">
    <property name="targets" value="['/Users/yic/workspace/pants/examples/src/python/example/hello/main/', '/Users/yic/workspace/pants/examples/tests/java/org/pantsbuild/example/hello/greet/']" />
    <property name="project_path" value="/Users/yic/workspace/pants/examples/src/python/example/hello/main/" />

Other change:
set default java language level to 8 for IdeGen

  • 0
  • 0
  • 3
  • 2
  • 5
Description From Last Updated
  1. Ooh, this brings us closer to using the open-source Pants plugin at Square, instead of maintaining our custom internal plugin.

    What does this mean for the workflow of working with generated code? Does the open-source pants plugin handle arbitrary code gen? We have a ton of custom code gen (using xjc, jooq, protoc, wire, etc). Last I checked the open-source plugin wasn't working well with that. We have our developers using a workflow where they run our internal ./pants idea goal, or just ./pants gen, whenever they need to refresh generated code.

    1. Regarding generated code, like pants idea, pants export used by the plugin will trigger [gen] as well. the plugin also has refresh function to regenerate the code. In twitter, folks are using the plugin on project with generated code every day, so it is worth checking again.

      This change is merely a function to tell the plugin what targets and path need to be imported, and the plugin will continue to work as if user tries to import a project from GUI.

      The workflow is like:
      1. ./pants idea-plugin <some targets>, which invokes intellij
      2. the plugin sees it is a potential pants project, tries to import it via the normal workflow:
      a) call pants export
      b) parse the result into a project

  2. For our internal plugin we have an --open-with= option that, if set, uses subprocess.Popen to open the IPR file with an arbitrary command instead of using ui_open. This is for compatibility with systems that don't have an open (eg, some users pass xdg-open or a custom launcher for IJ).

    It'd be nice to see the same thing here.

    1. Happy to incorperate it in. Although I am not too familiar with open or xdg-open, do you think you can share that piece of code?

    2. Sure, we just use:

            if self.open_with:
              null = open(os.devnull, 'w')
              subprocess.Popen([self.open_with, self.project_filename], stdout=null, stderr=null)
    3. Thanks! Added and tested with ./pants idea-plugin examples/src/java/org/pantsbuild/example/hello/:: --idea-plugin-open-with='open'

  2. nit: sort

  3. this is a strange flag, from the comment it is not tied with plugin, it allows 11 or 12 contradics to what we are telling people (internally at twitter) that 15.0.x are recommended.

    also 11 and 12 are 4 years old, just saying.

    1. flag removed. the version flag does not translate to anything meaningful. in the actually xml, it says version 4.

  4. not familiar with this, wonder if this can be derived from scala-platform?

    1. filed for followup. user have to select scala sdk after a project is imported.
      jdk is configured by --java-language-level

  1. This feels like the wrong approach to me... it's far too large an API on the pants side.

    Could this be something like a JVM command line tool wrapped in a pants task, that takes exactly the same arguments as the intellij plugin's "Import Project" window?

    1. doc added below PluginGen

  2. src/python/pants/backend/project_info/tasks/ (Diff revision 7)

    It would be instructive to explain what these fields are and why they're initialized the way they are.

    1. docstring under PluginGen documents the important bits.

      It was a straight copy-paste from IdeaGen, which generates project file from the given parameters, but I am not familiar with all its parts yet. Left "TODO" for further refactoring/trimming.

  3. This is an 80-line function with one comment and no unit tests. This needs a few things:
    1. Function-level docstring explaining what it does.
    2. 1-line comment per major step (more or less the code sections you have separated by blank lines)
    3. Ideally break it up and unit test the parts (don't go overboard and make it less readable, of course)

  2. src/python/pants/backend/project_info/tasks/ (Diff revision 8)

    Should have idea in the name, or be in an idea directory probably.

    1. renamed to IdeaPluginGen in

  3. It should come from export, ideally.

  4. This should probably be coming in via export, but I don't think we currently have configured encodings per target.

  5. src/python/pants/backend/project_info/tasks/ (Diff revision 8)

    Should be coming from export?

    1. Ideally it should get the jdk the same way as export does, but it should be fine for now as it is defaulted to java 8.

  6. There is a context manager for this:

    from pants.util.contextutil import temporary_file_path
    1. used from pants.util.contextutil import temporary_file. thanks!

  7. Maybe add open_with as an optional argument to ui_open?

    1. ui_open's interfaces is
      def ui_open(*files):
      so adding an option like def ui_open(*files, open_with) is not allowed, refactoring this would be a bit out of scope since many functions depend on it.

  2. src/python/pants/backend/project_info/tasks/ (Diff revision 9)

    I think all of this is unused in this plugin. Looks like copypasta from the idea plugin

    1. removed. thanks for catching that!

  3. Presumably, this overwrites the .iws file. Are you regenerating it because Idea won't launch without it it? I'm fine if you want to land this as-is and iterate, but keep in mind that this is one of users' least favorite things about using the idea plugin at Square.

    It would be nice if the .iws file already existed we just allowed the existing one to be used.

    Maybe the same for the .ipr file. Do we really want to overwrite a project that's already been imported once with the plugin? Maybe we should only overwrite existing config if someone passes a --overwrite

    1. Unlike idea goal that overwrites the existing project, this idea-plugin will generate the project at a new location. Maybe idea should do the same.

      [tw-mbp-yic pants (from_cli)]$ ./pants idea-plugin --no-open examples/tests/scala/org/pantsbuild/example/hello/welcome/::
      [tw-mbp-yic pants (from_cli)]$ ./pants idea-plugin --no-open examples/tests/scala/org/pantsbuild/example/hello/welcome/::
  1. Ship It!
  1. Ship It!
Review request changed

Status: Closed (submitted)

Change Summary:

d31ec5b4b1fb4f91e5beb685539ea14278dc62cf thanks gents!