-
Notifications
You must be signed in to change notification settings - Fork 205
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
8 changed files
with
304 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
compiler/damlc/daml-compiler/src/DA/Daml/Compiler/ExtractDar.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
-- Copyright (c) 2020 The DAML Authors. All rights reserved. | ||
-- SPDX-License-Identifier: Apache-2.0 | ||
|
||
module DA.Daml.Compiler.ExtractDar | ||
( ExtractedDar(..) | ||
, extractDar | ||
, getEntry | ||
) where | ||
|
||
import qualified "zip-archive" Codec.Archive.Zip as ZipArchive | ||
import Control.Monad.Extra | ||
import qualified Data.ByteString.Lazy as BSL | ||
import qualified Data.ByteString.UTF8 as BSUTF8 | ||
import Data.List.Extra | ||
import System.FilePath | ||
import DA.Daml.LF.Reader | ||
|
||
data ExtractedDar = ExtractedDar | ||
{ edSdkVersions :: String | ||
, edMain :: [ZipArchive.Entry] | ||
, edConfFiles :: [ZipArchive.Entry] | ||
, edDalfs :: [ZipArchive.Entry] | ||
, edSrcs :: [ZipArchive.Entry] | ||
} | ||
|
||
-- | Extract a dar archive | ||
extractDar :: FilePath -> IO ExtractedDar | ||
extractDar fp = do | ||
bs <- BSL.readFile fp | ||
let archive = ZipArchive.toArchive bs | ||
manifest <- getEntry manifestPath archive | ||
dalfManifest <- either fail pure $ readDalfManifest archive | ||
mainDalfEntry <- getEntry (mainDalfPath dalfManifest) archive | ||
sdkVersion <- | ||
case parseManifestFile $ BSL.toStrict $ ZipArchive.fromEntry manifest of | ||
Left err -> fail err | ||
Right manifest -> | ||
case lookup "Sdk-Version" manifest of | ||
Nothing -> fail "No Sdk-Version entry in manifest" | ||
Just version -> pure $! trim $ BSUTF8.toString version | ||
let confFiles = | ||
[ e | ||
| e <- ZipArchive.zEntries archive | ||
, ".conf" `isExtensionOf` ZipArchive.eRelativePath e | ||
] | ||
let srcs = | ||
[ e | ||
| e <- ZipArchive.zEntries archive | ||
, takeExtension (ZipArchive.eRelativePath e) `elem` | ||
[".daml", ".hie", ".hi"] | ||
] | ||
dalfs <- forM (dalfPaths dalfManifest) $ \p -> getEntry p archive | ||
pure (ExtractedDar sdkVersion [mainDalfEntry] confFiles dalfs srcs) | ||
|
||
-- | Get an entry from a dar or fail. | ||
getEntry :: FilePath -> ZipArchive.Archive -> IO ZipArchive.Entry | ||
getEntry fp dar = | ||
maybe (fail $ "Package does not contain " <> fp) pure $ | ||
ZipArchive.findEntryByPath fp dar |
63 changes: 63 additions & 0 deletions
63
compiler/damlc/daml-compiler/src/DA/Daml/Compiler/Validate.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
-- Copyright (c) 2020 The DAML Authors. All rights reserved. | ||
-- SPDX-License-Identifier: Apache-2.0 | ||
|
||
module DA.Daml.Compiler.Validate (validateDar) where | ||
|
||
import Control.Exception.Extra (errorIO) | ||
import Control.Monad (forM_) | ||
import qualified "zip-archive" Codec.Archive.Zip as ZipArchive | ||
import qualified DA.Daml.LF.Ast as LF | ||
import qualified DA.Daml.LF.Proto3.Archive as Archive | ||
import qualified Data.ByteString.Lazy as BSL | ||
|
||
import DA.Daml.Compiler.ExtractDar (extractDar,ExtractedDar(..)) | ||
import DA.Daml.LF.Ast.Version | ||
import DA.Daml.LF.Ast.World (initWorldSelf) | ||
import DA.Pretty (renderPretty) | ||
import qualified DA.Daml.LF.TypeChecker as TC (checkPackage) | ||
import qualified DA.Daml.LF.TypeChecker.Error as TC | ||
|
||
|
||
data ValidationError | ||
= VeArchiveError FilePath Archive.ArchiveError | ||
| VeTypeError TC.Error | ||
|
||
instance Show ValidationError where | ||
show = \case | ||
VeArchiveError fp err -> unlines | ||
[ "Invalid DAR." | ||
, "DALF entry cannot be decoded: " <> fp | ||
, show err ] | ||
VeTypeError err -> unlines | ||
[ "Invalid DAR." | ||
, "The DAR is not well typed." | ||
, renderPretty err ] | ||
|
||
|
||
validationError :: ValidationError -> IO a | ||
validationError = errorIO . show | ||
|
||
-- | Validate a loaded DAR: that all DALFs are well-typed and consequently that the DAR is closed | ||
validateDar :: FilePath -> IO Int | ||
validateDar inFile = do | ||
ExtractedDar{edDalfs} <- extractDar inFile | ||
extPackages <- mapM (decodeDalfEntry Archive.DecodeAsDependency) edDalfs | ||
validateWellTyped edDalfs extPackages | ||
return $ length extPackages | ||
|
||
validateWellTyped :: [ZipArchive.Entry] -> [LF.ExternalPackage] -> IO () | ||
validateWellTyped entries extPackages = do | ||
forM_ entries $ \e -> do | ||
LF.ExternalPackage{extPackagePkg=self} <- decodeDalfEntry Archive.DecodeAsMain e | ||
let world = initWorldSelf extPackages self | ||
let version = versionDev | ||
case TC.checkPackage world version of | ||
Right () -> return () | ||
Left err -> validationError $ VeTypeError err | ||
|
||
decodeDalfEntry :: Archive.DecodingMode -> ZipArchive.Entry -> IO LF.ExternalPackage | ||
decodeDalfEntry decodeAs entry = do | ||
let bs = BSL.toStrict $ ZipArchive.fromEntry entry | ||
case Archive.decodeArchive decodeAs bs of | ||
Left err -> validationError $ VeArchiveError (ZipArchive.eRelativePath entry) err | ||
Right (pid,package) -> return $ LF.ExternalPackage pid package |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.