Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
C
Cabal
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Requirements
Requirements
List
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Environments
Packages & Registries
Packages & Registries
Package Registry
Container Registry
Analytics
Analytics
CI / CD
Insights
Issue
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
Glasgow Haskell Compiler
Packages
Cabal
Commits
c9c0cb35
Unverified
Commit
c9c0cb35
authored
May 07, 2020
by
Oleg Grenrus
Committed by
GitHub
May 07, 2020
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #6724 from haskell/active-repositories
Add active-repositories configuration
parents
10051c3c
87cf8604
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
434 additions
and
124 deletions
+434
-124
Cabal/Distribution/Utils/GrammarRegex.hs
Cabal/Distribution/Utils/GrammarRegex.hs
+1
-1
Cabal/doc/cabal-project.rst
Cabal/doc/cabal-project.rst
+31
-9
Cabal/doc/installing-packages.rst
Cabal/doc/installing-packages.rst
+2
-14
cabal-install/Distribution/Client/Config.hs
cabal-install/Distribution/Client/Config.hs
+1
-0
cabal-install/Distribution/Client/Get.hs
cabal-install/Distribution/Client/Get.hs
+6
-3
cabal-install/Distribution/Client/GlobalFlags.hs
cabal-install/Distribution/Client/GlobalFlags.hs
+41
-35
cabal-install/Distribution/Client/IndexUtils.hs
cabal-install/Distribution/Client/IndexUtils.hs
+45
-22
cabal-install/Distribution/Client/IndexUtils/ActiveRepos.hs
cabal-install/Distribution/Client/IndexUtils/ActiveRepos.hs
+196
-0
cabal-install/Distribution/Client/Install.hs
cabal-install/Distribution/Client/Install.hs
+1
-1
cabal-install/Distribution/Client/ProjectConfig.hs
cabal-install/Distribution/Client/ProjectConfig.hs
+1
-0
cabal-install/Distribution/Client/ProjectConfig/Legacy.hs
cabal-install/Distribution/Client/ProjectConfig/Legacy.hs
+3
-0
cabal-install/Distribution/Client/ProjectConfig/Types.hs
cabal-install/Distribution/Client/ProjectConfig/Types.hs
+4
-0
cabal-install/Distribution/Client/ProjectPlanning.hs
cabal-install/Distribution/Client/ProjectPlanning.hs
+4
-3
cabal-install/Distribution/Client/Setup.hs
cabal-install/Distribution/Client/Setup.hs
+12
-0
cabal-install/Distribution/Solver/Types/PackageIndex.hs
cabal-install/Distribution/Solver/Types/PackageIndex.hs
+12
-0
cabal-install/cabal-install.cabal
cabal-install/cabal-install.cabal
+1
-0
cabal-install/cabal-install.cabal.pp
cabal-install/cabal-install.cabal.pp
+1
-0
cabal-install/tests/UnitTests/Distribution/Client/ArbitraryInstances.hs
...tests/UnitTests/Distribution/Client/ArbitraryInstances.hs
+19
-0
cabal-install/tests/UnitTests/Distribution/Client/Described.hs
...-install/tests/UnitTests/Distribution/Client/Described.hs
+7
-4
cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs
...tall/tests/UnitTests/Distribution/Client/ProjectConfig.hs
+39
-32
cabal-install/tests/UnitTests/Distribution/Client/TreeDiffInstances.hs
.../tests/UnitTests/Distribution/Client/TreeDiffInstances.hs
+4
-0
changelog.d/active-repositories
changelog.d/active-repositories
+3
-0
No files found.
Cabal/Distribution/Utils/GrammarRegex.hs
View file @
c9c0cb35
...
...
@@ -50,7 +50,7 @@ data GrammarRegex a
|
RESpaces
-- ^ zero-or-more spaces
|
RESpaces1
-- ^ one-or-more spaces
|
RECommaList
(
GrammarRegex
a
)
-- ^ comma list (note, leading or trailing commas)
|
RECommaNonEmpty
(
GrammarRegex
a
)
-- ^ comma non-empty list
|
RECommaNonEmpty
(
GrammarRegex
a
)
-- ^ comma non-empty list
(note, leading or trailing commas)
|
REOptCommaList
(
GrammarRegex
a
)
-- ^ opt comma list
|
RETodo
-- ^ unspecified
...
...
Cabal/doc/cabal-project.rst
View file @
c9c0cb35
...
...
@@ -433,6 +433,37 @@ The following settings control the behavior of the dependency solver:
--
for
storing
`--
index
-
state
`
values
.
index
-
state
:
2016
-
09
-
24
T17
:
47
:
48
Z
--
Specify
different
index
-
states
per
package
repository
--
Supported
since
3.4
index
-
state
:
,
hackage
.
haskell
.
org
2020
-
05
-
06
T22
:
33
:
27
Z
,
head
.
hackage
2020
-
04
-
29
T04
:
11
:
05
Z
..
cfg
-
field
::
active
-
repositories
:
reponame1
,
reponame2
:
synopsis
:
Specify
active
package
repositories
:
since
:
3.4
:
default
:
``:
rest
``
This
allows
to
specify
the
active
package
repositories
,
when
multiple
are
specified
.
This
is
useful
as
you
can
specify
the
order
and
the
way
active
repositories
are
merged
.
::
--
for
packages
in
head
.
hackage
--
only
versions
in
head
.
hackage
are
considered
active
-
repositories
:
,
hackage
.
haskell
.
org
,
head
.
hackage
:
override
--
Force
head
.
hackage
to
be
the
primary
repository
considered
active
-
repositories
:
:
rest
,
head
.
hackage
--
"Offline"
mode
active
-
repositories
:
none
..
cfg
-
field
::
reject
-
unconstrained
-
dependencies
:
all
,
none
--
reject
-
unconstrained
-
dependencies
=[
all
|
none
]
...
...
@@ -1377,15 +1408,6 @@ Advanced global configuration options
The
command
line
variant
of
this
flag
is
``--
build
-
summary
=
TEMPLATE
``.
..
cfg
-
field
::
local
-
repo
:
directory
--
local
-
repo
=
DIR
:
deprecated
:
[
STRIKEOUT
:
The
location
of
a
local
repository
.]
Deprecated
.
See
"Legacy repositories."
The
command
line
variant
of
this
flag
is
``--
local
-
repo
=
DIR
``.
..
cfg
-
field
::
world
-
file
:
path
--
world
-
file
=
FILE
:
deprecated
:
...
...
Cabal/doc/installing-packages.rst
View file @
c9c0cb35
...
...
@@ -188,8 +188,8 @@ The part of the path will be used to determine the cache key part.
Legacy repositories
^^^^^^^^^^^^^^^^^^^
Currently ``cabal`` supports
two kinds of “legacy” repositories. The
firs
t is specified using
Currently ``cabal`` supports
single kind of “legacy” repositories.
I
t is specified using
::
...
...
@@ -206,18 +206,6 @@ although, in (and only in) the specific case of Hackage, the URL
``http://hackage.haskell.org/packages/archive`` will be silently
translated to ``http://hackage.haskell.org/``.
The second kind of legacy repositories are so-called “(legacy) local”
repositories:
::
local-repo: my-local-repo:/path/to/local/repo
This can be used to access repositories on the local file system.
However, the layout of these local repositories is different from the
layout of remote repositories, and usage of these local repositories is
deprecated.
Secure local repositories
^^^^^^^^^^^^^^^^^^^^^^^^^
...
...
cabal-install/Distribution/Client/Config.hs
View file @
c9c0cb35
...
...
@@ -251,6 +251,7 @@ instance Semigroup SavedConfig where
globalRemoteRepos
=
lastNonEmptyNL
globalRemoteRepos
,
globalCacheDir
=
combine
globalCacheDir
,
globalLocalNoIndexRepos
=
lastNonEmptyNL
globalLocalNoIndexRepos
,
globalActiveRepos
=
combine
globalActiveRepos
,
globalLogsDir
=
combine
globalLogsDir
,
globalWorldFile
=
combine
globalWorldFile
,
globalIgnoreExpiry
=
combine
globalIgnoreExpiry
,
...
...
cabal-install/Distribution/Client/Get.hs
View file @
c9c0cb35
...
...
@@ -51,8 +51,8 @@ import Distribution.Client.Dependency
import
Distribution.Client.VCS
import
Distribution.Client.FetchUtils
import
qualified
Distribution.Client.Tar
as
Tar
(
extractTarGzFile
)
import
Distribution.Client.IndexUtils
as
IndexUtils
(
getSourcePackagesAtIndexState
,
TotalIndexState
)
import
Distribution.Client.IndexUtils
(
getSourcePackagesAtIndexState
,
TotalIndexState
,
ActiveRepos
)
import
Distribution.Solver.Types.SourcePackage
import
Control.Exception
...
...
@@ -89,7 +89,10 @@ get verbosity repoCtxt globalFlags getFlags userTargets = do
let
idxState
::
Maybe
TotalIndexState
idxState
=
flagToMaybe
$
getIndexState
getFlags
(
sourcePkgDb
,
_
)
<-
getSourcePackagesAtIndexState
verbosity
repoCtxt
idxState
activeRepos
::
Maybe
ActiveRepos
activeRepos
=
flagToMaybe
$
getActiveRepos
getFlags
(
sourcePkgDb
,
_
)
<-
getSourcePackagesAtIndexState
verbosity
repoCtxt
idxState
activeRepos
pkgSpecifiers
<-
resolveUserTargets
verbosity
repoCtxt
(
fromFlag
$
globalWorldFile
globalFlags
)
...
...
cabal-install/Distribution/Client/GlobalFlags.hs
View file @
c9c0cb35
...
...
@@ -29,6 +29,9 @@ import Distribution.Verbosity
import
Distribution.Simple.Utils
(
info
,
warn
)
import
Distribution.Client.IndexUtils.ActiveRepos
(
ActiveRepos
)
import
Control.Concurrent
(
MVar
,
newMVar
,
modifyMVar
)
import
Control.Exception
...
...
@@ -55,47 +58,50 @@ import qualified System.FilePath.Posix as FilePath.Posix
-- ------------------------------------------------------------
-- | Flags that apply at the top level, not to any sub-command.
data
GlobalFlags
=
GlobalFlags
{
globalVersion
::
Flag
Bool
,
globalNumericVersion
::
Flag
Bool
,
globalConfigFile
::
Flag
FilePath
,
globalConstraintsFile
::
Flag
FilePath
,
globalRemoteRepos
::
NubList
RemoteRepo
,
-- ^ Available Hackage servers.
globalCacheDir
::
Flag
FilePath
,
globalLocalNoIndexRepos
::
NubList
LocalRepo
,
globalLogsDir
::
Flag
FilePath
,
globalWorldFile
::
Flag
FilePath
,
globalIgnoreExpiry
::
Flag
Bool
,
-- ^ Ignore security expiry dates
globalHttpTransport
::
Flag
String
,
globalNix
::
Flag
Bool
,
-- ^ Integrate with Nix
globalStoreDir
::
Flag
FilePath
,
globalProgPathExtra
::
NubList
FilePath
-- ^ Extra program path used for packagedb lookups in a global context (i.e. for http transports)
}
deriving
Generic
data
GlobalFlags
=
GlobalFlags
{
globalVersion
::
Flag
Bool
,
globalNumericVersion
::
Flag
Bool
,
globalConfigFile
::
Flag
FilePath
,
globalConstraintsFile
::
Flag
FilePath
,
globalRemoteRepos
::
NubList
RemoteRepo
-- ^ Available Hackage servers.
,
globalCacheDir
::
Flag
FilePath
,
globalLocalNoIndexRepos
::
NubList
LocalRepo
,
globalActiveRepos
::
Flag
ActiveRepos
,
globalLogsDir
::
Flag
FilePath
,
globalWorldFile
::
Flag
FilePath
,
globalIgnoreExpiry
::
Flag
Bool
-- ^ Ignore security expiry dates
,
globalHttpTransport
::
Flag
String
,
globalNix
::
Flag
Bool
-- ^ Integrate with Nix
,
globalStoreDir
::
Flag
FilePath
,
globalProgPathExtra
::
NubList
FilePath
-- ^ Extra program path used for packagedb lookups in a global context (i.e. for http transports)
}
deriving
Generic
defaultGlobalFlags
::
GlobalFlags
defaultGlobalFlags
=
GlobalFlags
{
globalVersion
=
Flag
False
,
globalNumericVersion
=
Flag
False
,
globalConfigFile
=
mempty
,
globalConstraintsFile
=
mempty
,
globalRemoteRepos
=
mempty
,
globalCacheDir
=
mempty
,
globalLocalNoIndexRepos
=
mempty
,
globalLogsDir
=
mempty
,
globalWorldFile
=
mempty
,
globalIgnoreExpiry
=
Flag
False
,
globalHttpTransport
=
mempty
,
globalNix
=
Flag
False
,
globalStoreDir
=
mempty
,
globalProgPathExtra
=
mempty
}
defaultGlobalFlags
=
GlobalFlags
{
globalVersion
=
Flag
False
,
globalNumericVersion
=
Flag
False
,
globalConfigFile
=
mempty
,
globalConstraintsFile
=
mempty
,
globalRemoteRepos
=
mempty
,
globalCacheDir
=
mempty
,
globalLocalNoIndexRepos
=
mempty
,
globalActiveRepos
=
mempty
,
globalLogsDir
=
mempty
,
globalWorldFile
=
mempty
,
globalIgnoreExpiry
=
Flag
False
,
globalHttpTransport
=
mempty
,
globalNix
=
Flag
False
,
globalStoreDir
=
mempty
,
globalProgPathExtra
=
mempty
}
instance
Monoid
GlobalFlags
where
mempty
=
gmempty
mappend
=
(
<>
)
mempty
=
gmempty
mappend
=
(
<>
)
instance
Semigroup
GlobalFlags
where
(
<>
)
=
gmappend
(
<>
)
=
gmappend
-- ------------------------------------------------------------
-- * Repo context
...
...
cabal-install/Distribution/Client/IndexUtils.hs
View file @
c9c0cb35
...
...
@@ -28,6 +28,7 @@ module Distribution.Client.IndexUtils (
TotalIndexState
,
getSourcePackagesAtIndexState
,
ActiveRepos
,
Index
(
..
),
RepoIndexState
(
..
),
...
...
@@ -48,6 +49,7 @@ import qualified Codec.Archive.Tar as Tar
import
qualified
Codec.Archive.Tar.Entry
as
Tar
import
qualified
Codec.Archive.Tar.Index
as
Tar
import
qualified
Distribution.Client.Tar
as
Tar
import
Distribution.Client.IndexUtils.ActiveRepos
import
Distribution.Client.IndexUtils.IndexState
import
Distribution.Client.IndexUtils.Timestamp
import
Distribution.Client.Types
...
...
@@ -69,8 +71,9 @@ import Distribution.Simple.Program
(
ProgramDb
)
import
qualified
Distribution.Simple.Configure
as
Configure
(
getInstalledPackages
,
getInstalledPackagesMonitorFiles
)
import
Distribution.Types.PackageName
(
PackageName
)
import
Distribution.Version
(
Version
,
mkVersion
,
intersectVersionRanges
)
(
Version
,
VersionRange
,
mkVersion
,
intersectVersionRanges
)
import
Distribution.Deprecated.Text
(
display
,
simpleParse
)
import
Distribution.Simple.Utils
...
...
@@ -197,7 +200,7 @@ filterCache (IndexStateTime ts0) cache0 = (cache, IndexStateInfo{..})
-- This is a higher level wrapper used internally in cabal-install.
getSourcePackages
::
Verbosity
->
RepoContext
->
IO
SourcePackageDb
getSourcePackages
verbosity
repoCtxt
=
fst
<$>
getSourcePackagesAtIndexState
verbosity
repoCtxt
Nothing
fst
<$>
getSourcePackagesAtIndexState
verbosity
repoCtxt
Nothing
Nothing
-- | Variant of 'getSourcePackages' which allows getting the source
-- packages at a particular 'IndexState'.
...
...
@@ -212,8 +215,9 @@ getSourcePackagesAtIndexState
::
Verbosity
->
RepoContext
->
Maybe
TotalIndexState
->
Maybe
ActiveRepos
->
IO
(
SourcePackageDb
,
TotalIndexState
)
getSourcePackagesAtIndexState
verbosity
repoCtxt
_
getSourcePackagesAtIndexState
verbosity
repoCtxt
_
_
|
null
(
repoContextRepos
repoCtxt
)
=
do
-- In the test suite, we routinely don't have any remote package
-- servers, so don't bleat about it
...
...
@@ -224,7 +228,7 @@ getSourcePackagesAtIndexState verbosity repoCtxt _
packageIndex
=
mempty
,
packagePreferences
=
mempty
},
headTotalIndexState
)
getSourcePackagesAtIndexState
verbosity
repoCtxt
mb_idxState
=
do
getSourcePackagesAtIndexState
verbosity
repoCtxt
mb_idxState
mb_activeRepos
=
do
let
describeState
IndexStateHead
=
"most recent state"
describeState
(
IndexStateTime
time
)
=
"historical state as of "
++
prettyShow
time
...
...
@@ -288,40 +292,59 @@ getSourcePackagesAtIndexState verbosity repoCtxt mb_idxState = do
prettyShow
(
isiHeadTime
isi
)
++
")"
)
pure
RepoData
{
rdIndexStates
=
[(
rname
,
isiMaxTime
isi
)]
{
rdRepoName
=
rname
,
rdTimeStamp
=
isiMaxTime
isi
,
rdIndex
=
pis
,
rdPreferences
=
deps
}
let
RepoData
indexStates
pkgs
prefs
=
mconcat
pkgss
prefs'
=
Map
.
fromListWith
intersectVersionRanges
[
(
name
,
range
)
|
Dependency
name
range
_
<-
prefs
]
totalIndexState
=
foldl'
(
\
acc
(
rn
,
ts
)
->
insertIndexState
rn
(
IndexStateTime
ts
)
acc
)
headTotalIndexState
indexStates
let
activeRepos
::
ActiveRepos
activeRepos
=
fromMaybe
defaultActiveRepos
mb_activeRepos
pkgss'
<-
case
organizeByRepos
activeRepos
rdRepoName
pkgss
of
Right
x
->
return
x
Left
err
->
warn
verbosity
err
>>
return
(
map
(
\
x
->
(
x
,
CombineStrategyMerge
))
pkgss
)
let
totalIndexState
::
TotalIndexState
totalIndexState
=
makeTotalIndexState
IndexStateHead
$
Map
.
fromList
[
(
n
,
IndexStateTime
ts
)
|
(
RepoData
n
ts
_idx
_prefs
,
_strategy
)
<-
pkgss'
]
let
addIndex
::
PackageIndex
UnresolvedSourcePackage
->
(
RepoData
,
CombineStrategy
)
->
PackageIndex
UnresolvedSourcePackage
addIndex
acc
(
RepoData
_
_
idx
_
,
CombineStrategyMerge
)
=
PackageIndex
.
merge
acc
idx
addIndex
acc
(
RepoData
_
_
idx
_
,
CombineStrategyOverride
)
=
PackageIndex
.
override
acc
idx
let
pkgs
::
PackageIndex
UnresolvedSourcePackage
pkgs
=
foldl'
addIndex
mempty
pkgss'
-- Note: preferences combined without using CombineStrategy
let
prefs
::
Map
PackageName
VersionRange
prefs
=
Map
.
fromListWith
intersectVersionRanges
[
(
name
,
range
)
|
(
RepoData
_n
_ts
_idx
prefs'
,
_strategy
)
<-
pkgss'
,
Dependency
name
range
_
<-
prefs'
]
_
<-
evaluate
pkgs
_
<-
evaluate
prefs
'
_
<-
evaluate
prefs
_
<-
evaluate
totalIndexState
return
(
SourcePackageDb
{
packageIndex
=
pkgs
,
packagePreferences
=
prefs
'
packagePreferences
=
prefs
},
totalIndexState
)
-- auxiliary data used in getSourcePackagesAtIndexState
data
RepoData
=
RepoData
{
rdIndexStates
::
[(
RepoName
,
Timestamp
)]
{
rdRepoName
::
RepoName
,
rdTimeStamp
::
Timestamp
,
rdIndex
::
PackageIndex
UnresolvedSourcePackage
,
rdPreferences
::
[
Dependency
]
}
instance
Semigroup
RepoData
where
RepoData
x
y
z
<>
RepoData
u
v
w
=
RepoData
(
x
<>
u
)
(
y
<>
v
)
(
z
<>
w
)
instance
Monoid
RepoData
where
mempty
=
RepoData
mempty
mempty
mempty
mappend
=
(
<>
)
-- | Read a repository index from disk, from the local file specified by
-- the 'Repo'.
--
...
...
cabal-install/Distribution/Client/IndexUtils/ActiveRepos.hs
0 → 100644
View file @
c9c0cb35
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module
Distribution.Client.IndexUtils.ActiveRepos
(
ActiveRepos
(
..
),
defaultActiveRepos
,
ActiveRepoEntry
(
..
),
CombineStrategy
(
..
),
organizeByRepos
,
)
where
import
Distribution.Client.Compat.Prelude
import
Distribution.Client.Types.RepoName
(
RepoName
(
..
))
import
Prelude
()
import
Distribution.FieldGrammar.Described
import
Distribution.Parsec
(
Parsec
(
..
),
parsecLeadingCommaList
)
import
Distribution.Pretty
(
Pretty
(
..
),
prettyShow
)
import
qualified
Distribution.Compat.CharParsing
as
P
import
qualified
Text.PrettyPrint
as
Disp
-- $setup
-- >>> import Distribution.Parsec
-------------------------------------------------------------------------------
-- Types
-------------------------------------------------------------------------------
-- | Ordered list of active repositories.
newtype
ActiveRepos
=
ActiveRepos
[
ActiveRepoEntry
]
deriving
(
Eq
,
Show
,
Generic
)
defaultActiveRepos
::
ActiveRepos
defaultActiveRepos
=
ActiveRepos
[
ActiveRepoRest
CombineStrategyMerge
]
instance
Binary
ActiveRepos
instance
Structured
ActiveRepos
instance
NFData
ActiveRepos
instance
Pretty
ActiveRepos
where
pretty
(
ActiveRepos
[]
)
=
Disp
.
text
":none"
pretty
(
ActiveRepos
repos
)
=
Disp
.
hsep
$
Disp
.
punctuate
Disp
.
comma
$
map
pretty
repos
-- | Note: empty string is not valid 'ActiveRepos'.
--
-- >>> simpleParsec "" :: Maybe ActiveRepos
-- Nothing
--
-- >>> simpleParsec ":none" :: Maybe ActiveRepos
-- Just (ActiveRepos [])
--
-- >>> simpleParsec ":rest" :: Maybe ActiveRepos
-- Just (ActiveRepos [ActiveRepoRest CombineStrategyMerge])
--
-- >>> simpleParsec "hackage.haskell.org, :rest, head.hackage:override" :: Maybe ActiveRepos
-- Just (ActiveRepos [ActiveRepo (RepoName "hackage.haskell.org") CombineStrategyMerge,ActiveRepoRest CombineStrategyMerge,ActiveRepo (RepoName "head.hackage") CombineStrategyOverride])
--
instance
Parsec
ActiveRepos
where
parsec
=
ActiveRepos
[]
<$
P
.
try
(
P
.
string
":none"
)
<|>
do
repos
<-
parsecLeadingCommaList
parsec
return
(
ActiveRepos
(
toList
repos
))
instance
Described
ActiveRepos
where
describe
_
=
REUnion
[
":none"
,
RECommaNonEmpty
(
describe
(
Proxy
::
Proxy
ActiveRepoEntry
))
]
data
ActiveRepoEntry
=
ActiveRepoRest
CombineStrategy
-- ^ rest repositories, i.e. not explicitly listed as 'ActiveRepo'
|
ActiveRepo
RepoName
CombineStrategy
-- ^ explicit repository name
deriving
(
Eq
,
Show
,
Generic
)
instance
Binary
ActiveRepoEntry
instance
Structured
ActiveRepoEntry
instance
NFData
ActiveRepoEntry
instance
Pretty
ActiveRepoEntry
where
pretty
(
ActiveRepoRest
s
)
=
Disp
.
text
":rest"
<<>>
Disp
.
colon
<<>>
pretty
s
pretty
(
ActiveRepo
r
s
)
=
pretty
r
<<>>
Disp
.
colon
<<>>
pretty
s
instance
Parsec
ActiveRepoEntry
where
parsec
=
leadColon
<|>
leadRepo
where
leadColon
=
do
_
<-
P
.
char
':'
token
<-
P
.
munch1
isAlpha
case
token
of
"rest"
->
ActiveRepoRest
<$>
strategyP
"repo"
->
P
.
char
':'
*>
leadRepo
_
->
P
.
unexpected
$
"Unknown active repository entry type: "
++
token
leadRepo
=
do
r
<-
parsec
s
<-
strategyP
return
(
ActiveRepo
r
s
)
strategyP
=
P
.
option
CombineStrategyMerge
(
P
.
char
':'
*>
parsec
)
instance
Described
ActiveRepoEntry
where
describe
_
=
REUnion
[
":rest"
<>
strategy
,
REOpt
":repo:"
<>
describe
(
Proxy
::
Proxy
RepoName
)
<>
strategy
]
where
strategy
=
REOpt
$
":"
<>
describe
(
Proxy
::
Proxy
CombineStrategy
)
data
CombineStrategy
=
CombineStrategyMerge
-- ^ merge existing versions
|
CombineStrategyOverride
-- ^ if later repository specifies a package,
-- all package versions are replaced
deriving
(
Eq
,
Show
,
Enum
,
Bounded
,
Generic
)
instance
Binary
CombineStrategy
instance
Structured
CombineStrategy
instance
NFData
CombineStrategy
instance
Pretty
CombineStrategy
where
pretty
CombineStrategyMerge
=
Disp
.
text
"merge"
pretty
CombineStrategyOverride
=
Disp
.
text
"override"
instance
Parsec
CombineStrategy
where
parsec
=
P
.
choice
[
CombineStrategyMerge
<$
P
.
string
"merge"
,
CombineStrategyOverride
<$
P
.
string
"override"
]
instance
Described
CombineStrategy
where
describe
_
=
REUnion
[
"merge"
,
"override"
]
-------------------------------------------------------------------------------
-- Organisation
-------------------------------------------------------------------------------
-- | Sort values 'RepoName' according to 'ActiveRepos' list.
--
-- >>> let repos = [RepoName "a", RepoName "b", RepoName "c"]
-- >>> organizeByRepos (ActiveRepos [ActiveRepoRest CombineStrategyMerge]) id repos
-- Right [(RepoName "a",CombineStrategyMerge),(RepoName "b",CombineStrategyMerge),(RepoName "c",CombineStrategyMerge)]
--
-- >>> organizeByRepos (ActiveRepos [ActiveRepo (RepoName "b") CombineStrategyOverride, ActiveRepoRest CombineStrategyMerge]) id repos
-- Right [(RepoName "b",CombineStrategyOverride),(RepoName "a",CombineStrategyMerge),(RepoName "c",CombineStrategyMerge)]
--
-- >>> organizeByRepos (ActiveRepos [ActiveRepoRest CombineStrategyMerge, ActiveRepo (RepoName "b") CombineStrategyOverride]) id repos
-- Right [(RepoName "a",CombineStrategyMerge),(RepoName "c",CombineStrategyMerge),(RepoName "b",CombineStrategyOverride)]
--
-- >>> organizeByRepos (ActiveRepos [ActiveRepoRest CombineStrategyMerge, ActiveRepo (RepoName "d") CombineStrategyOverride]) id repos
-- Left "no repository provided d"
--
-- Note: currently if 'ActiveRepoRest' is provided more than once,
-- rest-repositories will be multiple times in the output.
--
organizeByRepos
::
forall
a
.
ActiveRepos
->
(
a
->
RepoName
)
->
[
a
]
->
Either
String
[(
a
,
CombineStrategy
)]
organizeByRepos
(
ActiveRepos
xs0
)
sel
ys0
=
-- here we use lazyness to do only one traversal
let
(
rest
,
result
)
=
case
go
rest
xs0
ys0
of
Right
(
rest'
,
result'
)
->
(
rest'
,
Right
result'
)
Left
err
->
(
[]
,
Left
err
)
in
result
where
go
::
[
a
]
->
[
ActiveRepoEntry
]
->
[
a
]
->
Either
String
([
a
],
[(
a
,
CombineStrategy
)])
go
_rest
[]
ys
=
Right
(
ys
,
[]
)
go
rest
(
ActiveRepoRest
s
:
xs
)
ys
=
go
rest
xs
ys
<&>
\
(
rest'
,
result
)
->
(
rest'
,
map
(
\
x
->
(
x
,
s
))
rest
++
result
)
go
rest
(
ActiveRepo
r
s
:
xs
)
ys
=
do
(
z
,
zs
)
<-
extract
r
ys
go
rest
xs
zs
<&>
\
(
rest'
,
result
)
->
(
rest'
,
(
z
,
s
)
:
result
)
extract
::
RepoName
->
[
a
]
->
Either
String
(
a
,
[
a
])
extract
r
=
loop
id
where
loop
_acc
[]
=
Left
$
"no repository provided "
++
prettyShow
r
loop
acc
(
x
:
xs
)
|
sel
x
==
r
=
Right
(
x
,
acc
xs
)
|
otherwise
=
loop
(
acc
.
(
x
:
))
xs
(
<&>
)
::
Either
err
([
s
],
b
)
->
(([
s
],
b
)
->
([
s
],
c
))
->
Either
err
([
s
],
c
)
(
<&>
)
=
flip
fmap
cabal-install/Distribution/Client/Install.hs
View file @
c9c0cb35
...
...
@@ -272,7 +272,7 @@ makeInstallContext verbosity
let
idxState
=
flagToMaybe
(
installIndexState
installFlags
)
installedPkgIndex
<-
getInstalledPackages
verbosity
comp
packageDBs
progdb
(
sourcePkgDb
,
_
)
<-
getSourcePackagesAtIndexState
verbosity
repoCtxt
idxState
(
sourcePkgDb
,
_
)
<-
getSourcePackagesAtIndexState
verbosity
repoCtxt
idxState
Nothing
pkgConfigDb
<-
readPkgConfigDb
verbosity
progdb
checkConfigExFlags
verbosity
installedPkgIndex
...
...
cabal-install/Distribution/Client/ProjectConfig.hs
View file @
c9c0cb35
...
...
@@ -253,6 +253,7 @@ resolveSolverSettings ProjectConfig{
solverSettingAllowBootLibInstalls
=
fromFlag
projectConfigAllowBootLibInstalls
solverSettingOnlyConstrained
=
fromFlag
projectConfigOnlyConstrained
solverSettingIndexState
=
flagToMaybe
projectConfigIndexState
solverSettingActiveRepos
=
flagToMaybe
projectConfigActiveRepos
solverSettingIndependentGoals
=
fromFlag
projectConfigIndependentGoals
--solverSettingShadowPkgs = fromFlag projectConfigShadowPkgs
--solverSettingReinstall = fromFlag projectConfigReinstall
...
...
cabal-install/Distribution/Client/ProjectConfig/Legacy.hs
View file @
c9c0cb35
...
...
@@ -335,6 +335,7 @@ convertLegacyAllPackageFlags globalFlags configFlags
globalConfigFile
=
projectConfigConfigFile
,
globalRemoteRepos
=
projectConfigRemoteRepos
,
globalLocalNoIndexRepos
=
projectConfigLocalNoIndexRepos
,
globalActiveRepos
=
projectConfigActiveRepos
,
globalProgPathExtra
=
projectConfigProgPathExtra
,
globalStoreDir
=
projectConfigStoreDir
}
=
globalFlags
...
...
@@ -569,6 +570,7 @@ convertToLegacySharedConfig
globalRemoteRepos
=
projectConfigRemoteRepos
,
globalCacheDir
=
projectConfigCacheDir
,
globalLocalNoIndexRepos
=
projectConfigLocalNoIndexRepos
,
globalActiveRepos
=
projectConfigActiveRepos
,
globalLogsDir
=
projectConfigLogsDir
,
globalWorldFile
=
mempty
,
globalIgnoreExpiry
=
projectConfigIgnoreExpiry
,
...
...
@@ -939,6 +941,7 @@ legacySharedConfigFieldDescrs =
.
filterFields
[
"remote-repo-cache"
,
"logs-dir"
,
"store-dir"
,
"ignore-expiry"
,
"http-transport"
,
"active-repositories"
]
.
commandOptionsToFields
)
(
commandOptions
(
globalCommand
[]
)
ParseArgs
)
...
...
cabal-install/Distribution/Client/ProjectConfig/Types.hs
View file @
c9c0cb35
...
...
@@ -36,6 +36,8 @@ import Distribution.Client.Types.SourceRepo (SourceRepoList)
import
Distribution.Client.IndexUtils.IndexState
(
TotalIndexState
)
import
Distribution.Client.IndexUtils.ActiveRepos
(
ActiveRepos
)
import
Distribution.Client.CmdInstall.ClientInstallFlags
(
ClientInstallFlags
(
..
)
)
...
...
@@ -180,6 +182,7 @@ data ProjectConfigShared
-- configuration used both by the solver and other phases
projectConfigRemoteRepos
::
NubList
RemoteRepo
,
-- ^ Available Hackage servers.
projectConfigLocalNoIndexRepos
::
NubList
LocalRepo
,
projectConfigActiveRepos
::
Flag
ActiveRepos
,
projectConfigIndexState
::
Flag
TotalIndexState
,
projectConfigStoreDir
::
Flag
FilePath
,
...
...
@@ -406,6 +409,7 @@ data SolverSettings
solverSettingAllowBootLibInstalls
::
AllowBootLibInstalls
,
solverSettingOnlyConstrained
::
OnlyConstrained
,
solverSettingIndexState
::
Maybe
TotalIndexState
,
solverSettingActiveRepos
::
Maybe
ActiveRepos
,
solverSettingIndependentGoals
::
IndependentGoals
-- Things that only make sense for manual mode, not --local mode
-- too much control!
...
...
cabal-install/Distribution/Client/ProjectPlanning.hs