> I'm a little unsure if it is possible to change the project's classpath during a compile.
Right now we do change the classpath whilst building - but not via eclipse, instead by manipulating the groovy class loader used during the compile - this is what enables AST transforms to be found. A similar thing worked that I prototyped for Grab support, where all the magic happened under the covers, but I'd rather surface the dependencies users are getting into the eclipse project, than hide them. As you say, there may be restrictions on doing it during a compile, although I'm perhaps not saying that 'and after it is dynamically added the project needs to notice immediately', as I'm saying 'the user needs to see this dependency they have introduced'. I still need to get my thoughts straight here.
We don't want to get into a pickle where the code won't compile (even reconcile) on first attempt because we haven't yet added a particular Grab dependency to the project classpath - i'd really like to avoid a scenario where the first compile of something correctly formed actually fails because of using Grab.
> But, I could imagine some sort of post reconcile listener that detects if @Grab is being used and then makes the classpath
> changes. The Grab container would then remain in the .classpath (and therefore be committed to any repo) until it is
> explicitly removed by the user (this can be managed from the project properties or by right clicking -> remove from build
grab support is ast transform driven, ast transforms are currently banned from execution during reconciling (this may be lifted but needs a good reason to be lifted). However, what you are proposing would be driving the ast transform in a very different way to how it is driven right now, by detecting the annotation ourselves and calling the transform implementation at a different time to do its job and discover the real dependency. This may be feasible but it depends on how easily callable the transform is from a different context, I really would not want to duplicate what Grab and friends do in another place.
> I could imagine some grab container operations like: empty, refresh, validate, and maybe some way to search for all
> uses of @Grab in the project (so the container contents could be managed).
Hmm, after more thinking perhaps I want it all handled automatically. But I still perhaps like the idea of promoting an entry from the container to the 'real' project classpath - the user just needs to be aware that the GrabContainer represents the current state of their code and any changes to a Grab annotation will be automatically reflected in the GrabContainer, so if they don't promote dependencies out of that container, they may lose them when Grabs are removed.
I think I can see a use case where you hack away at a script/class trying things out then when you are happy, you promote the dependency to a 'real one' and remove the @Grab.
> If a post compile/reconcile listener is used to initially create the container, then another build/reconcile would need to be > created before errors are resolved.
> Not sure what the first step here would be, but I imagine that I could create a stub Grab container that is created when an
> @Grab is encountered. But, is there a quick way of doing this? I don't want to have to walk the AST to find any possible
> @Grab annotations. Is it possible that the compiler could add a special error marker to the compilation unit if @Grab is
> found, but there is not corresponding Grab container?
I need to think about this and how it relates to what happens for Grab under the covers. I am thinking I really want to avoid the first compile failing even when the code is properly formed, because the Grab is processed too late. hmm.