The Workspace Plugin was built for IntelliJ and Android Studio to support working on source code that spans multiple repositories in a single Gradle workspace and IDE instance. This way you can build and test against source for libraries you may need to make changes in instead of relying on clumsy SNAPSHOT workflow that requires multiple IDE instances and artifact deployments.
- Supports adding and removing modules as source from an IntelliJ or Android Studio workspace with a single click (currently Gradle only)
- When projects are added or removed from a workspace, dependencies of all modules in the workspace (that the plugin knows about) are automatically adjusted to account for state of the dependency so they build against the appropriate artifact/source
- When opening a project in IntelliJ, dependencies are adjusted to match the modules included in the workspace.
- Multiple window support so you can work in multiple workspaces and IDE instances at the same time.
- The plugin relies on a set of regular expressions to parse dependencies for both included projects (
settings.gradle
) and module's dependencies (build.gradle
).- If dependencies aren't matched by the regex, they're ignored (they're not lost, just not auto-adjusted if workspace that match are a part of the workspace).
- Included modules are discovered during refresh and on initialization via settings.gradle parsing.
- This allows the plugin to also discover newly added workspace if they're already a part of your workspace.
- File "lines" are determined differently before run through regular expressions
build.gradle
- Split on\n
onlysettings.gradle
- Split on,
and by\n
- Supported modules are determined by modules present in your
workspace.manfiest
file.
{
"settingsPath": "<relative path to settings.gradle from project root (can be empty)>",
"name": "<workspace_name>",
"modules": [
{
"name": "<artifact_name>",
"path": "<relative_path_to_module_source>",
"group": "<artifact_group>"
},
{
"name": "<artifact_name>",
"path": "<relative_path_to_module_source>",
"group": "<artifact_group>"
},
{
"name": "<artifact_name>",
"path": "<relative_path_to_module_source>",
"group": "<artifact_group>"
}
]
}
{
"settingsPath": "",
"name": "example-workspace",
"modules": [
{
"name": "example-1",
"path": "../example-1/example",
"group": "com.example.group"
},
{
"name": "random-library",
"path": "../random-library/random",
"group": "com.example.random"
},
{
"name": "example-4",
"path": "../../../../../example-4/example",
"group": "com.foo.bar"
}
]
}
Upon a user triggered workspace refresh, the plugin performs the following actions.
- Determine included modules (read
settings.gradle
) - Gather Dependencies for ALL potentially supported modules (current dependencies per module)
- Rebuild module info graph (included modules that depend on eachother)
- Update included modules from bottom up (Modify
build.gradle
filess for included modules) - Updated included modules so we know which modules to modify (included)
- Ensure included modules' dependencies match include (modify
build.gradle
to account for source/remote)
Upon a user triggered module swap (source -> artifact or artifact -> source), the plugin performs the following actions.
- Add/Remove module to/from include
- Updated
settings.gradle
to add/remove module from workspace - Ensure included modules' dependencies match include (modify
build.gradle
to account for source/remote)
- Sub-projects names must contain no more than 2 colons (limitation of the regex used)
- If IntelliJ/Android Studio is opened and a library is included as source already, conversion to artifact (exluding source from workspace) will result in an unknown version number in the
build.gradle
because there's no way to know the desired version if there isn't one to read initially (should be restorable easily by using VCS tools to see the diffs). - Manual changes to
build.gradle
are not automatically picked up by the plugin so manual refresh might be needed if changes result in the plugin window being out of sync with thebuild.gradle
files. - Currently, modules can only be included as the same name as their artifact name (IE -
com.example.group:artifact-name:1.2.34
would have to be included asartifact-name
). Down the road, we could provide more information in the manifest to support this if desired. - settings.gradle formatting will be overwritten despite functionality remaining in tact.
- Workspace manifest file is currently hardcoded to live at
<project_root>/workspace.manifest
workspace.manifest
currently needs to be hand edited.
- Expose file chooser to allow user to point to
workspace.manifest
file - Expose file chooser to allow user to point to directory or
build.gradle
and add a project to theworkspace.manifest
- Allow plugin to work with multiple workspaces and hotswap between them.
- Maven support (stretch)
- Possibly use gradle tasks to determine dependencies (requires a lot of work and might result in worse performance)
- Publish to Jetbrains plugin repository
- IntelliJ Sandbox (Fastest) - see Running and Debugging
- Android Studio
- Build the plugin into a zip file
- Find the zip
- Uninstall the current plugin from Android Studio if installed
- Install the plugin from the zip file you built
- Restart Android Studio
- IntelliJ uses virtual files (see VFS) which are potentially stale
- To account for this, files are forcefully refreshed before attempting any reads or writes on them. This ensures the plugin is always using the most up to date info on the files and prevents us from having to watch files for changes.
- To get multi-window support to work, I had to create a Project Component which starts a Tool Window manually.
- When trying to build/run with a normal JDK, I was getting random hangs while indexing. To fix, you must download and build the Jetbrains JDK and have the IntelliJ sandbox target this for debug builds
- General IDEA configs and such
- IDEA has different thread pools for reads and writes and will throw exceptions if you try to write from a read only thread
- To deal with this, we simply use Write threads for all our async stuff. It's relatively fast enough for what we're doing.
- See General Threading
- Java regular expression tester with multiple inputs and java string representation
- Plugin Samples
- IntelliJ Log File Locations