intellij-haskell icon indicating copy to clipboard operation
intellij-haskell copied to clipboard

Import Haskell module or automatically import new Cabal packages

Open develop7 opened this issue 6 years ago • 28 comments

Repro:

  1. Have a multi-package Stack project handled with IJ-haskell
  2. Create another cabal package inside it and specify it in stack.yaml
  3. Open above project in IDEA

Expected: new cabal package gets picked up by IJ-haskell, the way it got picked up when importing project

Instead: it is not. In order to pick up new cabal packages user has to reimport project losing custom modules, local history, configurations etc.

develop7 avatar Jan 21 '19 15:01 develop7

You can do Tools/Haskell/Update Settings and Restart REPLs

rikvdkleij avatar Jan 21 '19 15:01 rikvdkleij

Nope, didn't work for me. With the project I work on, that is.

develop7 avatar Jan 21 '19 16:01 develop7

Ok, Tools/Haskell/Update Settings and Restart REPLs supports only changes in Cabal file.

rikvdkleij avatar Jan 21 '19 16:01 rikvdkleij

Will fix it when I'm done with getting the UI more responsive/solid.

rikvdkleij avatar Jan 21 '19 16:01 rikvdkleij

Need some time to figure this out.

rikvdkleij avatar Jan 29 '19 20:01 rikvdkleij

Done in beta43. It only adds/imports new modules.

rikvdkleij avatar Jan 31 '19 20:01 rikvdkleij

Thanks for implementing this, it does the job in test project indeed, but I've ran into following exception after adding a package to the day job project:

stack trace
java.lang.NullPointerException
	at scala.collection.mutable.ArrayOps$ofRef$.length$extension(ArrayOps.scala:204)
	at scala.collection.mutable.ArrayOps$ofRef.length(ArrayOps.scala:204)
	at scala.collection.IndexedSeqOptimized.segmentLength(IndexedSeqOptimized.scala:196)
	at scala.collection.IndexedSeqOptimized.segmentLength$(IndexedSeqOptimized.scala:195)
	at scala.collection.mutable.ArrayOps$ofRef.segmentLength(ArrayOps.scala:198)
	at scala.collection.GenSeqLike.prefixLength(GenSeqLike.scala:98)
	at scala.collection.GenSeqLike.prefixLength$(GenSeqLike.scala:98)
	at scala.collection.mutable.ArrayOps$ofRef.prefixLength(ArrayOps.scala:198)
	at scala.collection.IndexedSeqOptimized.find(IndexedSeqOptimized.scala:53)
	at scala.collection.IndexedSeqOptimized.find$(IndexedSeqOptimized.scala:52)
	at scala.collection.mutable.ArrayOps$ofRef.find(ArrayOps.scala:198)
	at intellij.haskell.util.HaskellProjectUtil$.findCabalFile(HaskellProjectUtil.scala:147)
	at intellij.haskell.module.HaskellModuleBuilder$.getCabalFile(HaskellModuleBuilder.scala:222)
	at intellij.haskell.module.HaskellModuleBuilder$.createCabalInfo(HaskellModuleBuilder.scala:179)
	at intellij.haskell.module.StackProjectImportBuilder$.$anonfun$addHaskellModule$1(StackProjectImportBuilder.scala:82)
	at intellij.haskell.util.ScalaUtil$$anon$2.compute(ScalaUtil.scala:41)
	at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:963)
	at intellij.haskell.util.ApplicationUtil$.runReadAction(ApplicationUtil.scala:33)
	at intellij.haskell.module.StackProjectImportBuilder$.addHaskellModule(StackProjectImportBuilder.scala:82)
	at intellij.haskell.external.component.StackProjectManager$$anon$2.$anonfun$run$14(StackProjectManager.scala:195)
	at intellij.haskell.external.component.StackProjectManager$$anon$2.$anonfun$run$14$adapted(StackProjectManager.scala:194)
	at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:62)
	at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:55)
	at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:49)
	at intellij.haskell.external.component.StackProjectManager$$anon$2.run(StackProjectManager.scala:194)
	at com.intellij.openapi.progress.impl.CoreProgressManager$TaskRunnable.run(CoreProgressManager.java:727)
	at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$2(CoreProgressManager.java:164)
	at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:582)
	at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:532)
	at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:87)
	at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:151)
	at com.intellij.openapi.progress.impl.CoreProgressManager$4.run(CoreProgressManager.java:403)
	at com.intellij.openapi.application.impl.ApplicationImpl$1.run(ApplicationImpl.java:314)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

The stack trace looks very relevant to this issue, unfortunately I'm not sure what I was doing wrong.

develop7 avatar Feb 08 '19 14:02 develop7

Thanks for reporting!

Used this feature already couple of time within large projects and worked as expected so must be some corner case.

Looking to the stacktrace it could be that no Cabal file was found but library code should not crash....

rikvdkleij avatar Feb 08 '19 15:02 rikvdkleij

Can you display the directory listing of the root folder of the package you wanted to add?

rikvdkleij avatar Feb 08 '19 15:02 rikvdkleij

All right, here's a redacted screenshot. The package directory name, .cabal file name and package name in the .cabal file are all the same.

screenshot from 2019-02-09 18-52-30

develop7 avatar Feb 09 '19 15:02 develop7

Thanks!

No hidden files?

rikvdkleij avatar Feb 09 '19 16:02 rikvdkleij

none, besides usual .gitignore & .stack-work

BTW copying&renaming .iml file from sibling package & referencing it in .idea/modules.xml did the job

develop7 avatar Feb 09 '19 16:02 develop7

BTW copying&renaming .iml file from sibling package & referencing it in .idea/modules.xml did the job

Ok, but that is just hacking :smile:

Like I said, importing new modules in existing projects worked for me. I'm curious why it does not work in your case.

rikvdkleij avatar Feb 09 '19 17:02 rikvdkleij

Other question :smile:

How do you refer in the stack.yaml to that other project/module?

rikvdkleij avatar Feb 09 '19 18:02 rikvdkleij

by simply adding the

- REDACTED_PACKAGE_NAME

line under packages key

develop7 avatar Feb 09 '19 18:02 develop7

So not using a relative or absolute file path?

rikvdkleij avatar Feb 09 '19 20:02 rikvdkleij

I mean, it is relative already, to the stack project root.

develop7 avatar Feb 09 '19 20:02 develop7

Okay, I get exactly the same error (stacktrace) when there exists a non-existing file path in packages.

Only thing the plugin can do is check if file path exists before adding new module.

rikvdkleij avatar Feb 10 '19 12:02 rikvdkleij

I have tried to reproduce your issue with new package to import in project folder but without success.

rikvdkleij avatar Feb 11 '19 19:02 rikvdkleij

I found another cause of this error. When there are git(hub) references defined in packages.

rikvdkleij avatar Feb 14 '19 13:02 rikvdkleij

Yes there are in my stack.yaml! They should've been added as modules too, but there's no way to ask stack to list directories with packages' source code.

develop7 avatar Feb 14 '19 14:02 develop7

They should've been added as modules too, but there's no way to ask stack to list directories with packages source code.

Well, I could download code and add them as modules but that is some work and have to do some more investigation. Also, if github reference is changed, plugin has to update the code in some way. Does package have to be seen as part of project or as external library?

rikvdkleij avatar Feb 14 '19 15:02 rikvdkleij

To think of it, all of the VCS "packages" actually had an extra-dep: true stanza, which means they must end up on the extra-deps section (the extra-dep: true isn't mentioned in Stack docs at the moment). Therefore I should these "packages" to extra-deps first and the issue would just go away.

Well, I could download code and add them as modules but that is some work and have to do some more investigation.

Stack checks out VCS/http dependencies under .stack-work/downloaded/<seemingly_random_name>/, so the question is to actually figure out which dependency ends what directory. In fact this is the exactly the way extra-deps are handled too.

Also, if github reference is changed, plugin has to update the code in some way.

No need, stack build got it covered. I mean all you have to update is the module source directory, because if reference gets changed, the path under .stack-work/downloaded is changed too.

Does package have to be seen as part of project or as external library?

Actually I'd go with external library unconditionally, at least at first as lower-hanging fruit. Also because the source ends up in .stack-work/downloaded/<random_name> anyway, tracking which only complicates things.

develop7 avatar Feb 17 '19 08:02 develop7

@develop7 Is this issue solved?

rikvdkleij avatar May 22 '19 13:05 rikvdkleij

Actually it's still there. Just recently (May 2 to be exact) I've hacked .idea/modules.xml so the new subpackage would be picked up.

develop7 avatar May 22 '19 15:05 develop7

Do you have an example project so I can try to reproduce it? Must be something unexpected in the stack.yaml.

rikvdkleij avatar May 22 '19 19:05 rikvdkleij

Not really, it was that huge project on the job. Will try to reproduce the issue against the sample project bit later.

develop7 avatar May 22 '19 19:05 develop7

@develop7 ping :smile:

rikvdkleij avatar Sep 01 '19 19:09 rikvdkleij