IvyDE
  1. IvyDE
  2. IVYDE-195

"Ivy Dependency Explorer" View for synchronizing revisions across multiple projects in a workspace

    Details

    • Type: New Feature New Feature
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.1.0
    • Component/s: None
    • Labels:
      None

      Description

      When working with multiple projects in a workspace that represent the whole or part of a larger application, I often want to bring the revisions of dependencies up to a single new revision all at the same time (notwithstanding the wonderful eviction mechanism inherent to Ivy).

      Other times it is instructive just to see what dependencies are being utilized by projects in the workspace by revision without having to dig into each project and look at each individual module descriptor.

      I am introducing the Ivy Dependency explorer that turns the tree upside-down, exploring the workspace by organization, module, and revision and providing a mechanism to synchronize revisions across projects/classpath containers.

      1. ivyde-195(3).patch
        67 kB
        Jon Schneider
      2. ivyde-195(3).patch
        65 kB
        Jon Schneider
      3. new-project-menu-item.jpg
        113 kB
        Jon Schneider
      4. projects-represented-in-explorer.jpg
        19 kB
        Jon Schneider
      5. synced.gif
        0.2 kB
        Jon Schneider

        Issue Links

          Activity

          Hide
          Jon Schneider added a comment - - edited

          A picture is worth a thousand words... preliminary patch attached.

          Show
          Jon Schneider added a comment - - edited A picture is worth a thousand words... preliminary patch attached.
          Hide
          Nicolas Lalevée added a comment -

          This seems quite interesting !

          First about the patch:

          • there is an issue in IvyClasspathUtil, it imports an interal eclipse package: org.eclipse.wst.common.frameworks.internal.SimpleValidateEdit . We shouldn't as this kind of package are not part of the Eclipse API and can be changed at any time. There are some such import in the current code base of IvyDE, but there are only here to support the context menu on the Ivy classpath container.
          • I think there are some missing images, isn't it ?
          • and it would be cool if you can use IvyDE's formatter, some openning braces are put at some beginning of new lines whereas they should be at the end of them.

          Then as far as I could understand, this view is working with every opened project in the workspace, no matter what the dependencies are between them ? What about launching the revision check based on a selection of projects ? Then there would be an new entry in the projects context menu, like "check dependencies", which would launch the refresh of the dependency explorer based on selected project.

          And some minor suggestion: what about naming the view "Reverse Dependency Explorer" as the dependency are seen in the reversed way ? And I would also replace "sync" by "fix dependencies". WDYT ?

          Show
          Nicolas Lalevée added a comment - This seems quite interesting ! First about the patch: there is an issue in IvyClasspathUtil, it imports an interal eclipse package: org.eclipse.wst.common.frameworks.internal.SimpleValidateEdit . We shouldn't as this kind of package are not part of the Eclipse API and can be changed at any time. There are some such import in the current code base of IvyDE, but there are only here to support the context menu on the Ivy classpath container. I think there are some missing images, isn't it ? and it would be cool if you can use IvyDE's formatter, some openning braces are put at some beginning of new lines whereas they should be at the end of them. Then as far as I could understand, this view is working with every opened project in the workspace, no matter what the dependencies are between them ? What about launching the revision check based on a selection of projects ? Then there would be an new entry in the projects context menu, like "check dependencies", which would launch the refresh of the dependency explorer based on selected project. And some minor suggestion: what about naming the view "Reverse Dependency Explorer" as the dependency are seen in the reversed way ? And I would also replace "sync" by "fix dependencies". WDYT ?
          Hide
          Jon Schneider added a comment -

          1. I agree about SimpleValidateEdit. I was being a little lazy, don't recall which validator to use. I'll look it up.
          2. Oops on the images. I think I also forgot to add the manifest change to the patch. Got too much going on in my working copy...
          3. Honestly, I have no idea what you are referring to on the formatter. Opening braces? More details?
          4. Currently the view does include every project in the workspace. I can see where the project selection option would be a nice addition. I think I will probably add it to both the project menu and also to the viewer toolbar so as not to be confusing.
          5. I'll change labeling according to your recommendations – that's easy!

          Thanks for your quick response.

          Show
          Jon Schneider added a comment - 1. I agree about SimpleValidateEdit. I was being a little lazy, don't recall which validator to use. I'll look it up. 2. Oops on the images. I think I also forgot to add the manifest change to the patch. Got too much going on in my working copy... 3. Honestly, I have no idea what you are referring to on the formatter. Opening braces? More details? 4. Currently the view does include every project in the workspace. I can see where the project selection option would be a nice addition. I think I will probably add it to both the project menu and also to the viewer toolbar so as not to be confusing. 5. I'll change labeling according to your recommendations – that's easy! Thanks for your quick response.
          Hide
          Jon Schneider added a comment - - edited

          Attached an updated patch:

          1. Fixed.
          2. Fixed? Let me know if there are any missing images.
          3. Waiting on input.
          4. Fixed.
          5. Fixed.

          Attached new screenshots to demonstrate the changes.

          Show
          Jon Schneider added a comment - - edited Attached an updated patch: 1. Fixed. 2. Fixed? Let me know if there are any missing images. 3. Waiting on input. 4. Fixed. 5. Fixed. Attached new screenshots to demonstrate the changes.
          Hide
          Nicolas Lalevée added a comment -

          I still don't have the images. You need to upload them manually, as images are not "diffable" and won't be included in a patch.

          About the braces, for instance the SyncIvyFilesJob.java you provided is correct whereas IvyRevisionSync.java doesn't. It is not a big deal, I can format it before commiting.

          I also got some error logged when launching "Show all projects in workspace", see the following stack trace:

          Java Model Exception: Java Model Status [ivydetest-vfs does not exist]
          	at org.eclipse.jdt.internal.core.JavaElement.newNotPresentException(JavaElement.java:492)
          	at org.eclipse.jdt.internal.core.JavaModelManager.getPerProjectInfoCheckExistence(JavaModelManager.java:2063)
          	at org.eclipse.jdt.internal.core.JavaProject.getPerProjectInfo(JavaProject.java:1815)
          	at org.eclipse.jdt.internal.core.JavaProject.getRawClasspath(JavaProject.java:1837)
          	at org.apache.ivyde.eclipse.cpcontainer.IvyClasspathUtil.getIvyClasspathContainers(IvyClasspathUtil.java:115)
          	at org.apache.ivyde.eclipse.ui.core.IvyUtil.getIvyProjectsInWorkspace(IvyUtil.java:50)
          	at org.apache.ivyde.eclipse.ui.core.IvyUtil.getAllDependencyDescriptorsInWorkspace(IvyUtil.java:125)
          	at org.apache.ivyde.eclipse.ui.views.ReverseDependencyExplorerView$5.run(ReverseDependencyExplorerView.java:174)
          	at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:179)
          	at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:150)
          	at org.eclipse.swt.widgets.Display.syncExec(Display.java:3944)
          	at org.apache.ivyde.eclipse.ui.views.ReverseDependencyExplorerView.refresh(ReverseDependencyExplorerView.java:170)
          	at org.apache.ivyde.eclipse.ui.views.ReverseDependencyExplorerView$4.run(ReverseDependencyExplorerView.java:114)
          	at org.eclipse.jface.action.Action.runWithEvent(Action.java:498)
          	at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584)
          	at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501)
          	at org.eclipse.jface.action.ActionContributionItem$6.handleEvent(ActionContributionItem.java:452)
          	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
          	at org.eclipse.swt.widgets.Display.sendEvent(Display.java:3542)
          	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1247)
          	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1270)
          	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1255)
          	at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1076)
          	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3440)
          	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3099)
          	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2405)
          	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2369)
          	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2221)
          	at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:500)
          	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
          	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:493)
          	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
          	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:113)
          	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:194)
          	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
          	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
          	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:368)
          	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
          	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
          	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
          	at java.lang.reflect.Method.invoke(Method.java:592)
          	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:559)
          	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:514)
          	at org.eclipse.equinox.launcher.Main.run(Main.java:1311)
          	at org.eclipse.equinox.launcher.Main.main(Main.java:1287)
          

          I think that in IvyUtil#getIvyProjectsInWorkspace() you should first check that a project is opened before trying to get its classpath containers.

          Then about exception catching, there is an IvyDEException in IvyRevisionSync#sync() which is catched but nothing is done with it. I think if something bad happened in the parsing of the module descriptor and then preventing to update it, the end user should we notified about it. Another alternative here is to use the cached version of the module descriptor, because it has already been parsed at least for the generation of the reverse dependency tree. So then just logging the exception would be sufficient. I don't know what is the best of the two solutions though.

          Another no very handled exception is in IvyClasspathUtil#toIvyFile(). As far as I could remember, a Job shouldn't throw exceptions, because the end user won't see that a job has failed unless he looks in the logs. The returned IStatus should be used instead to notify the end user of the result of the job. So the best here should be I think to throw an IvyDEException and then in IvyRevisionSync#sync() catch that thrown IvyDEException accordingly. (hint: see the MultiStatus class)

          And same note in IvyUtil#getDependencyDescriptorsByProjects(), the IvyDEException should be handled. In that case I think that the end user should be notified. See IvyDEException#show().

          And another very important subject: the colors . Well, I just find the green and red color highlighting quite aggressive, don't you you too ?

          Show
          Nicolas Lalevée added a comment - I still don't have the images. You need to upload them manually, as images are not "diffable" and won't be included in a patch. About the braces, for instance the SyncIvyFilesJob.java you provided is correct whereas IvyRevisionSync.java doesn't. It is not a big deal, I can format it before commiting. I also got some error logged when launching "Show all projects in workspace", see the following stack trace: Java Model Exception: Java Model Status [ivydetest-vfs does not exist] at org.eclipse.jdt.internal.core.JavaElement.newNotPresentException(JavaElement.java:492) at org.eclipse.jdt.internal.core.JavaModelManager.getPerProjectInfoCheckExistence(JavaModelManager.java:2063) at org.eclipse.jdt.internal.core.JavaProject.getPerProjectInfo(JavaProject.java:1815) at org.eclipse.jdt.internal.core.JavaProject.getRawClasspath(JavaProject.java:1837) at org.apache.ivyde.eclipse.cpcontainer.IvyClasspathUtil.getIvyClasspathContainers(IvyClasspathUtil.java:115) at org.apache.ivyde.eclipse.ui.core.IvyUtil.getIvyProjectsInWorkspace(IvyUtil.java:50) at org.apache.ivyde.eclipse.ui.core.IvyUtil.getAllDependencyDescriptorsInWorkspace(IvyUtil.java:125) at org.apache.ivyde.eclipse.ui.views.ReverseDependencyExplorerView$5.run(ReverseDependencyExplorerView.java:174) at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:179) at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:150) at org.eclipse.swt.widgets.Display.syncExec(Display.java:3944) at org.apache.ivyde.eclipse.ui.views.ReverseDependencyExplorerView.refresh(ReverseDependencyExplorerView.java:170) at org.apache.ivyde.eclipse.ui.views.ReverseDependencyExplorerView$4.run(ReverseDependencyExplorerView.java:114) at org.eclipse.jface.action.Action.runWithEvent(Action.java:498) at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:584) at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:501) at org.eclipse.jface.action.ActionContributionItem$6.handleEvent(ActionContributionItem.java:452) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) at org.eclipse.swt.widgets.Display.sendEvent(Display.java:3542) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1247) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1270) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1255) at org.eclipse.swt.widgets.Widget.notifyListeners(Widget.java:1076) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3440) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3099) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2405) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2369) at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2221) at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:500) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:493) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:113) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:194) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:368) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:592) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:559) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:514) at org.eclipse.equinox.launcher.Main.run(Main.java:1311) at org.eclipse.equinox.launcher.Main.main(Main.java:1287) I think that in IvyUtil#getIvyProjectsInWorkspace() you should first check that a project is opened before trying to get its classpath containers. Then about exception catching, there is an IvyDEException in IvyRevisionSync#sync() which is catched but nothing is done with it. I think if something bad happened in the parsing of the module descriptor and then preventing to update it, the end user should we notified about it. Another alternative here is to use the cached version of the module descriptor, because it has already been parsed at least for the generation of the reverse dependency tree. So then just logging the exception would be sufficient. I don't know what is the best of the two solutions though. Another no very handled exception is in IvyClasspathUtil#toIvyFile(). As far as I could remember, a Job shouldn't throw exceptions, because the end user won't see that a job has failed unless he looks in the logs. The returned IStatus should be used instead to notify the end user of the result of the job. So the best here should be I think to throw an IvyDEException and then in IvyRevisionSync#sync() catch that thrown IvyDEException accordingly. (hint: see the MultiStatus class) And same note in IvyUtil#getDependencyDescriptorsByProjects(), the IvyDEException should be handled. In that case I think that the end user should be notified. See IvyDEException#show(). And another very important subject: the colors . Well, I just find the green and red color highlighting quite aggressive, don't you you too ?
          Hide
          Jon Schneider added a comment -

          Nicolas,

          Again, thanks for the response and my apologies about the sloppiness on exception handling and code formatting.

          The colors are a little bright compared to the rest of Eclipse. I could go with changing the text color in the revision and new revision columns instead. I think that might be a little less offensive. What do you think?

          I also need to think a little more about how I should integrate the branch concept into this as well. Just not real familiar with it yet.

          Show
          Jon Schneider added a comment - Nicolas, Again, thanks for the response and my apologies about the sloppiness on exception handling and code formatting. The colors are a little bright compared to the rest of Eclipse. I could go with changing the text color in the revision and new revision columns instead. I think that might be a little less offensive. What do you think? I also need to think a little more about how I should integrate the branch concept into this as well. Just not real familiar with it yet.
          Hide
          Jon Schneider added a comment -

          The new patch is attached. I've updated it based on your last comment and the refactoring you have been doing on IvyClasspathContainerConfiguration, etc.

          Show
          Jon Schneider added a comment - The new patch is attached. I've updated it based on your last comment and the refactoring you have been doing on IvyClasspathContainerConfiguration, etc.
          Hide
          Nicolas Lalevée added a comment - - edited

          Jon, your patch seems to be broken.
          There was a compilation failure after patching. I easily fixed that.
          But then I think there is also some missing patch on the plugin.xml to declare the new view. As you deleted the old patches (and I did too on my local machine) I cannot recover.

          Note that you don't need to delete old patches. You can even upload new patches with the same name without deleting the old ones. Jira will understand it is an update, so it will make appear the new one as first and make the old appear more "gray". And keeping the history of patches is a good practice I think.

          Show
          Nicolas Lalevée added a comment - - edited Jon, your patch seems to be broken. There was a compilation failure after patching. I easily fixed that. But then I think there is also some missing patch on the plugin.xml to declare the new view. As you deleted the old patches (and I did too on my local machine) I cannot recover. Note that you don't need to delete old patches. You can even upload new patches with the same name without deleting the old ones. Jira will understand it is an update, so it will make appear the new one as first and make the old appear more "gray". And keeping the history of patches is a good practice I think.
          Hide
          Jon Schneider added a comment -

          Updated the patch.

          Show
          Jon Schneider added a comment - Updated the patch.
          Hide
          Nicolas Lalevée added a comment -

          So I integrated with few cosmetic code change: formatting, created an revdepexplorer package.

          I had only one worry: IvyClasspathUtil#toIvyFile() will only properly work on ivy file in the workspace. It is possible to have some absolute path here. I don't think this is a primery use case and the code won't break (the Eclipse API will see them as read only as far as I could see). So I just put a TODO.

          And I have created a page about the new view in the doc. I would be nice if you can take time to write some paragraphs about it, how to use it, present some use case.

          thanks a lot for your patch Jon !

          Show
          Nicolas Lalevée added a comment - So I integrated with few cosmetic code change: formatting, created an revdepexplorer package. I had only one worry: IvyClasspathUtil#toIvyFile() will only properly work on ivy file in the workspace. It is possible to have some absolute path here. I don't think this is a primery use case and the code won't break (the Eclipse API will see them as read only as far as I could see). So I just put a TODO. And I have created a page about the new view in the doc. I would be nice if you can take time to write some paragraphs about it, how to use it, present some use case. thanks a lot for your patch Jon !

            People

            • Assignee:
              Nicolas Lalevée
              Reporter:
              Jon Schneider
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development