diff --git a/app/ghcup/Main.hs b/app/ghcup/Main.hs index 5f0941a..b4eac9a 100644 --- a/app/ghcup/Main.hs +++ b/app/ghcup/Main.hs @@ -213,6 +213,8 @@ data HLSCompileOptions = HLSCompileOptions , ovewrwiteVer :: Maybe Version , isolateDir :: Maybe FilePath , cabalProject :: Maybe FilePath + , cabalProjectLocal :: Maybe FilePath + , patchDir :: Maybe FilePath , targetGHCs :: [ToolVersion] } @@ -1268,8 +1270,22 @@ hlsCompileOpts = <*> optional (option str - (short 'p' <> long "projectfile" <> metavar "CABAL_PROJECT_LOCAL" <> help - "Absolute path to a cabal.project.local to be used for the build" + (long "cabal-project" <> metavar "CABAL_PROJECT" <> help + "If relative, specifies the path to cabal.project inside the unpacked HLS tarball/checkout. If absolute, will copy the file over." + ) + ) + <*> optional + (option + (eitherReader absolutePathParser) + (long "cabal-project-local" <> metavar "CABAL_PROJECT_LOCAL" <> help + "Absolute path to a cabal.project.local to be used for the build. Will be copied over." + ) + ) + <*> optional + (option + (eitherReader absolutePathParser) + (short 'p' <> long "patchdir" <> metavar "PATCH_DIR" <> help + "Absolute path to patch directory (applies all .patch and .diff files in order using -p1)" ) ) <*> some (toolVersionArgument Nothing (Just GHC)) @@ -1504,6 +1520,11 @@ isolateParser f = case isValid f of True -> Right $ normalise f False -> Left "Please enter a valid filepath for isolate dir." +absolutePathParser :: FilePath -> Either String FilePath +absolutePathParser f = case isValid f && isAbsolute f of + True -> Right $ normalise f + False -> Left "Please enter a valid absolute filepath." + toSettings :: Options -> IO (Settings, KeyBindings) toSettings options = do userConf <- runE @'[ JSONError ] ghcupConfigFile >>= \case @@ -2357,6 +2378,8 @@ Report bugs at |] ovewrwiteVer isolateDir cabalProject + cabalProjectLocal + patchDir GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo let vi = getVersionInfo targetVer HLS dls when setCompile $ void $ liftE $ diff --git a/lib/GHCup.hs b/lib/GHCup.hs index 5b25a09..502d86e 100644 --- a/lib/GHCup.hs +++ b/lib/GHCup.hs @@ -754,6 +754,8 @@ compileHLS :: ( MonadMask m -> Maybe Version -> Maybe FilePath -> Maybe FilePath + -> Maybe FilePath + -> Maybe FilePath -> Excepts '[ NoDownload , GPGError , DownloadFailed @@ -764,7 +766,7 @@ compileHLS :: ( MonadMask m , BuildFailed , NotInstalled ] m Version -compileHLS targetHLS ghcs jobs ov isolateDir cabalProject = do +compileHLS targetHLS ghcs jobs ov isolateDir cabalProject cabalProjectLocal patchdir = do PlatformRequest { .. } <- lift getPlatformReq GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo Dirs { .. } <- lift getDirs @@ -835,13 +837,26 @@ compileHLS targetHLS ghcs jobs ov isolateDir cabalProject = do liftE $ runBuildAction workdir Nothing - (reThrowAll @_ @'[ProcessError, FileAlreadyExistsError, CopyError] @'[BuildFailed] (BuildFailed workdir) $ do + (reThrowAll @_ @'[PatchFailed, ProcessError, FileAlreadyExistsError, CopyError] @'[BuildFailed] (BuildFailed workdir) $ do let installDir = workdir "out" + liftIO $ createDirRecursive' installDir + + -- apply patches + forM_ patchdir (\dir -> liftE $ applyPatches dir workdir) + + -- set up project files + cp <- case cabalProject of + Just cp + | isAbsolute cp -> do + handleIO (throwE . CopyError . show) $ liftIO $ copyFile cp (workdir "cabal.project") + pure "cabal.project" + | otherwise -> pure (takeFileName cp) + Nothing -> pure "cabal.project" + forM_ cabalProjectLocal $ \cpl -> handleIO (throwE . CopyError . show) $ liftIO $ copyFile cpl (workdir cp <.> "local") artifacts <- forM (sort ghcs) $ \ghc -> do let ghcInstallDir = installDir T.unpack (prettyVer ghc) liftIO $ createDirRecursive' installDir - forM_ cabalProject $ \cp -> handleIO (throwE . CopyError . show) $ liftIO $ copyFile cp (workdir "cabal.project.local") lift $ logInfo $ "Building HLS " <> prettyVer installVer <> " for GHC version " <> prettyVer ghc liftE $ lEM @_ @'[ProcessError] $ execLogged "cabal" ( [ "v2-install" @@ -857,6 +872,7 @@ compileHLS targetHLS ghcs jobs ov isolateDir cabalProject = do , "--enable-executable-stripping" , "--enable-executable-static" , "--installdir=" <> ghcInstallDir + , "--project-file=" <> cp , "exe:haskell-language-server" , "exe:haskell-language-server-wrapper"] )