Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Context Menu #949

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open

Context Menu #949

wants to merge 30 commits into from

Conversation

lsmor
Copy link
Collaborator

@lsmor lsmor commented Dec 11, 2023

Create popUp widget: widget state, widget drawing and widget handler. The widget is pretty straigthfoward

I have to implement the instalation logic still. I am gonna need some help with it. I understand how to pass some advance parameters, but not others. The whole list of parameters is:

  • url
  • set
  • isolate
  • force
  • configure Args

If we translate that into code

--                                           |- Change be IsolateDir ... if parameter isolate is set
--                                           |             |- change to True is param force is set.
installGHCBin (GHCTargetVersion lCross lVer) GHCupInternal False [] $> (vi, dirs, ce)
--                                                               |- Is this list for the rest of params??

@hasufell
Copy link
Member

Nice.

Although it seems this popup is for installation? We want it for ghcup compile hls.

@lsmor
Copy link
Collaborator Author

lsmor commented Dec 11, 2023

Although it seems this popup is for installation? We want it for ghcup compile hls.

Ouch! I got confuse in the conversation. If the new feature is for ghcup compile, how would the user interface be? Another hot-key?

@hasufell
Copy link
Member

Although it seems this popup is for installation? We want it for ghcup compile hls.

Ouch! I got confuse in the conversation. If the new feature is for ghcup compile, how would the user interface be? Another hot-key?

I think we're going to run out of hotkeys.

I suggest something like "context menu", maybe defaulting to Enter. Then it has select menu which we may extend in the future.

@lsmor
Copy link
Collaborator Author

lsmor commented Dec 11, 2023

I suggest something like "context menu", maybe defaulting to Enter. Then it has select menu which we may extend in the future.

I think I am missing some ghcup knowledge here. From my understanding ghcup compile is a command like ghcup install, or ghcup set. So, Is the "context menu" in fact a "compile menu"? I mean, instead of adding a hot-key for compile, we have a popup with a big "compile" button and a buch of options (following ghcup compile hls --help docs). Maybe there is something about compile I am missing...

For reference I've tried to implement this comment ideas.

@hasufell
Copy link
Member

So, Is the "context menu" in fact a "compile menu"?

Let's say the context menu for now will have only one button that leads you to said compile menu.

We can add more stuff as we go.

@lsmor
Copy link
Collaborator Author

lsmor commented Dec 18, 2023

We can add more stuff as we go.

I am playing around with this. Would it be useful to add an small Menu widget utilities? It would be some default widgets for easily creating/composing menus. I am thinking three options data MenuEntry = Button | EditBox | CheckBox. Then you defined your menu as

-- Missing internal state bits for each variant
data MenuEntry = Button | EditBox | CheckBox

-- oversimplification
data CompileMenu =  CompileMenu {gitRefEditBox :: MenuEntry, setCheckBox :: MenuEntry, okButton :: MenuEntry}
newCompileMenu = CompileMenu EditBox CheckBox Button

@hasufell
Copy link
Member

Yeah, why not. We can always change things. Code decisions here are low impact, because they can be easily reverted.

It's harder with our decisions on how to organize installed files. They are hard to revert.

@runeksvendsen
Copy link
Collaborator

runeksvendsen commented Dec 20, 2023

Hi @lsmor

Thank you for your efforts in getting this implemented!

I want to help you get this over the finish line.

To achieve this, I think we first need a clear specification of exactly what it is we want to implement. I have read the linked issue (#706) as well as the comments in this PR, and below is my suggestion for a final spec (for this PR):

  1. A new "context menu" is added
    1. This is a small popup widget (overlaying part of the main TUI widget) that appears when the user presses ENTER on the currently selected tool (GHCup/Stack/HLS/cabal/GHC) in the TUI
    2. The title of this popup widget is Context menu (<tool name> <tool version>), for example Context menu (GHC 8.10.7)
    3. The widget contains one or more actions relevant to the given tool. Each action is a line that can be navigated to using the up/down keys and entered by pressing ENTER. All configuration for the given action happens in the widget that appears after pressing ENTER on an action (to keep the context menu clean).
    4. Pressing ESCAPE closes the context menu (thus showing the default TUI view)
  2. Generally speaking, this context menu will contain additional actions relevant to the selected tool in question. Thus, the content of the context menu may differ depending on which tool is selected. For example:
    1. For GHC only there may be a "compile HLS for this GHC version"-item
    2. For all tools:
      1. An "advanced installation" item, which allows configuring advanced options such as "isolated install"/"force install"/"compile instead of downloading bin-dist" (the options displayed by install --help)
      2. A "compile" item, which acts as a TUI for the ghcup compile command
    3. For HLS only we can imagine being able to deselect plugins

Example context menu for GHC 8.10.7:

┌────────────────────────────────────────GHCup────────────────────────────────────────┐
│    Tool  Version         Tags                          Notes                        │
│─────────────────────────────────────────────────────────────────────────────────────│
│                                                                                     │
│─────────────────────────────────────────────────────────────────────────────────────│
│                                                                                     │
│          ┌───────────────────Context menu (GHC 8.10.7)───────────────────┐          │
│          │┌────────┐                                                     │          │
│          ││Compile │                                                     │          │
│          │└────────┘                                                     │          │
│          │┌─────────────────────┐                                        │          │
│──────────││Advanced installation│                                        │──────────│
│          │└─────────────────────┘                                        │          │
│          │┌────────────────────────────────────────┐                     │          │
│          ││Compile HLS for this GHC version        │                     │          │
│          │└────────────────────────────────────────┘                     │          │
│          └───────────────────────────────────────────────────────────────┘          │
│                                                                                     │
│                                                                                     │
│─────────────────────────────────────────────────────────────────────────────────────│
│                                                                                     │
└─────────────────────────────────────────────────────────────────────────────────────┘
q:Quit  i:Install  u:Uninstall  s:Set  c:ChangeLog  a:Show all versions  ↑:Up  ↓:Down
h:help

Note that the above is only about the nature of the "context menu", which allows putting more advanced features into the TUI without cluttering the main view and adding additional hot keys.

Does this sound reasonable? @hasufell @arjunkathuria @david-christiansen @Kleidukos

If we agree on this, then it's up to you @lsmor to decide which of the above context menu features you want to implement. It looks like you've started to implement the "advanced installation"-item feature. The goal of this PR can then be adding (1) the context menu itself; and (2) whatever context menu feature @lsmor wants to implement.

If @lsmor wants to continue with the "advanced installation"-item feature then a subsequent PR can add the "compile HLS for this GHC version"-feature.

@lsmor lsmor changed the title PopUp installation widget Context Menu Dec 20, 2023
@lsmor
Copy link
Collaborator Author

lsmor commented Dec 21, 2023

Code decisions here are low impact, because they can be easily reverted.

Well, given the amount of features for this (I wont implement all of them in this PR though), I think It is worth to split the brick related stuff into another component (say lib-tui), instead of having a single file. So I am taking this quote literal, and do It. The only thing I wonder is if this is going to break CI for some reason. In principle I am not planning to break any cabal flag so I guess there should be no problem

I want to help you get this over the finish line.

Thanks, actually I had somethings wrong. This design helped to get things clearer

@runeksvendsen
Copy link
Collaborator

Thanks, actually I had somethings wrong. This design helped to get things clearer

Great! I'm happy to hear that.

I have to implement the instalation logic still. I am gonna need some help with it. I understand how to pass some advance parameters, but not others. The whole list of parameters is:

  • url
  • set
  • isolate
  • force
  • configure Args

If we translate that into code

--                                           |- Change be IsolateDir ... if parameter isolate is set
--                                           |             |- change to True is param force is set.
installGHCBin (GHCTargetVersion lCross lVer) GHCupInternal False [] $> (vi, dirs, ce)
--                                                               |- Is this list for the rest of params??

I'm not that familiar with the GHCup codebase, but after looking around a bit, I can see that all the relevant options are contained in the data type InstallOptions (in the GHCup.OptParse.Install module).

So I would prefer to go a few levels up from installGHCBin, and calling GHCup.OptParse.Install.install. This takes an InstallOptions as argument and ultimately calls installGHCBin. This should also work for all tools instead of just GHC, which we need because the Advanced installation action should be in the Context Menu for all tools.

Generally speaking, I prefer to call some sort of eval function which takes a single data type as argument that specifies everything to do. This avoids having to call specific functions with specific arguments in the right place. In this case the install function seems to behave this way along with the InstallCommand data type.

@hasufell does the above sound reasonable to you? I'm not familiar with how various options are passed around by GHCup, so calling GHCup.OptParse.Install.install from an action within the Context menu might be problematic.

@hasufell
Copy link
Member

@hasufell does the above sound reasonable to you? I'm not familiar with how various options are passed around by GHCup, so calling GHCup.OptParse.Install.install from an action within the Context menu might be problematic.

I'm not sure I agree. GHCup.OptParse.Install.install was written for the cli interface and assumes cli when doing error handling, logging, etc.

My approach in such cases, where it's not clear what the design overlap is, usually is to rather duplicate code and let us explore what actually ends up similar. Abstraction is, imo, discovered and not actively sought.

Here I'm not sure what a good design is that abstracts over cli and tui. A pre-existing interface may just skew your creativity when coming up with a good API for the tui to consume.

Also remember that this creates coupling and refactors over the optparse code would also affect the tui.

That said, I'd probably expect a small common denominator between cli and tui in a separate sublibrary or the main library, if one really wants to avoid code/logic duplication. So you might end up with 3 ADTs:

  • TUI ADT
  • opt-parse ADT
  • GHCup library ADT, which the other two are converted to

And now I'm not sure it's worth it. But feel free to give it a try.

@runeksvendsen
Copy link
Collaborator

@hasufell thank you for your input! You make several good points.

And now I'm not sure it's worth it.

I agree. Let's go with the simple solution for now.

@lsmor I will try again to answer your question — please ignore my comment above :-)

  • url
  • set
  • isolate
  • force
  • configure Args

If we translate that into code

--                                           |- Change be IsolateDir ... if parameter isolate is set
--                                           |             |- change to True is param force is set.
installGHCBin (GHCTargetVersion lCross lVer) GHCupInternal False [] $> (vi, dirs, ce)
--                                                               |- Is this list for the rest of params??

As you've figured out, the parameters isolate, force and configure args are all arguments to installGHCBin.

If the url option is set (the CLI option called instBindist), then we call installGHCBindist instead of installGHCBin as is done here:

liftE $ runBothE' (installGHCBindist
(DownloadInfo uri (Just $ RegexDir "ghc-.*") "" Nothing Nothing)
v
(maybe GHCupInternal IsolateDir isolateDir)
forceInstall
addConfArgs
)
and we also run the Excepts actions with the noVerify setting set to True:
runInstGHC s'{ settings = settings {noVerify = True}} $ do

For the set option, the following line takes care of this:

$ when instSet $ when (isNothing isolateDir) $ liftE $ void $ setGHC v SetGHCOnly Nothing

Let me know whether this clears things up.

@lsmor
Copy link
Collaborator Author

lsmor commented Jan 10, 2024

I am force pushing a commit with a big (but easy) change. I have moved the BrickMain.hs into its own library and split it in many modules. The original BrickMain.hs remains as in master branch. The reasons for this are:

  • If we are willing to implement a few menus with advance options, one module becomes too much of a mess to handle
  • If we gonna need more than one module, a library becomes a better approach (IMO) than many modules in an executable component
  • (selfish reason) This wont be an easy PR, hence a lot of rebase / conflicts are expected. I am willing to re-implement changes in BrickMain.hs into the new library, but rebasing 10 commits each with many conflicts is just painfull (not a commit expert myself)

If any of you have concerns about the commit please ask. In general what I've done is to move "sections" from BrickMain.hs into modules in lib-tui. I have changed some types in order to break cyclic dependencies (but all changes are minor)

@runeksvendsen
Copy link
Collaborator

@lsmor I think this kind of change makes a lot of sense. Separating into smaller modules increases readability and the sub-library increases testability.

I don't have enough knowledge of the codebase to judge whether this particular organization of modules is the "right" one, but IMO if it works then it's good enough.

@runeksvendsen
Copy link
Collaborator

@hasufell what do you think about merging this as-is (without the "context menu"-changes)? It works for me, and I think it's a useful change.

ghcup.cabal Outdated Show resolved Hide resolved
@lsmor
Copy link
Collaborator Author

lsmor commented Jan 19, 2024

Hi there!

I'll be pushing some funcitonality soon. For now I've implemented only the visual part, without logic. Before continuing I'd like to have some feedback. Each tools has its own "Context Menu" (I'd prefer advance options, honestly), from there you can go to other settings like "compile", "install", etc...

install-pop-up

Code is very messi, I am cleaning it a liitle bit before pushing.

@runeksvendsen
Copy link
Collaborator

I'll be pushing some funcitonality soon. For now I've implemented only the visual part, without logic. Before continuing I'd like to have some feedback. Each tools has its own "Context Menu" (I'd prefer advance options, honestly), from there you can go to other settings like "compile", "install", etc...

@lsmor awesome! Looks great.

I would make some small changes — provided it's not too difficult:

  1. For the "advanced installation", have a help text (ie. description) of each argument. For example:
    1. what does "force" mean; and
    2. what am I supposed to put in the "isolated" text field?
    3. (the help texts are available here:
      installOpts :: Maybe Tool -> Parser InstallOptions
      installOpts tool =
      (\(u, v) b is f -> InstallOptions v u b is f)
      <$> ( ( (,)
      <$> optional
      (option
      (eitherReader uriParser)
      (short 'u' <> long "url" <> metavar "BINDIST_URL" <> help
      "Install the specified version from this bindist"
      <> completer (toolDlCompleter (fromMaybe GHC tool))
      )
      )
      <*> (Just <$> toolVersionTagArgument [] tool)
      )
      <|> pure (Nothing, Nothing)
      )
      <*> fmap (fromMaybe setDefault) (invertableSwitch "set" Nothing setDefault
      (help $ if not setDefault then "Set as active version after install" else "Don't set as active version after install"))
      <*> optional
      (option
      (eitherReader isolateParser)
      ( short 'i'
      <> long "isolate"
      <> metavar "DIR"
      <> help "install in an isolated absolute directory instead of the default one"
      <> completer (bashCompleter "directory")
      )
      )
      <*> switch
      (short 'f' <> long "force" <> help "Force install (THIS IS UNSAFE, only use it in Dockerfiles or CI)")
      <*> many (argument str (metavar "CONFIGURE_ARGS" <> help "Additional arguments to bindist configure, prefix with '-- ' (longopts)"))
      where
      setDefault = case tool of
      Nothing -> False
      Just GHC -> False
      Just _ -> True
      )
  2. Include tool version in Context Menu title
  3. Press ESC to go back to the main screen instead of having a "Cancel" button
    1. Show this in the Context Menu window in the same way keyboard shortcuts are shown in the main window, e.g. ESC:Back

@hasufell
Copy link
Member

For the "advanced installation", have a help text (ie. description) of each argument. For example:

I think it should be possible to put that help text inside the input fields (if said input field is not focused). I think that's similar to how many web input fields work and saves space.

Press ESC to go back to the main screen instead of having a "Cancel" button

Maybe the same as in the main window, which by default is q. I think I avoided Esc, because it's more likely to be defined for the terminal window or something. It can still be set by the user to this key.


Otherwise I think this goes into the right direction.

@hasufell
Copy link
Member

@lsmor if you rebase this branch against master, then CI should succeed.

@hasufell
Copy link
Member

@lsmor let us know if you need any further feedback for the design. I believe this is a major improvement to the TUI.

@lsmor
Copy link
Collaborator Author

lsmor commented Jan 24, 2024

I am pushing (only) the visuals after rebasing. TODOS:

  • migrate the fix Restore TUI scrolling to old behavior #987 to the new library
  • add option's help message in grey font
  • implement the visual for CompileMenu
  • implement the logic for AdvanceInstallMenu
  • implement the logic for CompileMenu
  • Solve bug about q used for exit (see below)

@hasufell
Copy link
Member

@lsmor what's the timeline you think you will have this finished? I'm evaluating whether to wait for it before making a release or doing a release sooner than later.

@lsmor
Copy link
Collaborator Author

lsmor commented Jan 26, 2024

@lsmor what's the timeline you think you will have this finished? I'm evaluating whether to wait for it before making a release or doing a release sooner than later.

um... I don't expect it to have it soon. the first two points are easy, and I can have them in the next week, but I still don't know how difficult will be to have the last two point working. + There should be some extensive testing which I don't know how to approach actually. So I would expect to have something testable in about 1,5 month. From there, fixing all possible bugs, etc... let say 2 or 3 months to merge.

Btw, I am terrible at ETA. Notice #850 , took me 5+ months (summer in the middle) and I estimated 3 months (and it was merge with a bug on my side!!!)... Also I am more familiar with the code base now.

@hasufell
Copy link
Member

I am terrible at ETA

Well, I'm not trying to be a manager :D

Just trying to understand when to schedule releases. I think I'll start setting up a milestone then and only merge smaller stuff.

@lsmor
Copy link
Collaborator Author

lsmor commented Jan 30, 2024

Maybe the same as in the main window, which by default is q

I just recall, why this isn't a good Idea. You can either type q on a textbox, or q to exit. You could be intelligent enough and dispatch the q depending on whether or not a text box is focused, but thats brittle as it literally depends on pattern matching order... Also, it feels a little bit clumsy.

3. Press ESC to go back to the main screen instead of having a "Cancel" button

AS @hasufell said, adding a different key for exit, is risky as something like ESC might be dispatch to the terminal itself instead of the content within the terminal (example: Ctrl + Enter doesn't work on my gnome's terminal, probably because some colission with terminal's shortcuts)

¿is it ok if we keep the cancell button?

I think it should be possible to put that help text inside the input fields

I am adding this to the check list

@lsmor
Copy link
Collaborator Author

lsmor commented Apr 27, 2024

Hi again!

This is pretty much ready to test. The only problem is that I don't know how to test it. I have being able to set up a docker container with both ghcup-v0.1.22.0 and ghcup-this.branch, which set of parameter do I need to test? specially for the compile menus.

For example, ghcup compile ghc has two flags --make and --hadrian and also --flavour. What do they mean? which are the patches referenced in the flag --patch? etc...

@hasufell
Copy link
Member

hasufell commented Apr 27, 2024

For example, ghcup compile ghc has two flags --make and --hadrian and also --flavour. What do they mean? which are the patches referenced in the flag --patch? etc...

--make and --hadrian are the two build systems of GHC. Make was later decomissioned. So, old GHCs only have make, then there are a couple of releases that have both make and hadrian and then the latest ones only have hadrian. I forgot which versions exactly. The selection logic currently is like this:

ghcup-hs/lib/GHCup/GHC.hs

Lines 988 to 1005 in 7daf199

case buildSystem of
Just Hadrian -> do
lift $ logInfo "Requested to use Hadrian"
liftE doHadrian
Just Make -> do
lift $ logInfo "Requested to use Make"
doMake
Nothing -> do
supportsHadrian <- liftE $ catchE @HadrianNotFound @'[HadrianNotFound] @'[] (\_ -> return False)
$ fmap (const True)
$ findHadrianFile (fromGHCupPath workdir)
if supportsHadrian
then do
lift $ logInfo "Detected Hadrian"
liftE doHadrian
else do
lift $ logInfo "Detected Make"
doMake

--patch are user supplied patches and can be specified multiple times (file or http/https url, all in URI format). --patchdir is similar, except is just a directory path, see the --help text.

--flavour is documented here: https://gitlab.haskell.org/ghc/ghc/blob/master/hadrian/doc/flavours.md ...but we should accept any string.

@lsmor
Copy link
Collaborator Author

lsmor commented May 2, 2024

Hi, I am having a totally not fun time compiling ghc. Is there any way to configure hadrian so no documentation at all is build? is the fifth time the build fails because either python is missing or sphinx is missing or some haddock / latex font is missing... I guess all of those are errors related to documentation builds.

I am compiling with the following options (below, the equivalent CLI, but in am doing it via the new menu in the TUI)

# I am doing all of this in an ubuntu docker image with a mounted volume in the isolated path.
ghcup compile ghc -v 9.8.2 -b 9.4.8 --hadrian --flavour quickest --isolate /root/.cache/host-machine/builds/test -j 4

I wonder if there is something in CONFIGURE_ARGS which can be useto avoid documentation builds.

@hasufell
Copy link
Member

hasufell commented May 2, 2024

It should be --docs=none, see https://gitlab.haskell.org/ghc/ghc/-/blob/master/hadrian/doc/user-settings.md#documentation

But I just realize we only let you define the flavor and pass configure args, not hadrian args.

The idea was that "flavour transformers" should be enough: https://gitlab.haskell.org/ghc/ghc/-/blob/master/hadrian/doc/flavours.md#flavour-transformers

But there appears to be none to disable docs.

But you can apply a patch to disable docs in the build flavor:; https://gist.githubusercontent.com/hasufell/8de8890c6ede3ea190a1d177a6cae5ac/raw/e25cf46563bcb37e7b3cb696c25a034d9ebd064a/0001-Disable-docs-for-quickest-build-flavor.patch

Then your line becomes:

ghcup compile ghc -v 9.8.2 -b 9.4.8 --hadrian --flavour quickest --isolate /root/.cache/host-machine/builds/test -j 4 --patch=https://gist.githubusercontent.com/hasufell/8de8890c6ede3ea190a1d177a6cae5ac/raw/e25cf46563bcb37e7b3cb696c25a034d9ebd064a/0001-Disable-docs-for-quickest-build-flavor.patch

@hasufell
Copy link
Member

hasufell commented May 2, 2024

Related: #846

@lsmor
Copy link
Collaborator Author

lsmor commented May 3, 2024

Hi there,

Good news!. I've been able to compile both ghc and hls from the TUI. The configurations I've tested are (CLI equiv.)

ghcup compile ghc -v 9.8.2 -b 9.4.8 --hadrian --flavour quickest --isolate /root/.cache/host-machine/builds/test -j 4 --patch=https://gist.githubusercontent.com/hasufell/8de8890c6ede3ea190a1d177a6cae5ac/raw/e25cf46563bcb37e7b3cb696c25a034d9ebd064a/0001-Disable-docs-for-quickest-build-flavor.patch

ghcup compile hls -v 2.7.0.0 --isolate /root/.cache/host-machine/builds/test --ghc 9.4.8 -j 4 --cabal-update

The combinations of different settings is large. Is there any particular setting I should test?.

I have created a precarious ubuntu-based dockerfile in this branch in my fork. The dockerfile should be enough to compile all three of ghcup, ghc (with no docs) and hls. The isolated paths are pointing to mounted volumes in the docker container, so you need to set them up.

What else is needed to move this PR forward?

@hasufell
Copy link
Member

hasufell commented May 3, 2024

What else is needed to move this PR forward?

Not much. I just need to find the time to go through it again. I'm still recovering from health issues.

I definitely want to merge this before Zurihac, since I will be giving a talk in the ecosystem workshop preceding Zurihac. The new TUI design should be merged by then, so I don't give outdated information.

@lsmor
Copy link
Collaborator Author

lsmor commented May 4, 2024

I just need to find the time to go through it again

Let me know if I can facilitate something: documentation, testing workflows, etc...

@dfordivam
Copy link
Contributor

I have tried this PR and made some minor fixes on this branch.

There are a couple of issues I noticed

  • The ghcup cannot be compiled without tui. (by disabling tui flag in cabal)
  • The HLS compilation via ContextMenu is not working for me. I will debug further, and pushes fixes to this branch.

This is an initial feedback, more testing is necessary.

@hasufell
Copy link
Member

@lsmor if you happen to be on Matrix, consider joining #ghcup:matrix.org

@lsmor
Copy link
Collaborator Author

lsmor commented May 26, 2024

Thanks for the feedback and for the contibutions!

  • The ghcup cannot be compiled without tui. (by disabling tui flag in cabal)

Indeed. I notice the cabal file is too optimistic with respect the tui. Here is the diff you need to make it tui independant

❯ git diff ghcup.cabal
diff --git a/ghcup.cabal b/ghcup.cabal
index 0a9545f..0ed5275 100644
--- a/ghcup.cabal
+++ b/ghcup.cabal
@@ -402,19 +402,13 @@ executable ghcup
   build-depends:
     , ghcup
     , ghcup-optparse
-    , ghcup-tui
 
   if flag(internal-downloader)
     cpp-options: -DINTERNAL_DOWNLOADER
 
   if flag(tui)
     cpp-options:   -DBRICK
-    other-modules: BrickMain
-    build-depends:
-      , brick         ^>=2.1
-      , transformers  ^>=0.5
-      , vty           ^>=6.0 || ^>=6.1 || ^>=6.2
-      , optics        ^>=0.4
+    build-depends: ghcup-tui
 
   if os(windows)
     cpp-options: -DIS_WINDOWS
  • The HLS compilation via ContextMenu is not working for me

Which configuration doesn't work for you?

if you happen to be on Matrix, consider joining #ghcup:matrix.org

I am not in matrix nor any messaging platform. But I could join if there is a discussion about this PR there.

@hasufell
Copy link
Member

I am not in matrix nor any messaging platform. But I could join if there is a discussion about this PR there.

Up to you. I'm just trying to gather contributors and establish a less formal place to get pinged, do discussions and ask questions.

E.g. I don't know if you will be at Zurihac.

@dfordivam
Copy link
Contributor

@lsmor I did more testing and had the following feedback, plus responses to your comments.

  1. In HLS advanced compilation

    • Allow specifying comma or space separated list of multiple target GHC's in the same field. (A single invocation of ghcup compile ghc supports specifying multiple GHC values.)
    • "cabal project" / "cabal project local" seems to be not that useful and could be removed (??)
    • a new field for "-g" option would be very useful. ("The git commit/branch/ref to build from (accepts anything 'git checkout' accepts)"
  2. Print the CLI command which would do the exact advanced installation as being performed by the tui

    If the user is trying to do something experimental the possibility of the compilation failing is high and the user will have to check the logs and fire the compilation again.
    in this case providing the user with the CLI command with all the fields specified would be nice.

    This could be printed as an "Info"

  3. Which configuration doesn't work for you?

    I hit the following error when building HLS, and interestingly I cannot reproduce this now.

[ Info  ] verifying digest of: haskell-language-server-2.7.0.0-src.tar.gz
[ Info  ] Unpacking: haskell-language-server-2.7.0.0-src.tar.gz to /home/divam/vms/ubuntu/.ghcup/tmp/ghcup-4f98de77d2a77843
[ Info  ] Installing HLS
ghcup: user error (Pattern match failure in 'do' block at lib/GHCup/HLS.hs:231:3-12)
  1. In response to this comment

Both of the APIs return Either String (), which is handled in withIOAction

If this API returns a Right value in case of an error, then "Success" is printed like this

[ Error ] [GHCup-00841] Process "/home/divam/vms/ubuntu/.ghcup/tmp/ghcup-b01477984640547e/ghc-9.10.1/hadrian/build" with arguments ["-j8",
[ ...   ]                                                                                                             "binary-dist"] failed with exit code 1.
Success
Press enter to continue

Whereas if a Left value is returned the following is printed

[ ghc-conf ] configure: error: GHC version 9.6 or later is required to compile GHC.
Error: [GHCup-00841] Process "sh" with arguments ["./configure", "GHC=ghc-9.8.2",
                             "--prefix=/home/divam/vms/ubuntu/.ghcup/ghc/9.10.0.20240328",
                             "--disable-ld-override"] failed with exit code 1.
Press enter to continue
  1. In response to this comment

The most likely use cases for the tui based advanced installations would be "simple" scenarios like compiling HLS (when a new minor release of GHC is released), and the power users would prefer the CLI.

If the user is invoking the advanced options menu for compile/install of only a single version of a tool, then keeping the state is certainly a better choice, since the user might want to tweak the values in case the installation or compilation did not happen successfully.

(Note: User should be able to run the compilation of HLS for multiple GHC versions in a single step, as I mentioned above in this comment)

When the user want to use the advanced options submenu multiple times in a
single session of GHCup, then the design choice for keeping/resetting the state becomes more complicated.

Therefore let's consider both of these design choices for a couple of scenarios I think would be common.

  • Install multiple versions of GHC and specify an isolated directory for each of them.

    After the installation finishes, user will open the advanced install menu for another version of GHC, and will have to specify the isolated directory again.

    In this scenario I think both keeping the state / clearing the state should be fine, since user has to specify only a single field.
    (Keeping the state has an advantage that the user might want to just change the last part of the path, edit it manually, and fire the install again.)

  • Compile multiple version of GHC, with CONFIGURE_ARGS or flavour specified

    For example, user wants to build a static flavor for multiple versions.
    In this case the user will likely specify these fields: bootstrap-ghc, overwrite-version, jobs, flavour, and isolated.

    For compiling different GHC the bootstrap-ghc and isolated fields, will be different.
    But having the flavor and jobs fields preserved is good.
    For overwrite-version field, it depends whether its a simple string or more complex like '%v-%h'
    Therefore both keeping the state and reseting has pros/cons.

I think other than these two scenarios there aren't many use cases for using the advanced options menu. Anything more complicated might be better done via CLI.

Overall I think maintaining the state is better.

@hasufell
Copy link
Member

There is something intriguing about the TUI, which is actually much harder to do via the CLI: #846

There are 3 classes of "pass through flags".

  1. ./configure <flags> for compilation
  2. ./hadrian/build.sh <flags>
  3. ./configure <flags> for the resulting bindist

At the moment, the ghcup compile ghc interface makes the decision to use the "longopts" for case 1. The TUI doesn't have that limitation.

@hasufell
Copy link
Member

At any rate... I believe the TUI can very well be improved gradually. Unlike the CLI, it doesn't really impose a static interface, because it cannot be used in scripts. We can "break" TUI just fine and provide alternative ways to e.g. navigate it. It is interactive, after all.

So I don't mind a bit of experimentation wrt the interface.

@lsmor
Copy link
Collaborator Author

lsmor commented May 29, 2024

  • Allow specifying comma or space separated list of multiple target GHC's in the same field.

Oh!! sure, I'll do it

  • "cabal project" / "cabal project local" seems to be not that useful and could be removed (??)

I did not commit those...

  • a new field for "-g" option would be very useful.

I remmember to implement this, but there was a problem with it... not very sure now, I'll take a look a come back with feedback later.

I will merge your commits and push them (read below). By the way, thanks a lot for the help and testing!!! probably keeping the state is better than not keeping it.

At any rate... I believe the TUI can very well be improved gradually

Absolutely, I was thinking about adding a section to docs/dev.md with the docs for the TUI, so hopefully (unrealisticly?) other people can contribute.

Now a git question... how do I proceed? can @dfordivam merge to this PR directly? o should I add locally his fork to my remotes, then pull, then push to my fork? (the last is moreless what I do at job, but the usage of git is much more amateur)

To recap:

  • add multiple version of ghc for hls compilation
  • explore the -g option and implement it if is easy enough.
  • merge @dfordivam job on this.

To have frequently used fields shown first.
INTERNAL_DOWNLOADER, and BRICK are not used in ghcup-tui
@dfordivam
Copy link
Contributor

I did not commit those...

I was only referring the TUI interface. The TUI could provide a different set of options than CLI.
But since these options have already been added in the TUI, it's fine to keep them.
Although I think they will be hardly ever used, they could be moved to the bottom, which I did on my branch.

should I add locally his fork to my remotes, then pull, then push to my fork..

This is how it's usually accomplished, but I opened a PR on your fork to make it easy for you to merge the branch via GitHub.

I have also pushed a few more commits on my branch, including the cabal file fixes.
In case there are merge conflict with your local changes, or you don't want to merge all the changes, you should fetch my branch and cherry-pick commits on top of your branch, and then push to this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants