Compare commits
11 Commits
issue-1032
...
issue-1040
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d662bb020 | |||
| df6205c482 | |||
| 7a9d897c14 | |||
| 183498df7e | |||
| 53695fbb11 | |||
|
|
ca10f8ce62 | ||
|
|
978c6d2704 | ||
| eebbc9908b | |||
| b37ac53aaf | |||
| be4a1bdf7a | |||
| 7cad0ca9fe |
Submodule data/metadata updated: cca49a2e02...c9dae0c587
@@ -40,6 +40,80 @@ All you wanted to know about GHCup.
|
|||||||
* [haskell.org](https://www.haskell.org/haskell-org-committee/) via CI and infrastructure
|
* [haskell.org](https://www.haskell.org/haskell-org-committee/) via CI and infrastructure
|
||||||
* [Haskell Foundation](https://haskell.foundation/affiliates/) via affiliation
|
* [Haskell Foundation](https://haskell.foundation/affiliates/) via affiliation
|
||||||
|
|
||||||
|
## Project ownership and hierarchy
|
||||||
|
|
||||||
|
The project at the time of writing (2024-04-22) follows the model of
|
||||||
|
[benevolent dictator for life](https://en.wikipedia.org/wiki/Benevolent_dictator_for_life), which is
|
||||||
|
Julian Ospald at the moment.
|
||||||
|
|
||||||
|
Ideally, the ownership should be shared across a core team of collaborators sharing the same vision and
|
||||||
|
engagement in the future.
|
||||||
|
|
||||||
|
I do not believe in people making decisions over projects they are barely involved in. Instead I believe
|
||||||
|
in listening to end users needs very carefully and making decisions based on that. People who want a direct
|
||||||
|
influence on the decision process have to both demonstrate they share the vision of GHCup and do the actual
|
||||||
|
work.
|
||||||
|
|
||||||
|
"Work" here doesn't have to be "writing code". There are many ways to be engaged in a project.
|
||||||
|
|
||||||
|
### Transition plan in case of maintainer absence
|
||||||
|
|
||||||
|
In case the current maintainer of GHCup (Julian Ospald) is unreachable for a prolonged period of time (3 months),
|
||||||
|
the ownership of this project will be automatically transferred to the following individuals:
|
||||||
|
|
||||||
|
- [Moritz Angerman](https://github.com/angerman)
|
||||||
|
- [Andrew Lelechenko](https://github.com/Bodigrim)
|
||||||
|
|
||||||
|
They will be tasked with finding new maintainers in whatever way they see fit (be it appointing themselves or asking HF for help).
|
||||||
|
|
||||||
|
The appointed owners may choose to stay owners after the transition period (whether it's in a passive or active capacity) or
|
||||||
|
fully transfer ownership to someone else or an organization.
|
||||||
|
|
||||||
|
The community shall be informed about this process.
|
||||||
|
|
||||||
|
If not otherwise specified by the newly appointed owners, the following principles shall apply to the *transition period*:
|
||||||
|
|
||||||
|
#### During the transition period
|
||||||
|
|
||||||
|
During the transition period, no other individual or organization is allowed to drive changes to
|
||||||
|
[ghcup-hs](https://github.com/haskell/ghcup-hs) repository, unless they are explicitly allowed to do so by the appointed owners.
|
||||||
|
|
||||||
|
The following people (in addition to the owners) shall have full write access to the
|
||||||
|
[ghcup-metadata](https://github.com/haskell/ghcup-metadata) repository
|
||||||
|
(all files) for the length of the transition period, unless otherwise specified by the appointed owners:
|
||||||
|
|
||||||
|
- [Ben Gamari](https://github.com/bgamari)
|
||||||
|
- [Hécate Moonlight](https://github.com/Kleidukos)
|
||||||
|
- [Mike Pilgrem](https://github.com/mpilgrem)
|
||||||
|
- [Jens Petersen](https://github.com/juhp)
|
||||||
|
|
||||||
|
Contributions to the metadata are expected to follow a review process. If that turns out to be impractical due to lack of engagement, a wait
|
||||||
|
time of 2 days before merging shall be followed anyway, except for the `-vanilla` files, which may be merged at any time.
|
||||||
|
|
||||||
|
#### Access
|
||||||
|
|
||||||
|
The GHCup website, various scripts and unofficial bindists are hosted on haskell.org infrastructure. Contact the
|
||||||
|
[Haskell.org committee](https://www.haskell.org/haskell-org-committee/) for access.
|
||||||
|
|
||||||
|
The backup owners should already have admin rights on the GHCup repositories, which are hosted on the
|
||||||
|
[Github haskell namespace](https://github.com/haskell). In case of issues contact one of the
|
||||||
|
organization admins for access, e.g.:
|
||||||
|
|
||||||
|
- [Andrew Lelechenko](https://github.com/orgs/haskell/people/Bodigrim)
|
||||||
|
- [gbaz](https://github.com/orgs/haskell/people/gbaz)
|
||||||
|
- [Hécate Moonlight](https://github.com/Kleidukos)
|
||||||
|
- [davean](https://github.com/orgs/haskell/people/davean)
|
||||||
|
- [chessai](https://github.com/orgs/haskell/people/chessai)
|
||||||
|
|
||||||
|
The owners should already have access to the [hackage package](https://hackage.haskell.org/package/ghcup/maintainers/).
|
||||||
|
In case of issues contact the [hackage trustees](https://github.com/haskell-infra/hackage-trustees).
|
||||||
|
|
||||||
|
#### Private runners
|
||||||
|
|
||||||
|
Private runners maintained by Julian Ospald may cease to work. Moritz Angerman will have SSH access to the machines.
|
||||||
|
However, no one will have access to the Hetzner account and billing information. As such, those runners will simply
|
||||||
|
have to be replaced.
|
||||||
|
|
||||||
## How to help
|
## How to help
|
||||||
|
|
||||||
* if you want to contribute code or documentation, check out the [issue tracker](https://github.com/haskell/ghcup-hs/issues) and the [Development guide](./dev.md)
|
* if you want to contribute code or documentation, check out the [issue tracker](https://github.com/haskell/ghcup-hs/issues) and the [Development guide](./dev.md)
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ of metadata files to understand their purpose. These can be combined.
|
|||||||
For example, if you want access to both prerelease and cross bindists, you'd do:
|
For example, if you want access to both prerelease and cross bindists, you'd do:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml
|
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.8.yaml
|
||||||
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-cross-0.0.8.yaml
|
ghcup config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-cross-0.0.8.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -180,7 +180,7 @@ url-source:
|
|||||||
Also see [config.yaml](https://github.com/haskell/ghcup-hs/blob/master/data/config.yaml)
|
Also see [config.yaml](https://github.com/haskell/ghcup-hs/blob/master/data/config.yaml)
|
||||||
for more options.
|
for more options.
|
||||||
|
|
||||||
You can also use an alternative metadata via one-shot cli option:
|
You can also use an alternative metadata via the one-shot CLI option:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
ghcup --url-source=https://some-url/ghcup-0.0.8.yaml tui
|
ghcup --url-source=https://some-url/ghcup-0.0.8.yaml tui
|
||||||
@@ -207,7 +207,7 @@ Note that later versions of GHCup allow more sophisticated mirror support, see [
|
|||||||
1. [https://mirror.sjtu.edu.cn/docs/ghcup](https://mirror.sjtu.edu.cn/docs/ghcup)
|
1. [https://mirror.sjtu.edu.cn/docs/ghcup](https://mirror.sjtu.edu.cn/docs/ghcup)
|
||||||
2. [https://mirrors.ustc.edu.cn/help/ghcup.html](https://mirrors.ustc.edu.cn/help/ghcup.html)
|
2. [https://mirrors.ustc.edu.cn/help/ghcup.html](https://mirrors.ustc.edu.cn/help/ghcup.html)
|
||||||
|
|
||||||
### Git based metadata config
|
### Git-based metadata config
|
||||||
|
|
||||||
If you don't like the way ghcup updates its metadata with caching and fetching via curl, you can also do as follows:
|
If you don't like the way ghcup updates its metadata with caching and fetching via curl, you can also do as follows:
|
||||||
|
|
||||||
@@ -322,8 +322,24 @@ Stack metadata doesn't have a concept of those and we don't try to be smart when
|
|||||||
|
|
||||||
### Windows
|
### Windows
|
||||||
|
|
||||||
On windows, you may find the following config options useful too:
|
#### Using GHCup's MSYS2 installation
|
||||||
`skip-msys`, `extra-path`, `extra-include-dirs`, `extra-lib-dirs`.
|
|
||||||
|
Stack usually maintains its own msys2 installation. However, you can instruct it to use GHCup's MSYS2 or any other. E.g. if you
|
||||||
|
had GHCup install msys2 into `C:\ghcup\msys64\`, then you would add the following config to stack's `config.yaml`
|
||||||
|
(you can find its location via `stack path --stack-root`):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
skip-msys: true
|
||||||
|
extra-lib-dirs:
|
||||||
|
- C:\ghcup\msys64\mingw64\lib
|
||||||
|
- C:\ghcup\msys64\mingw64\bin
|
||||||
|
extra-path:
|
||||||
|
- C:\ghcup\msys64\mingw64\bin
|
||||||
|
- C:\ghcup\msys64\usr\bin
|
||||||
|
- C:\ghcup\msys64\usr\local\bin
|
||||||
|
extra-include-dirs:
|
||||||
|
- C:\ghcup\msys64\mingw64\include
|
||||||
|
```
|
||||||
|
|
||||||
Also check out: [https://docs.haskellstack.org/en/stable/yaml_configuration](https://docs.haskellstack.org/en/stable/yaml_configuration)
|
Also check out: [https://docs.haskellstack.org/en/stable/yaml_configuration](https://docs.haskellstack.org/en/stable/yaml_configuration)
|
||||||
|
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ executeOut' :: MonadIO m
|
|||||||
-> m CapturedProcess
|
-> m CapturedProcess
|
||||||
executeOut' path args chdir env' = do
|
executeOut' path args chdir env' = do
|
||||||
cp <- createProcessWithMingwPath ((proc path args){ cwd = chdir, env = env' })
|
cp <- createProcessWithMingwPath ((proc path args){ cwd = chdir, env = env' })
|
||||||
(exit, out, err) <- liftIO $ readCreateProcessWithExitCodeBS cp ""
|
(exit, out, err) <- liftIO $ withRestorePath (env cp) $ readCreateProcessWithExitCodeBS cp ""
|
||||||
pure $ CapturedProcess exit out err
|
pure $ CapturedProcess exit out err
|
||||||
|
|
||||||
|
|
||||||
@@ -166,20 +166,21 @@ execLogged :: ( MonadReader env m
|
|||||||
-> FilePath -- ^ log filename (opened in append mode)
|
-> FilePath -- ^ log filename (opened in append mode)
|
||||||
-> Maybe [(String, String)] -- ^ optional environment
|
-> Maybe [(String, String)] -- ^ optional environment
|
||||||
-> m (Either ProcessError ())
|
-> m (Either ProcessError ())
|
||||||
execLogged exe args chdir lfile env = do
|
execLogged exe args chdir lfile env' = do
|
||||||
Dirs {..} <- getDirs
|
Dirs {..} <- getDirs
|
||||||
logDebug $ T.pack $ "Running " <> exe <> " with arguments " <> show args
|
logDebug $ T.pack $ "Running " <> exe <> " with arguments " <> show args
|
||||||
let stdoutLogfile = fromGHCupPath logsDir </> lfile <> ".stdout.log"
|
let stdoutLogfile = fromGHCupPath logsDir </> lfile <> ".stdout.log"
|
||||||
stderrLogfile = fromGHCupPath logsDir </> lfile <> ".stderr.log"
|
stderrLogfile = fromGHCupPath logsDir </> lfile <> ".stderr.log"
|
||||||
cp <- createProcessWithMingwPath ((proc exe args)
|
cp <- createProcessWithMingwPath ((proc exe args)
|
||||||
{ cwd = chdir
|
{ cwd = chdir
|
||||||
, env = env
|
, env = env'
|
||||||
, std_in = CreatePipe
|
, std_in = CreatePipe
|
||||||
, std_out = CreatePipe
|
, std_out = CreatePipe
|
||||||
, std_err = CreatePipe
|
, std_err = CreatePipe
|
||||||
})
|
})
|
||||||
fmap (toProcessError exe args)
|
fmap (toProcessError exe args)
|
||||||
$ liftIO
|
$ liftIO
|
||||||
|
$ withRestorePath (env cp)
|
||||||
$ withCreateProcess cp
|
$ withCreateProcess cp
|
||||||
$ \_ mout merr ph ->
|
$ \_ mout merr ph ->
|
||||||
case (mout, merr) of
|
case (mout, merr) of
|
||||||
@@ -213,16 +214,9 @@ exec :: MonadIO m
|
|||||||
-> Maybe FilePath -- ^ optionally chdir into this
|
-> Maybe FilePath -- ^ optionally chdir into this
|
||||||
-> Maybe [(String, String)] -- ^ optional environment
|
-> Maybe [(String, String)] -- ^ optional environment
|
||||||
-> m (Either ProcessError ())
|
-> m (Either ProcessError ())
|
||||||
exec exe args chdir env = do
|
exec exe args chdir env' = do
|
||||||
-- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/375
|
cp <- createProcessWithMingwPath ((proc exe args) { cwd = chdir, env = env' })
|
||||||
forM_ (Map.fromList <$> env) $ \cEnv -> do
|
exit_code <- liftIO $ withRestorePath (env cp) $ withCreateProcess cp $ \_ _ _ p -> waitForProcess p
|
||||||
let paths = ["PATH", "Path"]
|
|
||||||
curPaths = (\x -> maybe [] splitSearchPath (Map.lookup x cEnv)) =<< paths
|
|
||||||
newPath = intercalate [searchPathSeparator] curPaths
|
|
||||||
liftIO $ setEnv "PATH" ""
|
|
||||||
liftIO $ setEnv "Path" newPath
|
|
||||||
cp <- createProcessWithMingwPath ((proc exe args) { cwd = chdir, env = env })
|
|
||||||
exit_code <- liftIO $ withCreateProcess cp $ \_ _ _ p -> waitForProcess p
|
|
||||||
pure $ toProcessError exe args exit_code
|
pure $ toProcessError exe args exit_code
|
||||||
|
|
||||||
-- | Like 'exec', except doesn't add msys2 stuff to PATH.
|
-- | Like 'exec', except doesn't add msys2 stuff to PATH.
|
||||||
@@ -233,13 +227,6 @@ execNoMinGW :: MonadIO m
|
|||||||
-> Maybe [(String, String)] -- ^ optional environment
|
-> Maybe [(String, String)] -- ^ optional environment
|
||||||
-> m (Either ProcessError ())
|
-> m (Either ProcessError ())
|
||||||
execNoMinGW exe args chdir env = do
|
execNoMinGW exe args chdir env = do
|
||||||
-- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/375
|
|
||||||
forM_ (Map.fromList <$> env) $ \cEnv -> do
|
|
||||||
let paths = ["PATH", "Path"]
|
|
||||||
curPaths = (\x -> maybe [] splitSearchPath (Map.lookup x cEnv)) =<< paths
|
|
||||||
newPath = intercalate [searchPathSeparator] curPaths
|
|
||||||
liftIO $ setEnv "PATH" ""
|
|
||||||
liftIO $ setEnv "Path" newPath
|
|
||||||
let cp = (proc exe args) { cwd = chdir, env = env }
|
let cp = (proc exe args) { cwd = chdir, env = env }
|
||||||
exit_code <- liftIO $ withCreateProcess cp $ \_ _ _ p -> waitForProcess p
|
exit_code <- liftIO $ withCreateProcess cp $ \_ _ _ p -> waitForProcess p
|
||||||
pure $ toProcessError exe args exit_code
|
pure $ toProcessError exe args exit_code
|
||||||
@@ -270,7 +257,27 @@ createProcessWithMingwPath cp = do
|
|||||||
newPath = intercalate [searchPathSeparator] (mingWPaths ++ curPaths)
|
newPath = intercalate [searchPathSeparator] (mingWPaths ++ curPaths)
|
||||||
envWithoutPath = foldr (\x y -> Map.delete x y) cEnv paths
|
envWithoutPath = foldr (\x y -> Map.delete x y) cEnv paths
|
||||||
envWithNewPath = Map.insert "Path" newPath envWithoutPath
|
envWithNewPath = Map.insert "Path" newPath envWithoutPath
|
||||||
liftIO $ setEnv "Path" newPath
|
|
||||||
pure $ cp { env = Just $ Map.toList envWithNewPath }
|
pure $ cp { env = Just $ Map.toList envWithNewPath }
|
||||||
|
|
||||||
|
|
||||||
|
withRestorePath :: MonadIO m => Maybe [(String, String)] -- ^ optional env we want to extract 'PATH' from
|
||||||
|
-> m a -- ^ action to perform
|
||||||
|
-> m a
|
||||||
|
withRestorePath env action = do
|
||||||
|
-- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/375
|
||||||
|
oldPATH <- liftIO $ lookupEnv "PATH"
|
||||||
|
oldPath <- liftIO $ lookupEnv "Path"
|
||||||
|
|
||||||
|
forM_ (Map.fromList <$> env) $ \cEnv -> do
|
||||||
|
let paths = ["PATH", "Path"]
|
||||||
|
curPaths = (\x -> maybe [] splitSearchPath (Map.lookup x cEnv)) =<< paths
|
||||||
|
newPath = intercalate [searchPathSeparator] curPaths
|
||||||
|
liftIO $ setEnv "PATH" ""
|
||||||
|
liftIO $ setEnv "Path" newPath
|
||||||
|
liftIO $ print newPath
|
||||||
|
|
||||||
|
r <- action
|
||||||
|
liftIO $ maybe (unsetEnv "PATH") (setEnv "PATH") oldPATH
|
||||||
|
liftIO $ maybe (unsetEnv "Path") (setEnv "Path") oldPath
|
||||||
|
pure r
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user