1 {-# LANGUAGE DeriveDataTypeable #-}
2 {-# LANGUAGE DeriveGeneric #-}
4 module Distribution
.Types
.SourceRepo
15 import Distribution
.Compat
.Prelude
18 import Distribution
.Utils
.Generic
(lowercase
)
20 import Distribution
.Parsec
21 import Distribution
.Pretty
23 import qualified Data
.Map
.Strict
as M
24 import qualified Distribution
.Compat
.CharParsing
as P
25 import qualified Text
.PrettyPrint
as Disp
27 -- ------------------------------------------------------------
31 -- ------------------------------------------------------------
33 -- | Information about the source revision control system for a package.
35 -- When specifying a repo it is useful to know the meaning or intention of the
36 -- information as doing so enables automation. There are two obvious common
37 -- purposes: one is to find the repo for the latest development version, the
38 -- other is to find the repo for this specific release. The 'ReopKind'
39 -- specifies which one we mean (or another custom one).
41 -- A package can specify one or the other kind or both. Most will specify just
42 -- a head repo but some may want to specify a repo to reconstruct the sources
43 -- for this package release.
45 -- The required information is the 'RepoType' which tells us if it's using
46 -- 'Darcs', 'Git' for example. The 'repoLocation' and other details are
47 -- interpreted according to the repo type.
48 data SourceRepo
= SourceRepo
49 { repoKind
:: RepoKind
50 -- ^ The kind of repo. This field is required.
51 , repoType
:: Maybe RepoType
52 -- ^ The type of the source repository system for this repo, eg 'Darcs' or
53 -- 'Git'. This field is required.
54 , repoLocation
:: Maybe String
55 -- ^ The location of the repository. For most 'RepoType's this is a URL.
56 -- This field is required.
57 , repoModule
:: Maybe String
58 -- ^ 'CVS' can put multiple \"modules\" on one server and requires a
59 -- module name in addition to the location to identify a particular repo.
60 -- Logically this is part of the location but unfortunately has to be
61 -- specified separately. This field is required for the 'CVS' 'RepoType' and
62 -- should not be given otherwise.
63 , repoBranch
:: Maybe String
64 -- ^ The name or identifier of the branch, if any. Many source control
65 -- systems have the notion of multiple branches in a repo that exist in the
66 -- same location. For example 'Git' and 'CVS' use this while systems like
67 -- 'Darcs' use different locations for different branches. This field is
68 -- optional but should be used if necessary to identify the sources,
69 -- especially for the 'RepoThis' repo kind.
70 , repoTag
:: Maybe String
71 -- ^ The tag identify a particular state of the repository. This should be
72 -- given for the 'RepoThis' repo kind and not for 'RepoHead' kind.
73 , repoSubdir
:: Maybe FilePath
74 -- ^ Some repositories contain multiple projects in different subdirectories
75 -- This field specifies the subdirectory where this packages sources can be
76 -- found, eg the subdirectory containing the @.cabal@ file. It is interpreted
77 -- relative to the root of the repository. This field is optional. If not
78 -- given the default is \".\" ie no subdirectory.
80 deriving (Eq
, Ord
, Generic
, Read, Show, Typeable
, Data
)
82 emptySourceRepo
:: RepoKind
-> SourceRepo
83 emptySourceRepo kind
=
87 , repoLocation
= Nothing
88 , repoModule
= Nothing
89 , repoBranch
= Nothing
91 , repoSubdir
= Nothing
94 instance Binary SourceRepo
95 instance Structured SourceRepo
96 instance NFData SourceRepo
where rnf
= genericRnf
98 -- | What this repo info is for, what it represents.
100 = -- | The repository for the \"head\" or development version of the project.
101 -- This repo is where we should track the latest development activity or
102 -- the usual repo people should get to contribute patches.
104 |
-- | The repository containing the sources for this exact package version
105 -- or release. For this kind of repo a tag should be given to give enough
106 -- information to re-create the exact sources.
108 | RepoKindUnknown
String
109 deriving (Eq
, Generic
, Ord
, Read, Show, Typeable
, Data
)
111 instance Binary RepoKind
112 instance Structured RepoKind
113 instance NFData RepoKind
where rnf
= genericRnf
115 -- | An enumeration of common source control systems. The fields used in the
116 -- 'SourceRepo' depend on the type of repo. The tools and methods used to
117 -- obtain and track the repo depend on the repo type.
127 |
-- | @since 3.4.0.0
129 deriving (Eq
, Generic
, Ord
, Read, Show, Typeable
, Data
, Enum
, Bounded
)
131 instance Binary KnownRepoType
132 instance Structured KnownRepoType
133 instance NFData KnownRepoType
where rnf
= genericRnf
135 instance Parsec KnownRepoType
where
137 str
<- P
.munch1 isIdent
139 (P
.unexpected
$ "Could not parse KnownRepoType from " ++ str
)
141 (M
.lookup str knownRepoTypeMap
)
143 instance Pretty KnownRepoType
where
144 pretty
= Disp
.text
. lowercase
. show
147 = KnownRepoType KnownRepoType
148 | OtherRepoType
String
149 deriving (Eq
, Generic
, Ord
, Read, Show, Typeable
, Data
)
151 instance Binary RepoType
152 instance Structured RepoType
153 instance NFData RepoType
where rnf
= genericRnf
155 knownRepoTypes
:: [KnownRepoType
]
156 knownRepoTypes
= [minBound .. maxBound]
158 repoTypeAliases
:: KnownRepoType
-> [String]
159 repoTypeAliases Bazaar
= ["bzr"]
160 repoTypeAliases Mercurial
= ["hg"]
161 repoTypeAliases GnuArch
= ["arch"]
162 repoTypeAliases _
= []
164 instance Pretty RepoKind
where
165 pretty RepoHead
= Disp
.text
"head"
166 pretty RepoThis
= Disp
.text
"this"
167 pretty
(RepoKindUnknown other
) = Disp
.text other
169 instance Parsec RepoKind
where
170 parsec
= classifyRepoKind
<$> P
.munch1 isIdent
172 classifyRepoKind
:: String -> RepoKind
173 classifyRepoKind name
= case lowercase name
of
176 _
-> RepoKindUnknown name
178 instance Parsec RepoType
where
179 parsec
= classifyRepoType
<$> P
.munch1 isIdent
181 instance Pretty RepoType
where
182 pretty
(OtherRepoType other
) = Disp
.text other
183 pretty
(KnownRepoType t
) = pretty t
185 classifyRepoType
:: String -> RepoType
190 (M
.lookup (lowercase s
) knownRepoTypeMap
)
192 knownRepoTypeMap
:: Map
String KnownRepoType
196 | repoType
' <- knownRepoTypes
197 , name
<- prettyShow repoType
' : repoTypeAliases repoType
'
200 isIdent
:: Char -> Bool
201 isIdent c
= isAlphaNum c || c
== '_
' || c
== '-'