11{-# LANGUAGE OverloadedStrings #-}
2+ {-# LANGUAGE RankNTypes #-}
23{-# LANGUAGE RecordWildCards #-}
34{-# LANGUAGE ViewPatterns #-}
45
78module Dhall.Freeze
89 ( -- * Freeze
910 freeze
10- , freezeWithManager
1111 , freezeExpression
12- , freezeExpressionWithManager
1312 , freezeImport
14- , freezeImportWithManager
1513 , freezeRemoteImport
16- , freezeRemoteImportWithManager
14+
15+ -- * Freeze with custom evaluation settings
16+ , freezeWithSettings
17+ , freezeExpressionWithSettings
18+ , freezeImportWithSettings
19+ , freezeRemoteImportWithSettings
1720
1821 -- * Types
1922 , Scope (.. )
2023 , Intent (.. )
24+
25+ -- * Deprecated functions
26+ , freezeWithManager
27+ , freezeExpressionWithManager
28+ , freezeImportWithManager
29+ , freezeRemoteImportWithManager
2130 ) where
2231
2332import Data.Foldable (for_ )
2433import Data.List.NonEmpty (NonEmpty )
2534import Data.Maybe (fromMaybe )
35+ import Dhall (EvaluateSettings )
2636import Dhall.Pretty (CharacterSet , detectCharacterSet )
2737import Dhall.Syntax
2838 ( Expr (.. )
@@ -39,11 +49,13 @@ import Dhall.Util
3949 , Transitivity (.. )
4050 , handleMultipleChecksFailed
4151 )
52+ import Lens.Family (set , view )
4253import System.Console.ANSI (hSupportsANSI )
4354
4455import qualified Control.Exception as Exception
4556import qualified Control.Monad.Trans.State.Strict as State
4657import qualified Data.Text.IO as Text.IO
58+ import qualified Dhall
4759import qualified Dhall.Core as Core
4860import qualified Dhall.Import
4961import qualified Dhall.Optics
@@ -57,21 +69,120 @@ import qualified System.AtomicWrite.Writer.LazyText as AtomicWrite.LazyText
5769import qualified System.FilePath
5870import qualified System.IO
5971
72+ -- | Specifies which imports to freeze
73+ data Scope
74+ = OnlyRemoteImports
75+ -- ^ Freeze only remote imports (i.e. URLs)
76+ | AllImports
77+ -- ^ Freeze all imports (including paths and environment variables)
78+
79+ -- | Specifies why we are adding semantic integrity checks
80+ data Intent
81+ = Secure
82+ -- ^ Protect imports with an integrity check without a fallback so that
83+ -- import resolution fails if the import changes
84+ | Cache
85+ -- ^ Protect imports with an integrity check and also add a fallback import
86+ -- import without an integrity check. This is useful if you only want to
87+ -- cache imports when possible but still gracefully degrade to resolving
88+ -- them if the semantic integrity check has changed.
89+
6090-- | Retrieve an `Import` and update the hash to match the latest contents
6191freezeImport
6292 :: FilePath
6393 -- ^ Current working directory
6494 -> Import
6595 -> IO Import
66- freezeImport = freezeImportWithManager Dhall.Import. defaultNewManager
96+ freezeImport = freezeImportWithSettings Dhall. defaultEvaluateSettings
6797
6898-- | See 'freezeImport'.
6999freezeImportWithManager
70100 :: IO Dhall.Import. Manager
71101 -> FilePath
72102 -> Import
73103 -> IO Import
74- freezeImportWithManager newManager directory import_ = do
104+ freezeImportWithManager newManager = freezeImportWithSettings (set Dhall. newManager newManager Dhall. defaultEvaluateSettings)
105+ {-# DEPRECATED freezeImportWithManager "Use freezeImportWithSettings directly" #-}
106+
107+ -- | Freeze an import only if the import is a `Remote` import
108+ freezeRemoteImport
109+ :: FilePath
110+ -- ^ Current working directory
111+ -> Import
112+ -> IO Import
113+ freezeRemoteImport = freezeRemoteImportWithSettings Dhall. defaultEvaluateSettings
114+
115+ -- | See 'freezeRemoteImport'.
116+ freezeRemoteImportWithManager
117+ :: IO Dhall.Import. Manager
118+ -> FilePath
119+ -> Import
120+ -> IO Import
121+ freezeRemoteImportWithManager newManager = freezeRemoteImportWithSettings (set Dhall. newManager newManager Dhall. defaultEvaluateSettings)
122+ {-# DEPRECATED freezeRemoteImportWithManager "Use freezeRemoteImportWithSettings directly" #-}
123+
124+ -- | Implementation of the @dhall freeze@ subcommand
125+ freeze
126+ :: OutputMode
127+ -> Transitivity
128+ -> NonEmpty Input
129+ -> Scope
130+ -> Intent
131+ -> Maybe CharacterSet
132+ -> Censor
133+ -> IO ()
134+ freeze = freezeWithSettings Dhall. defaultEvaluateSettings
135+
136+ -- | See 'freeze'.
137+ freezeWithManager
138+ :: IO Dhall.Import. Manager
139+ -> OutputMode
140+ -> Transitivity
141+ -> NonEmpty Input
142+ -> Scope
143+ -> Intent
144+ -> Maybe CharacterSet
145+ -> Censor
146+ -> IO ()
147+ freezeWithManager newManager = freezeWithSettings (set Dhall. newManager newManager Dhall. defaultEvaluateSettings)
148+ {-# DEPRECATED freezeWithManager "Use freezeWithSettings directly" #-}
149+
150+ {-| Slightly more pure version of the `freeze` function
151+
152+ This still requires `IO` to freeze the import, but now the input and output
153+ expression are passed in explicitly
154+ -}
155+ freezeExpression
156+ :: FilePath
157+ -- ^ Starting directory
158+ -> Scope
159+ -> Intent
160+ -> Expr s Import
161+ -> IO (Expr s Import )
162+ freezeExpression = freezeExpressionWithSettings Dhall. defaultEvaluateSettings
163+
164+ -- | See 'freezeExpression'.
165+ freezeExpressionWithManager
166+ :: IO Dhall.Import. Manager
167+ -> FilePath
168+ -> Scope
169+ -> Intent
170+ -> Expr s Import
171+ -> IO (Expr s Import )
172+ freezeExpressionWithManager newManager = freezeExpressionWithSettings (set Dhall. newManager newManager Dhall. defaultEvaluateSettings)
173+ {-# DEPRECATED freezeExpressionWithManager "Use freezeExpressionWithSettings directly" #-}
174+
175+ --------------------------------------------------------------------------------
176+ -- Versions that take EvaluateSettings
177+ --------------------------------------------------------------------------------
178+
179+ -- | See 'freezeImport'.
180+ freezeImportWithSettings
181+ :: EvaluateSettings
182+ -> FilePath
183+ -> Import
184+ -> IO Import
185+ freezeImportWithSettings settings directory import_ = do
75186 let unprotectedImport =
76187 import_
77188 { importHashed =
@@ -80,15 +191,15 @@ freezeImportWithManager newManager directory import_ = do
80191 }
81192 }
82193
83- let status = Dhall.Import. emptyStatusWithManager newManager directory
194+ let status = Dhall.Import. emptyStatusWithManager (view Dhall. newManager settings) directory
84195
85196 expression <- State. evalStateT (Dhall.Import. loadWith (Embed unprotectedImport)) status
86197
87- case Dhall.TypeCheck. typeOf expression of
198+ case Dhall.TypeCheck. typeWith (view Dhall. startingContext settings) expression of
88199 Left exception -> Exception. throwIO exception
89200 Right _ -> return ()
90201
91- let normalizedExpression = Core. alphaNormalize (Core. normalize expression)
202+ let normalizedExpression = Core. alphaNormalize (Core. normalizeWith (view Dhall. normalizer settings) expression)
92203
93204 -- make sure the frozen import is present in the semantic cache
94205 Dhall.Import. writeExpressionToSemanticCache (Core. denote expression)
@@ -101,58 +212,20 @@ freezeImportWithManager newManager directory import_ = do
101212
102213 return newImport
103214
104- -- | Freeze an import only if the import is a `Remote` import
105- freezeRemoteImport
106- :: FilePath
107- -- ^ Current working directory
108- -> Import
109- -> IO Import
110- freezeRemoteImport = freezeRemoteImportWithManager Dhall.Import. defaultNewManager
111-
112215-- | See 'freezeRemoteImport'.
113- freezeRemoteImportWithManager
114- :: IO Dhall.Import. Manager
216+ freezeRemoteImportWithSettings
217+ :: EvaluateSettings
115218 -> FilePath
116219 -> Import
117220 -> IO Import
118- freezeRemoteImportWithManager newManager directory import_ =
221+ freezeRemoteImportWithSettings settings directory import_ =
119222 case importType (importHashed import_) of
120- Remote {} -> freezeImportWithManager newManager directory import_
223+ Remote {} -> freezeImportWithSettings settings directory import_
121224 _ -> return import_
122225
123- -- | Specifies which imports to freeze
124- data Scope
125- = OnlyRemoteImports
126- -- ^ Freeze only remote imports (i.e. URLs)
127- | AllImports
128- -- ^ Freeze all imports (including paths and environment variables)
129-
130- -- | Specifies why we are adding semantic integrity checks
131- data Intent
132- = Secure
133- -- ^ Protect imports with an integrity check without a fallback so that
134- -- import resolution fails if the import changes
135- | Cache
136- -- ^ Protect imports with an integrity check and also add a fallback import
137- -- import without an integrity check. This is useful if you only want to
138- -- cache imports when possible but still gracefully degrade to resolving
139- -- them if the semantic integrity check has changed.
140-
141- -- | Implementation of the @dhall freeze@ subcommand
142- freeze
143- :: OutputMode
144- -> Transitivity
145- -> NonEmpty Input
146- -> Scope
147- -> Intent
148- -> Maybe CharacterSet
149- -> Censor
150- -> IO ()
151- freeze = freezeWithManager Dhall.Import. defaultNewManager
152-
153226-- | See 'freeze'.
154- freezeWithManager
155- :: IO Dhall.Import. Manager
227+ freezeWithSettings
228+ :: EvaluateSettings
156229 -> OutputMode
157230 -> Transitivity
158231 -> NonEmpty Input
@@ -161,7 +234,7 @@ freezeWithManager
161234 -> Maybe CharacterSet
162235 -> Censor
163236 -> IO ()
164- freezeWithManager newManager outputMode transitivity0 inputs scope intent chosenCharacterSet censor =
237+ freezeWithSettings settings outputMode transitivity0 inputs scope intent chosenCharacterSet censor =
165238 handleMultipleChecksFailed " freeze" " frozen" go inputs
166239 where
167240 go input = do
@@ -171,7 +244,7 @@ freezeWithManager newManager outputMode transitivity0 inputs scope intent chosen
171244 InputFile file ->
172245 System.FilePath. takeDirectory file
173246
174- let status = Dhall.Import. emptyStatusWithManager newManager directory
247+ let status = Dhall.Import. emptyStatusWithManager (view Dhall. newManager settings) directory
175248
176249 (inputName, originalText, transitivity) <- case input of
177250 InputFile file -> do
@@ -199,7 +272,7 @@ freezeWithManager newManager outputMode transitivity0 inputs scope intent chosen
199272 NonTransitive ->
200273 return ()
201274
202- frozenExpression <- freezeExpressionWithManager newManager directory scope intent parsedExpression
275+ frozenExpression <- freezeExpressionWithSettings settings directory scope intent parsedExpression
203276
204277 let doc = Pretty. pretty header
205278 <> Dhall.Pretty. prettyCharacterSet characterSet frozenExpression
@@ -238,41 +311,21 @@ freezeWithManager newManager outputMode transitivity0 inputs scope intent chosen
238311 then Right ()
239312 else Left CheckFailed {.. }
240313
241- {-| Slightly more pure version of the `freeze` function
242-
243- This still requires `IO` to freeze the import, but now the input and output
244- expression are passed in explicitly
245- -}
246- freezeExpression
247- :: FilePath
248- -- ^ Starting directory
249- -> Scope
250- -> Intent
251- -> Expr s Import
252- -> IO (Expr s Import )
253- freezeExpression = freezeExpressionWithManager Dhall.Import. defaultNewManager
254-
255- -- https://github.com/dhall-lang/dhall-haskell/issues/2347
256- toMissing :: Import -> Import
257- toMissing import_ =
258- import_ { importHashed = (importHashed import_) { importType = Missing } }
259-
260-
261314-- | See 'freezeExpression'.
262- freezeExpressionWithManager
263- :: IO Dhall.Import. Manager
315+ freezeExpressionWithSettings
316+ :: EvaluateSettings
264317 -> FilePath
265318 -> Scope
266319 -> Intent
267320 -> Expr s Import
268321 -> IO (Expr s Import )
269- freezeExpressionWithManager newManager directory scope intent expression = do
322+ freezeExpressionWithSettings settings directory scope intent expression = do
270323 let freezeScope =
271324 case scope of
272- AllImports -> freezeImportWithManager
273- OnlyRemoteImports -> freezeRemoteImportWithManager
325+ AllImports -> freezeImportWithSettings
326+ OnlyRemoteImports -> freezeRemoteImportWithSettings
274327
275- let freezeFunction = freezeScope newManager directory
328+ let freezeFunction = freezeScope settings directory
276329
277330 let cache
278331 -- This case is necessary because `transformOf` is a bottom-up
@@ -353,3 +406,8 @@ freezeExpressionWithManager newManager directory scope intent expression = do
353406 traverse freezeFunction expression
354407 Cache ->
355408 Dhall.Optics. transformMOf Core. subExpressions cache expression
409+
410+ -- https://github.com/dhall-lang/dhall-haskell/issues/2347
411+ toMissing :: Import -> Import
412+ toMissing import_ =
413+ import_ { importHashed = (importHashed import_) { importType = Missing } }
0 commit comments