mirror of
https://github.com/anoma/juvix.git
synced 2024-10-26 17:52:17 +03:00
Update the Juvix lock file when the Package file changes (#2522)
Adds a new version of the lock file that stores the hash (sha256 digest) of the package file (Package.juvix, juvix.yaml) it was generated from as a field: ``` # This file was autogenerated by Juvix version 0.5.4. # Do not edit this file manually. version: 2 checksum: d05940a4d3dc0e15451d02e1294819c875ba486ee54e26865ba8d190ac7c27c3 dependencies: - git: name: stdlib ref: f68b0614ad695eaa13ead42f3466e0a78219f826 url: https://github.com/anoma/juvix-stdlib.git dependencies: [] ``` The lock file is regenerated when the hash of the package file doesn't match the value of the `checksum` field, i.e when the user updates the package file. Existing lock files are automatically migrated to version 2. * Closes https://github.com/anoma/juvix/issues/2464
This commit is contained in:
parent
c6586a960d
commit
1c1a5b7117
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@ -198,6 +198,14 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
sed --version
|
sed --version
|
||||||
|
|
||||||
|
- name: Install coreutils
|
||||||
|
run: |
|
||||||
|
brew install coreutils
|
||||||
|
|
||||||
|
- name: Test sha256sum (used by smoke)
|
||||||
|
run: |
|
||||||
|
sha256sum --version
|
||||||
|
|
||||||
- name: Download and extract wasi-sysroot
|
- name: Download and extract wasi-sysroot
|
||||||
run: >
|
run: >
|
||||||
curl
|
curl
|
||||||
|
2
Makefile
2
Makefile
@ -240,10 +240,12 @@ fast-test-skip-slow:
|
|||||||
@${STACK} test --fast ${STACKFLAGS} ${STACKTESTFLAGS} --ta '-p "! /slow tests/"'
|
@${STACK} test --fast ${STACKFLAGS} ${STACKTESTFLAGS} --ta '-p "! /slow tests/"'
|
||||||
|
|
||||||
SMOKE := $(shell command -v smoke 2> /dev/null)
|
SMOKE := $(shell command -v smoke 2> /dev/null)
|
||||||
|
SHA256SUM := $(shell command -v sha256sum 2> /dev/null)
|
||||||
|
|
||||||
.PHONY : smoke-only
|
.PHONY : smoke-only
|
||||||
smoke-only:
|
smoke-only:
|
||||||
@$(if $(SMOKE),, $(error "Smoke not found, please install it from https://github.com/jonaprieto/smoke"))
|
@$(if $(SMOKE),, $(error "Smoke not found, please install it from https://github.com/jonaprieto/smoke"))
|
||||||
|
@$(if $(SHA256SUM),, $(error "sha256sum not found, please install the GNU coreutils package (e.g {apt, brew} install coreutils)"))
|
||||||
@smoke $(shell find tests -name '*.smoke.yaml')
|
@smoke $(shell find tests -name '*.smoke.yaml')
|
||||||
|
|
||||||
.PHONY : smoke
|
.PHONY : smoke
|
||||||
|
@ -45,9 +45,11 @@ dependencies:
|
|||||||
- aeson == 2.1.*
|
- aeson == 2.1.*
|
||||||
- ansi-terminal == 0.11.*
|
- ansi-terminal == 0.11.*
|
||||||
- base == 4.17.*
|
- base == 4.17.*
|
||||||
|
- base16-bytestring == 1.0.*
|
||||||
- blaze-html == 0.9.*
|
- blaze-html == 0.9.*
|
||||||
- bytestring == 0.11.*
|
- bytestring == 0.11.*
|
||||||
- containers == 0.6.*
|
- containers == 0.6.*
|
||||||
|
- cryptohash-sha256 == 0.11.*
|
||||||
- directory == 1.3.*
|
- directory == 1.3.*
|
||||||
- dlist == 1.0.*
|
- dlist == 1.0.*
|
||||||
- edit-distance == 0.2.*
|
- edit-distance == 0.2.*
|
||||||
|
@ -26,6 +26,7 @@ import Juvix.Compiler.Pipeline.Package
|
|||||||
import Juvix.Compiler.Pipeline.Package.Loader.EvalEff
|
import Juvix.Compiler.Pipeline.Package.Loader.EvalEff
|
||||||
import Juvix.Data.Effect.Git
|
import Juvix.Data.Effect.Git
|
||||||
import Juvix.Data.Effect.TaggedLock
|
import Juvix.Data.Effect.TaggedLock
|
||||||
|
import Juvix.Data.SHA256 qualified as SHA256
|
||||||
import Juvix.Extra.Paths
|
import Juvix.Extra.Paths
|
||||||
import Juvix.Extra.Stdlib (ensureStdlib)
|
import Juvix.Extra.Stdlib (ensureStdlib)
|
||||||
import Juvix.Prelude
|
import Juvix.Prelude
|
||||||
@ -175,15 +176,26 @@ registerDependencies' conf = do
|
|||||||
void (addRootDependency conf e glob)
|
void (addRootDependency conf e glob)
|
||||||
| otherwise -> do
|
| otherwise -> do
|
||||||
lockfile <- addRootDependency conf e (e ^. entryPointRoot)
|
lockfile <- addRootDependency conf e (e ^. entryPointRoot)
|
||||||
root <- asks (^. envRoot)
|
whenM shouldWriteLockfile $ do
|
||||||
whenM shouldWriteLockfile (writeLockfile root lockfile)
|
packageFileChecksum <- SHA256.digestFile (e ^. entryPointPackage . packageFile)
|
||||||
|
lockfilePath' <- lockfilePath
|
||||||
|
writeLockfile lockfilePath' packageFileChecksum lockfile
|
||||||
where
|
where
|
||||||
shouldWriteLockfile :: Sem r Bool
|
shouldWriteLockfile :: Sem r Bool
|
||||||
shouldWriteLockfile = do
|
shouldWriteLockfile = do
|
||||||
|
lockfileExists <- lockfilePath >>= fileExists'
|
||||||
|
hasRemoteDependencies <- gets (^. resolverHasRemoteDependencies)
|
||||||
|
shouldUpdateLockfile' <- gets (^. resolverShouldUpdateLockfile)
|
||||||
|
|
||||||
|
let shouldForce = conf ^. dependenciesConfigForceUpdateLockfile
|
||||||
|
shouldWriteInitialLockfile = not lockfileExists && hasRemoteDependencies
|
||||||
|
shouldUpdateLockfile = lockfileExists && shouldUpdateLockfile'
|
||||||
|
return (shouldForce || shouldWriteInitialLockfile || shouldUpdateLockfile)
|
||||||
|
|
||||||
|
lockfilePath :: Sem r (Path Abs File)
|
||||||
|
lockfilePath = do
|
||||||
root <- asks (^. envRoot)
|
root <- asks (^. envRoot)
|
||||||
lockfileExists <- fileExists' (mkPackageLockfilePath root)
|
return (mkPackageLockfilePath root)
|
||||||
depsShouldWriteLockfile <- gets (^. resolverShouldWriteLockfile)
|
|
||||||
return (conf ^. dependenciesConfigForceUpdateLockfile || not lockfileExists && depsShouldWriteLockfile)
|
|
||||||
|
|
||||||
addRootDependency ::
|
addRootDependency ::
|
||||||
forall r.
|
forall r.
|
||||||
@ -196,15 +208,23 @@ addRootDependency conf e root = do
|
|||||||
let pf = mkPackageFilePath root
|
let pf = mkPackageFilePath root
|
||||||
d = mkPackageDependencyInfo pf (mkPathDependency (toFilePath root))
|
d = mkPackageDependencyInfo pf (mkPathDependency (toFilePath root))
|
||||||
resolvedDependency <- resolveDependency d
|
resolvedDependency <- resolveDependency d
|
||||||
checkShouldWriteLockfile resolvedDependency
|
checkRemoteDependency resolvedDependency
|
||||||
let p = resolvedDependency ^. resolvedDependencyPath
|
let p = resolvedDependency ^. resolvedDependencyPath
|
||||||
withEnvRoot p $ do
|
withEnvRoot p $ do
|
||||||
pkg <- mkPackage (Just e) p
|
pkg <- mkPackage (Just e) p
|
||||||
|
shouldUpdateLockfile' <- shouldUpdateLockfile pkg
|
||||||
|
when shouldUpdateLockfile' setShouldUpdateLockfile
|
||||||
let resolvedPkg :: Package
|
let resolvedPkg :: Package
|
||||||
| conf ^. dependenciesConfigForceUpdateLockfile = unsetPackageLockfile pkg
|
| shouldUpdateLockfile' = unsetPackageLockfile pkg
|
||||||
| otherwise = pkg
|
| otherwise = pkg
|
||||||
deps <- addDependency' resolvedPkg (Just e) resolvedDependency
|
deps <- addDependency' resolvedPkg (Just e) resolvedDependency
|
||||||
return Lockfile {_lockfileDependencies = deps ^. lockfileDependencyDependencies}
|
return Lockfile {_lockfileDependencies = deps ^. lockfileDependencyDependencies}
|
||||||
|
where
|
||||||
|
shouldUpdateLockfile :: Package -> Sem r Bool
|
||||||
|
shouldUpdateLockfile pkg = do
|
||||||
|
let checksumMay :: Maybe Text = pkg ^? packageLockfile . _Just . lockfileInfoChecksum . _Just
|
||||||
|
packageFileChecksum <- SHA256.digestFile (pkg ^. packageFile)
|
||||||
|
return (conf ^. dependenciesConfigForceUpdateLockfile || Just packageFileChecksum /= checksumMay)
|
||||||
|
|
||||||
addDependency ::
|
addDependency ::
|
||||||
forall r.
|
forall r.
|
||||||
@ -214,7 +234,7 @@ addDependency ::
|
|||||||
Sem r LockfileDependency
|
Sem r LockfileDependency
|
||||||
addDependency me d = do
|
addDependency me d = do
|
||||||
resolvedDependency <- resolveDependency d
|
resolvedDependency <- resolveDependency d
|
||||||
checkShouldWriteLockfile resolvedDependency
|
checkRemoteDependency resolvedDependency
|
||||||
let p = resolvedDependency ^. resolvedDependencyPath
|
let p = resolvedDependency ^. resolvedDependencyPath
|
||||||
cached <- lookupCachedDependency p
|
cached <- lookupCachedDependency p
|
||||||
case cached of
|
case cached of
|
||||||
|
@ -23,7 +23,8 @@ data ResolverState = ResolverState
|
|||||||
_resolverFiles :: HashMap (Path Rel File) (NonEmpty PackageInfo),
|
_resolverFiles :: HashMap (Path Rel File) (NonEmpty PackageInfo),
|
||||||
-- | PackageInfos indexed by root
|
-- | PackageInfos indexed by root
|
||||||
_resolverCache :: HashMap (Path Abs Dir) ResolverCacheItem,
|
_resolverCache :: HashMap (Path Abs Dir) ResolverCacheItem,
|
||||||
_resolverShouldWriteLockfile :: Bool
|
_resolverHasRemoteDependencies :: Bool,
|
||||||
|
_resolverShouldUpdateLockfile :: Bool
|
||||||
}
|
}
|
||||||
deriving stock (Show)
|
deriving stock (Show)
|
||||||
|
|
||||||
@ -42,12 +43,19 @@ iniResolverState =
|
|||||||
ResolverState
|
ResolverState
|
||||||
{ _resolverCache = mempty,
|
{ _resolverCache = mempty,
|
||||||
_resolverFiles = mempty,
|
_resolverFiles = mempty,
|
||||||
_resolverShouldWriteLockfile = False
|
_resolverHasRemoteDependencies = False,
|
||||||
|
_resolverShouldUpdateLockfile = False
|
||||||
}
|
}
|
||||||
|
|
||||||
checkShouldWriteLockfile :: (Member (State ResolverState) r) => ResolvedDependency -> Sem r ()
|
setHasRemoteDependencies :: (Member (State ResolverState) r) => Sem r ()
|
||||||
checkShouldWriteLockfile d = case d ^. resolvedDependencyDependency of
|
setHasRemoteDependencies = modify' (set resolverHasRemoteDependencies True)
|
||||||
DependencyGit {} -> modify' (set resolverShouldWriteLockfile True)
|
|
||||||
|
setShouldUpdateLockfile :: (Member (State ResolverState) r) => Sem r ()
|
||||||
|
setShouldUpdateLockfile = modify' (set resolverShouldUpdateLockfile True)
|
||||||
|
|
||||||
|
checkRemoteDependency :: (Member (State ResolverState) r) => ResolvedDependency -> Sem r ()
|
||||||
|
checkRemoteDependency d = case d ^. resolvedDependencyDependency of
|
||||||
|
DependencyGit {} -> setHasRemoteDependencies
|
||||||
DependencyPath {} -> return ()
|
DependencyPath {} -> return ()
|
||||||
|
|
||||||
withEnvRoot :: (Members '[Reader ResolverEnv] r) => Path Abs Dir -> Sem r a -> Sem r a
|
withEnvRoot :: (Members '[Reader ResolverEnv] r) => Path Abs Dir -> Sem r a -> Sem r a
|
||||||
|
@ -7,6 +7,7 @@ import Data.Aeson.BetterErrors qualified as Aeson
|
|||||||
import Data.Aeson.Encoding (pair)
|
import Data.Aeson.Encoding (pair)
|
||||||
import Data.Aeson.TH
|
import Data.Aeson.TH
|
||||||
import Data.String.Interpolate (i)
|
import Data.String.Interpolate (i)
|
||||||
|
import Data.Text qualified as T
|
||||||
import Data.Yaml
|
import Data.Yaml
|
||||||
import Data.Yaml.Pretty
|
import Data.Yaml.Pretty
|
||||||
import Juvix.Compiler.Pipeline.Package.Dependency
|
import Juvix.Compiler.Pipeline.Package.Dependency
|
||||||
@ -29,16 +30,59 @@ newtype Lockfile = Lockfile
|
|||||||
}
|
}
|
||||||
deriving stock (Generic, Show, Eq)
|
deriving stock (Generic, Show, Eq)
|
||||||
|
|
||||||
|
type LockfileV1 = Lockfile
|
||||||
|
|
||||||
|
data LockfileV2 = LockfileV2
|
||||||
|
{ _lockfileV2Version :: Int,
|
||||||
|
_lockfileV2Checksum :: Text,
|
||||||
|
_lockfileV2Dependencies :: [LockfileDependency]
|
||||||
|
}
|
||||||
|
deriving stock (Generic, Show, Eq)
|
||||||
|
|
||||||
|
data VersionedLockfile
|
||||||
|
= V1Lockfile LockfileV1
|
||||||
|
| V2Lockfile LockfileV2
|
||||||
|
deriving stock (Show, Eq)
|
||||||
|
|
||||||
|
data LockfileVersionTag
|
||||||
|
= LockfileV1Tag
|
||||||
|
| LockfileV2Tag
|
||||||
|
deriving stock (Show, Eq)
|
||||||
|
|
||||||
|
allVersionedLockfiles :: [LockfileVersionTag]
|
||||||
|
allVersionedLockfiles = [LockfileV1Tag, LockfileV2Tag]
|
||||||
|
|
||||||
|
lockfileVersionNumber :: LockfileVersionTag -> Int
|
||||||
|
lockfileVersionNumber = \case
|
||||||
|
LockfileV1Tag -> 1
|
||||||
|
LockfileV2Tag -> 2
|
||||||
|
|
||||||
data LockfileInfo = LockfileInfo
|
data LockfileInfo = LockfileInfo
|
||||||
{ _lockfileInfoPath :: Path Abs File,
|
{ _lockfileInfoPath :: Path Abs File,
|
||||||
|
_lockfileInfoChecksum :: Maybe Text,
|
||||||
_lockfileInfoLockfile :: Lockfile
|
_lockfileInfoLockfile :: Lockfile
|
||||||
}
|
}
|
||||||
deriving stock (Eq, Show)
|
deriving stock (Eq, Show)
|
||||||
|
|
||||||
makeLenses ''LockfileDependency
|
makeLenses ''LockfileDependency
|
||||||
makeLenses ''Lockfile
|
makeLenses ''Lockfile
|
||||||
|
makeLenses ''LockfileV2
|
||||||
makeLenses ''LockfileInfo
|
makeLenses ''LockfileInfo
|
||||||
|
|
||||||
|
mkLockfileV2 :: Text -> [LockfileDependency] -> LockfileV2
|
||||||
|
mkLockfileV2 _lockfileV2Checksum _lockfileV2Dependencies =
|
||||||
|
LockfileV2 {_lockfileV2Version = lockfileVersionNumber LockfileV2Tag, ..}
|
||||||
|
|
||||||
|
lockfile' :: SimpleGetter VersionedLockfile Lockfile
|
||||||
|
lockfile' = to $ \case
|
||||||
|
V1Lockfile l -> l
|
||||||
|
V2Lockfile l -> Lockfile {_lockfileDependencies = l ^. lockfileV2Dependencies}
|
||||||
|
|
||||||
|
checksum :: SimpleGetter VersionedLockfile (Maybe Text)
|
||||||
|
checksum = to $ \case
|
||||||
|
V1Lockfile {} -> Nothing
|
||||||
|
V2Lockfile l -> Just (l ^. lockfileV2Checksum)
|
||||||
|
|
||||||
instance ToJSON LockfileDependency where
|
instance ToJSON LockfileDependency where
|
||||||
toJSON d = object [dep, Str.dependencies .= toJSON (d ^. lockfileDependencyDependencies)]
|
toJSON d = object [dep, Str.dependencies .= toJSON (d ^. lockfileDependencyDependencies)]
|
||||||
where
|
where
|
||||||
@ -65,20 +109,50 @@ instance FromJSON LockfileDependency where
|
|||||||
p' :: Parse' Dependency
|
p' :: Parse' Dependency
|
||||||
p' = DependencyPath <$> (key Str.path_ fromAesonParser) Aeson.<|> DependencyGit <$> (key Str.git fromAesonParser)
|
p' = DependencyPath <$> (key Str.path_ fromAesonParser) Aeson.<|> DependencyGit <$> (key Str.git fromAesonParser)
|
||||||
|
|
||||||
lockfileOptions :: Options
|
lockfileV2Options :: Options
|
||||||
lockfileOptions =
|
lockfileV2Options =
|
||||||
defaultOptions
|
defaultOptions
|
||||||
{ fieldLabelModifier = over Lens._head toLower . dropPrefix "_lockfile",
|
{ fieldLabelModifier = over Lens._head toLower . dropPrefix "_lockfileV2",
|
||||||
rejectUnknownFields = True,
|
rejectUnknownFields = True,
|
||||||
omitNothingFields = True
|
omitNothingFields = True
|
||||||
}
|
}
|
||||||
|
|
||||||
instance ToJSON Lockfile where
|
instance ToJSON LockfileV2 where
|
||||||
toJSON = genericToJSON lockfileOptions
|
toJSON = genericToJSON lockfileV2Options
|
||||||
toEncoding = genericToEncoding lockfileOptions
|
toEncoding = genericToEncoding lockfileV2Options
|
||||||
|
|
||||||
instance FromJSON Lockfile where
|
data LockfileParseErr = LockfileUnsupportedVersion
|
||||||
parseJSON = toAesonParser' (Lockfile <$> (key Str.dependencies fromAesonParser))
|
|
||||||
|
instance FromJSON VersionedLockfile where
|
||||||
|
parseJSON = toAesonParser displayErr $ do
|
||||||
|
v <- parseVersion
|
||||||
|
case v of
|
||||||
|
LockfileV1Tag -> V1Lockfile <$> parseV1
|
||||||
|
LockfileV2Tag -> V2Lockfile <$> parseV2
|
||||||
|
where
|
||||||
|
parseV1 :: Parse LockfileParseErr Lockfile
|
||||||
|
parseV1 = Lockfile <$> key Str.dependencies fromAesonParser
|
||||||
|
|
||||||
|
parseV2 :: Parse LockfileParseErr LockfileV2
|
||||||
|
parseV2 = do
|
||||||
|
checksum' <- key "checksum" asText
|
||||||
|
deps <- key Str.dependencies fromAesonParser
|
||||||
|
return (mkLockfileV2 checksum' deps)
|
||||||
|
|
||||||
|
parseVersion :: Parse LockfileParseErr LockfileVersionTag
|
||||||
|
parseVersion = fromMaybeM (return LockfileV1Tag) (keyMay Str.version parseVersion')
|
||||||
|
where
|
||||||
|
parseVersion' :: Parse LockfileParseErr LockfileVersionTag
|
||||||
|
parseVersion' = do
|
||||||
|
n <- asIntegral
|
||||||
|
if
|
||||||
|
| lockfileVersionNumber LockfileV1Tag == n -> return LockfileV1Tag
|
||||||
|
| lockfileVersionNumber LockfileV2Tag == n -> return LockfileV2Tag
|
||||||
|
| otherwise -> throwCustomError LockfileUnsupportedVersion
|
||||||
|
|
||||||
|
displayErr :: LockfileParseErr -> Text
|
||||||
|
displayErr = \case
|
||||||
|
LockfileUnsupportedVersion -> "lockfile error: unsupported version. Supported versions: " <> T.intercalate ", " (show . lockfileVersionNumber <$> allVersionedLockfiles)
|
||||||
|
|
||||||
mkPackageLockfilePath :: Path Abs Dir -> Path Abs File
|
mkPackageLockfilePath :: Path Abs Dir -> Path Abs File
|
||||||
mkPackageLockfilePath = (<//> juvixLockfile)
|
mkPackageLockfilePath = (<//> juvixLockfile)
|
||||||
@ -93,11 +167,16 @@ mayReadLockfile root = do
|
|||||||
if
|
if
|
||||||
| lockfileExists -> do
|
| lockfileExists -> do
|
||||||
bs <- readFileBS' lockfilePath
|
bs <- readFileBS' lockfilePath
|
||||||
either (throwErr . pack . prettyPrintParseException) ((return . Just) . mkLockfileInfo lockfilePath) (decodeEither' @Lockfile bs)
|
either (throwErr . pack . prettyPrintParseException) ((return . Just) . mkLockfileInfo lockfilePath) (decodeEither' @VersionedLockfile bs)
|
||||||
| otherwise -> return Nothing
|
| otherwise -> return Nothing
|
||||||
where
|
where
|
||||||
mkLockfileInfo :: Path Abs File -> Lockfile -> LockfileInfo
|
mkLockfileInfo :: Path Abs File -> VersionedLockfile -> LockfileInfo
|
||||||
mkLockfileInfo _lockfileInfoPath _lockfileInfoLockfile = LockfileInfo {..}
|
mkLockfileInfo _lockfileInfoPath vl =
|
||||||
|
LockfileInfo
|
||||||
|
{ _lockfileInfoChecksum = vl ^. checksum,
|
||||||
|
_lockfileInfoLockfile = vl ^. lockfile',
|
||||||
|
..
|
||||||
|
}
|
||||||
|
|
||||||
lockfilePath :: Path Abs File
|
lockfilePath :: Path Abs File
|
||||||
lockfilePath = mkPackageLockfilePath root
|
lockfilePath = mkPackageLockfilePath root
|
||||||
@ -115,21 +194,23 @@ mayReadLockfile root = do
|
|||||||
lockfileEncodeConfig :: Config
|
lockfileEncodeConfig :: Config
|
||||||
lockfileEncodeConfig = setConfCompare keyCompare defConfig
|
lockfileEncodeConfig = setConfCompare keyCompare defConfig
|
||||||
where
|
where
|
||||||
-- serialize the dependencies after all other keys
|
-- serialize the dependencies field after all other keys and the version
|
||||||
|
-- field before all other keys
|
||||||
keyCompare :: Text -> Text -> Ordering
|
keyCompare :: Text -> Text -> Ordering
|
||||||
keyCompare x y =
|
keyCompare x y =
|
||||||
if
|
if
|
||||||
| y == Str.dependencies || x == Str.dependencies -> GT
|
| y == Str.dependencies -> LT
|
||||||
|
| x == Str.dependencies -> GT
|
||||||
|
| x == Str.version -> LT
|
||||||
|
| y == Str.version -> GT
|
||||||
| otherwise -> compare x y
|
| otherwise -> compare x y
|
||||||
|
|
||||||
writeLockfile :: (Members '[Files] r) => Path Abs Dir -> Lockfile -> Sem r ()
|
writeLockfile :: (Members '[Files] r) => Path Abs File -> Text -> Lockfile -> Sem r ()
|
||||||
writeLockfile root lf = do
|
writeLockfile lockfilePath checksum' lf = do
|
||||||
ensureDir' (parent lockfilePath)
|
ensureDir' (parent lockfilePath)
|
||||||
writeFileBS lockfilePath (header <> encodePretty lockfileEncodeConfig lf)
|
let v2lf = mkLockfileV2 checksum' (lf ^. lockfileDependencies)
|
||||||
|
writeFileBS lockfilePath (header <> encodePretty lockfileEncodeConfig v2lf)
|
||||||
where
|
where
|
||||||
lockfilePath :: Path Abs File
|
|
||||||
lockfilePath = mkPackageLockfilePath root
|
|
||||||
|
|
||||||
header :: ByteString
|
header :: ByteString
|
||||||
header = [i|\# This file was autogenerated by Juvix version #{versionDoc}.\n\# Do not edit this file manually.\n\n|]
|
header = [i|\# This file was autogenerated by Juvix version #{versionDoc}.\n\# Do not edit this file manually.\n\n|]
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ data LoaderResource = LoaderResource
|
|||||||
|
|
||||||
makeLenses ''LoaderResource
|
makeLenses ''LoaderResource
|
||||||
|
|
||||||
runEvalFileEffIO :: forall r a. (Members '[TaggedLock, Embed IO, Error PackageLoaderError] r) => Sem (EvalFileEff ': r) a -> Sem r a
|
runEvalFileEffIO :: forall r a. (Members '[TaggedLock, Files, Embed IO, Error PackageLoaderError] r) => Sem (EvalFileEff ': r) a -> Sem r a
|
||||||
runEvalFileEffIO = interpretScopedAs allocator handler
|
runEvalFileEffIO = interpretScopedAs allocator handler
|
||||||
where
|
where
|
||||||
allocator :: Path Abs File -> Sem r LoaderResource
|
allocator :: Path Abs File -> Sem r LoaderResource
|
||||||
@ -115,7 +115,7 @@ runEvalFileEffIO = interpretScopedAs allocator handler
|
|||||||
Just l -> l ^. intervalFile == f
|
Just l -> l ^. intervalFile == f
|
||||||
Nothing -> False
|
Nothing -> False
|
||||||
|
|
||||||
loadPackage' :: (Members '[TaggedLock, Embed IO, Error PackageLoaderError] r) => Path Abs File -> Sem r CoreResult
|
loadPackage' :: (Members '[TaggedLock, Files, Embed IO, Error PackageLoaderError] r) => Path Abs File -> Sem r CoreResult
|
||||||
loadPackage' packagePath = do
|
loadPackage' packagePath = do
|
||||||
( mapError
|
( mapError
|
||||||
( \e ->
|
( \e ->
|
||||||
@ -127,7 +127,6 @@ loadPackage' packagePath = do
|
|||||||
. evalInternetOffline
|
. evalInternetOffline
|
||||||
. ignoreHighlightBuilder
|
. ignoreHighlightBuilder
|
||||||
. runProcessIO
|
. runProcessIO
|
||||||
. runFilesIO
|
|
||||||
. evalTopBuiltins
|
. evalTopBuiltins
|
||||||
. evalTopNameIdGen
|
. evalTopNameIdGen
|
||||||
. evalTopBuiltins
|
. evalTopBuiltins
|
||||||
|
9
src/Juvix/Data/SHA256.hs
Normal file
9
src/Juvix/Data/SHA256.hs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
module Juvix.Data.SHA256 where
|
||||||
|
|
||||||
|
import Crypto.Hash.SHA256 qualified as SHA256
|
||||||
|
import Data.ByteString.Base16 qualified as Base16
|
||||||
|
import Juvix.Prelude
|
||||||
|
|
||||||
|
-- | Create a HEX encoded, SHA256 digest of the contents of a file.
|
||||||
|
digestFile :: (Member Files r) => Path Abs File -> Sem r Text
|
||||||
|
digestFile = fmap (decodeUtf8Lenient . Base16.encode . SHA256.hash) . readFileBS'
|
@ -802,3 +802,6 @@ path_ = "path"
|
|||||||
|
|
||||||
package :: (IsString s) => s
|
package :: (IsString s) => s
|
||||||
package = "package"
|
package = "package"
|
||||||
|
|
||||||
|
version :: (IsString s) => s
|
||||||
|
version = "version"
|
||||||
|
@ -6,9 +6,15 @@ module Juvix.Prelude.Aeson
|
|||||||
where
|
where
|
||||||
|
|
||||||
import Data.Aeson
|
import Data.Aeson
|
||||||
|
import Data.Aeson.KeyMap qualified as KeyMap
|
||||||
import Data.Aeson.Text
|
import Data.Aeson.Text
|
||||||
import Data.Text.Lazy qualified as Lazy
|
import Data.Text.Lazy qualified as Lazy
|
||||||
import Juvix.Prelude.Base
|
import Juvix.Prelude.Base
|
||||||
|
|
||||||
encodeToText :: (ToJSON a) => a -> Text
|
encodeToText :: (ToJSON a) => a -> Text
|
||||||
encodeToText = Lazy.toStrict . encodeToLazyText
|
encodeToText = Lazy.toStrict . encodeToLazyText
|
||||||
|
|
||||||
|
appendFields :: [(Key, Value)] -> Value -> Value
|
||||||
|
appendFields keyValues = \case
|
||||||
|
Object obj -> Object (KeyMap.fromList keyValues <> obj)
|
||||||
|
a -> a
|
||||||
|
@ -10,6 +10,7 @@ import Juvix.Compiler.Concrete.Print qualified as P
|
|||||||
import Juvix.Compiler.Concrete.Translation.FromParsed.Analysis.PathResolver
|
import Juvix.Compiler.Concrete.Translation.FromParsed.Analysis.PathResolver
|
||||||
import Juvix.Compiler.Concrete.Translation.FromParsed.Analysis.Scoping qualified as Scoper
|
import Juvix.Compiler.Concrete.Translation.FromParsed.Analysis.Scoping qualified as Scoper
|
||||||
import Juvix.Compiler.Concrete.Translation.FromSource qualified as Parser
|
import Juvix.Compiler.Concrete.Translation.FromSource qualified as Parser
|
||||||
|
import Juvix.Compiler.Pipeline.Package.Loader
|
||||||
import Juvix.Compiler.Pipeline.Package.Loader.Error
|
import Juvix.Compiler.Pipeline.Package.Loader.Error
|
||||||
import Juvix.Compiler.Pipeline.Package.Loader.EvalEff.IO
|
import Juvix.Compiler.Pipeline.Package.Loader.EvalEff.IO
|
||||||
import Juvix.Compiler.Pipeline.Package.Loader.PathResolver
|
import Juvix.Compiler.Pipeline.Package.Loader.PathResolver
|
||||||
@ -17,7 +18,6 @@ import Juvix.Compiler.Pipeline.Setup
|
|||||||
import Juvix.Data.Effect.Git
|
import Juvix.Data.Effect.Git
|
||||||
import Juvix.Data.Effect.Process
|
import Juvix.Data.Effect.Process
|
||||||
import Juvix.Data.Effect.TaggedLock
|
import Juvix.Data.Effect.TaggedLock
|
||||||
import Juvix.Prelude.Aeson
|
|
||||||
import Juvix.Prelude.Pretty
|
import Juvix.Prelude.Pretty
|
||||||
|
|
||||||
data PathResolverMode
|
data PathResolverMode
|
||||||
@ -94,9 +94,9 @@ testDescr PosTest {..} = helper renderCodeNew
|
|||||||
Concrete.fromParsed p
|
Concrete.fromParsed p
|
||||||
)
|
)
|
||||||
|
|
||||||
let yamlFiles :: [(Path Abs File, Text)]
|
let packageFiles' :: [(Path Abs File, Text)]
|
||||||
yamlFiles =
|
packageFiles' =
|
||||||
[ (pkgi ^. packageRoot <//> juvixYamlFile, encodeToText (rawPackage (pkgi ^. packagePackage)))
|
[ (pkgi ^. packagePackage . packageFile, renderPackageVersion PackageVersion1 (pkgi ^. packagePackage))
|
||||||
| pkgi <- (^. resolverCacheItemPackage) <$> toList (resolverState ^. resolverCache)
|
| pkgi <- (^. resolverCacheItemPackage) <$> toList (resolverState ^. resolverCache)
|
||||||
]
|
]
|
||||||
fsScoped :: HashMap (Path Abs File) Text
|
fsScoped :: HashMap (Path Abs File) Text
|
||||||
@ -105,14 +105,14 @@ testDescr PosTest {..} = helper renderCodeNew
|
|||||||
[ (getModuleFilePath m, renderer m)
|
[ (getModuleFilePath m, renderer m)
|
||||||
| m <- toList (s ^. Scoper.resultScoperTable . Scoper.infoModules)
|
| m <- toList (s ^. Scoper.resultScoperTable . Scoper.infoModules)
|
||||||
]
|
]
|
||||||
<> yamlFiles
|
<> packageFiles'
|
||||||
fsParsed :: HashMap (Path Abs File) Text
|
fsParsed :: HashMap (Path Abs File) Text
|
||||||
fsParsed =
|
fsParsed =
|
||||||
HashMap.fromList $
|
HashMap.fromList $
|
||||||
[ (getModuleFilePath m, renderCodeNew m)
|
[ (getModuleFilePath m, renderCodeNew m)
|
||||||
| m <- toList (p ^. Parser.resultTable . Parser.infoParsedModules)
|
| m <- toList (p ^. Parser.resultTable . Parser.infoParsedModules)
|
||||||
]
|
]
|
||||||
<> yamlFiles
|
<> packageFiles'
|
||||||
|
|
||||||
step "Parsing pretty scoped"
|
step "Parsing pretty scoped"
|
||||||
p' :: Parser.ParserResult <- evalHelper fsScoped upToParsing
|
p' :: Parser.ParserResult <- evalHelper fsScoped upToParsing
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
module Package;
|
module Package;
|
||||||
|
|
||||||
import PackageDescription.V1 open;
|
import PackageDescription.Basic open;
|
||||||
|
|
||||||
package : Package :=
|
package : Package := basicPackage;
|
||||||
defaultPackage
|
|
||||||
{name := "base";
|
|
||||||
version := mkVersion 1 0 0;
|
|
||||||
dependencies := []};
|
|
||||||
|
@ -8,5 +8,5 @@ package : Package :=
|
|||||||
version := mkVersion 0 0 1;
|
version := mkVersion 0 0 1;
|
||||||
dependencies := [ path ".libs/Extra"
|
dependencies := [ path ".libs/Extra"
|
||||||
; path ".libs/Base"
|
; path ".libs/Base"
|
||||||
; path ".juvix-build/stdlib"
|
; defaultStdlib
|
||||||
]};
|
]};
|
||||||
|
@ -317,7 +317,11 @@ tests:
|
|||||||
main := just "HelloWorld.juvix"};
|
main := just "HelloWorld.juvix"};
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
checksum=$(sha256sum Package.juvix | cut -d " " -f 1)
|
||||||
|
|
||||||
cat <<-EOF > juvix.lock.yaml
|
cat <<-EOF > juvix.lock.yaml
|
||||||
|
version: 2
|
||||||
|
checksum: $checksum
|
||||||
dependencies:
|
dependencies:
|
||||||
- path: .juvix-build/stdlib/
|
- path: .juvix-build/stdlib/
|
||||||
dependencies: []
|
dependencies: []
|
||||||
@ -353,6 +357,7 @@ tests:
|
|||||||
cat <<-EOF > HelloDep.juvix
|
cat <<-EOF > HelloDep.juvix
|
||||||
module HelloDep;
|
module HelloDep;
|
||||||
import HelloDep2 open;
|
import HelloDep2 open;
|
||||||
|
import Stdlib.Prelude open;
|
||||||
main : IO := printStringLn "This is from the second commit" >> printStringLn hello;
|
main : IO := printStringLn "This is from the second commit" >> printStringLn hello;
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@ -372,7 +377,7 @@ tests:
|
|||||||
git add -A
|
git add -A
|
||||||
git commit -m "commit2"
|
git commit -m "commit2"
|
||||||
|
|
||||||
# rebuild the project (should use the first commit
|
# rebuild the project (should use the first commit)
|
||||||
cd $temp/base
|
cd $temp/base
|
||||||
|
|
||||||
# compile with the new hash
|
# compile with the new hash
|
||||||
@ -388,8 +393,7 @@ tests:
|
|||||||
- bash
|
- bash
|
||||||
script: |
|
script: |
|
||||||
temp=$(mktemp -d)
|
temp=$(mktemp -d)
|
||||||
echo $temp
|
trap 'rm -rf -- "$temp"' EXIT
|
||||||
# trap 'rm -rf -- "$temp"' EXIT
|
|
||||||
|
|
||||||
# create dependency
|
# create dependency
|
||||||
mkdir $temp/dep
|
mkdir $temp/dep
|
||||||
@ -425,7 +429,7 @@ tests:
|
|||||||
version := mkVersion 0 0 1;
|
version := mkVersion 0 0 1;
|
||||||
dependencies :=
|
dependencies :=
|
||||||
[path ".juvix-build/stdlib";
|
[path ".juvix-build/stdlib";
|
||||||
git "dep1" "$temp/dep" "$dep1hash"];
|
git "dep1" "$temp/dep" "main"];
|
||||||
main := just "HelloWorld.juvix"};
|
main := just "HelloWorld.juvix"};
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@ -457,23 +461,7 @@ tests:
|
|||||||
|
|
||||||
# compile project with new ref - should use lockfile ref
|
# compile project with new ref - should use lockfile ref
|
||||||
cd $temp/base
|
cd $temp/base
|
||||||
|
juvix clean
|
||||||
cat <<-EOF > Package.juvix
|
|
||||||
-- juvix-package-version:1
|
|
||||||
module Package;
|
|
||||||
|
|
||||||
import Stdlib.Prelude open;
|
|
||||||
import PackageDescription.V1 open;
|
|
||||||
|
|
||||||
package : Package :=
|
|
||||||
defaultPackage
|
|
||||||
{name := "HelloWorld";
|
|
||||||
version := mkVersion 0 0 1;
|
|
||||||
dependencies :=
|
|
||||||
[path ".juvix-build/stdlib";
|
|
||||||
git "dep1" "$temp/dep" "$dep1hash"];
|
|
||||||
main := just "HelloWorld.juvix"};
|
|
||||||
EOF
|
|
||||||
|
|
||||||
juvix compile HelloWorld.juvix
|
juvix compile HelloWorld.juvix
|
||||||
./HelloWorld
|
./HelloWorld
|
||||||
@ -703,78 +691,6 @@ tests:
|
|||||||
contains: "Hello from dep1\nHello from dep2"
|
contains: "Hello from dep1\nHello from dep2"
|
||||||
exit-status: 0
|
exit-status: 0
|
||||||
|
|
||||||
- name: git-dependencies-lockfile-missing-dependency
|
|
||||||
command:
|
|
||||||
shell:
|
|
||||||
- bash
|
|
||||||
script: |
|
|
||||||
temp=$(mktemp -d)
|
|
||||||
trap 'rm -rf -- "$temp"' EXIT
|
|
||||||
|
|
||||||
# create dependency
|
|
||||||
mkdir $temp/dep1
|
|
||||||
cd $temp/dep1
|
|
||||||
git init
|
|
||||||
|
|
||||||
cat <<-EOF > HelloDep.juvix
|
|
||||||
module HelloDep;
|
|
||||||
import Stdlib.Prelude open;
|
|
||||||
main : IO := printStringLn "Hello from dep";
|
|
||||||
EOF
|
|
||||||
|
|
||||||
touch juvix.yaml
|
|
||||||
|
|
||||||
git add -A
|
|
||||||
git commit -m "commit1"
|
|
||||||
|
|
||||||
dep1hash=$(git rev-parse HEAD)
|
|
||||||
|
|
||||||
# create project that uses dependency
|
|
||||||
mkdir $temp/base
|
|
||||||
cd $temp/base
|
|
||||||
|
|
||||||
cat <<-EOF > Package.juvix
|
|
||||||
-- juvix-package-version:1
|
|
||||||
module Package;
|
|
||||||
|
|
||||||
import Stdlib.Prelude open;
|
|
||||||
import PackageDescription.V1 open;
|
|
||||||
|
|
||||||
package : Package :=
|
|
||||||
defaultPackage
|
|
||||||
{name := "HelloWorld";
|
|
||||||
version := mkVersion 0 0 1;
|
|
||||||
dependencies :=
|
|
||||||
[path ".juvix-build/stdlib/";
|
|
||||||
git "dep1" "$temp/dep1" "$dep1hash"];
|
|
||||||
main := just "HelloWorld.juvix"};
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat <<-EOF > juvix.lock.yaml
|
|
||||||
dependencies:
|
|
||||||
- path: .juvix-build/stdlib/
|
|
||||||
dependencies: []
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat <<-EOF > HelloWorld.juvix
|
|
||||||
-- HelloWorld.juvix
|
|
||||||
module HelloWorld;
|
|
||||||
|
|
||||||
import Stdlib.Prelude open;
|
|
||||||
import HelloDep;
|
|
||||||
|
|
||||||
main : IO := HelloDep.main;
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# compile and run the project
|
|
||||||
juvix compile HelloWorld.juvix
|
|
||||||
stderr:
|
|
||||||
contains: "dep1"
|
|
||||||
stdout:
|
|
||||||
matches:
|
|
||||||
regex: ".*"
|
|
||||||
exit-status: 1
|
|
||||||
|
|
||||||
- name: git-dependencies-update-ref-offline
|
- name: git-dependencies-update-ref-offline
|
||||||
command:
|
command:
|
||||||
shell:
|
shell:
|
||||||
|
@ -287,7 +287,11 @@ tests:
|
|||||||
version: 0.1.0
|
version: 0.1.0
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
checksum=$(sha256sum juvix.yaml | cut -d " " -f 1)
|
||||||
|
|
||||||
cat <<-EOF > juvix.lock.yaml
|
cat <<-EOF > juvix.lock.yaml
|
||||||
|
version: 2
|
||||||
|
checksum: $checksum
|
||||||
dependencies:
|
dependencies:
|
||||||
- path: .juvix-build/stdlib/
|
- path: .juvix-build/stdlib/
|
||||||
dependencies: []
|
dependencies: []
|
||||||
@ -323,6 +327,7 @@ tests:
|
|||||||
cat <<-EOF > HelloDep.juvix
|
cat <<-EOF > HelloDep.juvix
|
||||||
module HelloDep;
|
module HelloDep;
|
||||||
import HelloDep2 open;
|
import HelloDep2 open;
|
||||||
|
import Stdlib.Prelude open;
|
||||||
main : IO := printStringLn "This is from the second commit" >> printStringLn hello;
|
main : IO := printStringLn "This is from the second commit" >> printStringLn hello;
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@ -342,7 +347,7 @@ tests:
|
|||||||
git add -A
|
git add -A
|
||||||
git commit -m "commit2"
|
git commit -m "commit2"
|
||||||
|
|
||||||
# rebuild the project (should use the first commit
|
# rebuild the project (should use the first commit)
|
||||||
cd $temp/base
|
cd $temp/base
|
||||||
|
|
||||||
# compile with the new hash
|
# compile with the new hash
|
||||||
@ -358,8 +363,7 @@ tests:
|
|||||||
- bash
|
- bash
|
||||||
script: |
|
script: |
|
||||||
temp=$(mktemp -d)
|
temp=$(mktemp -d)
|
||||||
echo $temp
|
trap 'rm -rf -- "$temp"' EXIT
|
||||||
# trap 'rm -rf -- "$temp"' EXIT
|
|
||||||
|
|
||||||
# create dependency
|
# create dependency
|
||||||
mkdir $temp/dep
|
mkdir $temp/dep
|
||||||
@ -390,7 +394,7 @@ tests:
|
|||||||
- git:
|
- git:
|
||||||
url: $temp/dep
|
url: $temp/dep
|
||||||
name: dep1
|
name: dep1
|
||||||
ref: $dep1hash
|
ref: main
|
||||||
version: 0.1.0
|
version: 0.1.0
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
@ -423,18 +427,7 @@ tests:
|
|||||||
# compile project with new ref - should use lockfile ref
|
# compile project with new ref - should use lockfile ref
|
||||||
cd $temp/base
|
cd $temp/base
|
||||||
|
|
||||||
cat <<-EOF > juvix.yaml
|
juvix clean
|
||||||
name: HelloWorld
|
|
||||||
main: HelloWorld.juvix
|
|
||||||
dependencies:
|
|
||||||
- .juvix-build/stdlib
|
|
||||||
- git:
|
|
||||||
url: $temp/dep
|
|
||||||
name: dep1
|
|
||||||
ref: $dep1hash
|
|
||||||
version: 0.1.0
|
|
||||||
EOF
|
|
||||||
|
|
||||||
juvix compile HelloWorld.juvix
|
juvix compile HelloWorld.juvix
|
||||||
./HelloWorld
|
./HelloWorld
|
||||||
stdout:
|
stdout:
|
||||||
@ -643,73 +636,6 @@ tests:
|
|||||||
contains: "Hello from dep1\nHello from dep2"
|
contains: "Hello from dep1\nHello from dep2"
|
||||||
exit-status: 0
|
exit-status: 0
|
||||||
|
|
||||||
- name: git-dependencies-lockfile-missing-dependency
|
|
||||||
command:
|
|
||||||
shell:
|
|
||||||
- bash
|
|
||||||
script: |
|
|
||||||
temp=$(mktemp -d)
|
|
||||||
trap 'rm -rf -- "$temp"' EXIT
|
|
||||||
|
|
||||||
# create dependency
|
|
||||||
mkdir $temp/dep1
|
|
||||||
cd $temp/dep1
|
|
||||||
git init
|
|
||||||
|
|
||||||
cat <<-EOF > HelloDep.juvix
|
|
||||||
module HelloDep;
|
|
||||||
import Stdlib.Prelude open;
|
|
||||||
main : IO := printStringLn "Hello from dep";
|
|
||||||
EOF
|
|
||||||
|
|
||||||
touch juvix.yaml
|
|
||||||
|
|
||||||
git add -A
|
|
||||||
git commit -m "commit1"
|
|
||||||
|
|
||||||
dep1hash=$(git rev-parse HEAD)
|
|
||||||
|
|
||||||
# create project that uses dependency
|
|
||||||
mkdir $temp/base
|
|
||||||
cd $temp/base
|
|
||||||
|
|
||||||
cat <<-EOF > juvix.yaml
|
|
||||||
name: HelloWorld
|
|
||||||
main: HelloWorld.juvix
|
|
||||||
dependencies:
|
|
||||||
- .juvix-build/stdlib/
|
|
||||||
- git:
|
|
||||||
url: $temp/dep1
|
|
||||||
name: dep1
|
|
||||||
ref: $dep1hash
|
|
||||||
version: 0.1.0
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat <<-EOF > juvix.lock.yaml
|
|
||||||
dependencies:
|
|
||||||
- path: .juvix-build/stdlib/
|
|
||||||
dependencies: []
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat <<-EOF > HelloWorld.juvix
|
|
||||||
-- HelloWorld.juvix
|
|
||||||
module HelloWorld;
|
|
||||||
|
|
||||||
import Stdlib.Prelude open;
|
|
||||||
import HelloDep;
|
|
||||||
|
|
||||||
main : IO := HelloDep.main;
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# compile and run the project
|
|
||||||
juvix compile HelloWorld.juvix
|
|
||||||
stderr:
|
|
||||||
contains: "dep1"
|
|
||||||
stdout:
|
|
||||||
matches:
|
|
||||||
regex: ".*"
|
|
||||||
exit-status: 1
|
|
||||||
|
|
||||||
- name: git-dependencies-update-ref-offline
|
- name: git-dependencies-update-ref-offline
|
||||||
command:
|
command:
|
||||||
shell:
|
shell:
|
||||||
@ -1061,6 +987,88 @@ tests:
|
|||||||
contains: duplicate
|
contains: duplicate
|
||||||
exit-status: 1
|
exit-status: 1
|
||||||
|
|
||||||
|
- name: lockfile-update-when-package-file-is-updated
|
||||||
|
command:
|
||||||
|
shell:
|
||||||
|
- bash
|
||||||
|
script: |
|
||||||
|
temp=$(mktemp -d)
|
||||||
|
# trap 'rm -rf -- "$temp"' EXIT
|
||||||
|
echo $temp
|
||||||
|
|
||||||
|
# create dependency
|
||||||
|
mkdir $temp/dep
|
||||||
|
cd $temp/dep
|
||||||
|
git init
|
||||||
|
|
||||||
|
cat <<-EOF > HelloDep.juvix
|
||||||
|
module HelloDep;
|
||||||
|
import Stdlib.Prelude open;
|
||||||
|
main : IO := printStringLn "Hello from dep";
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat <<-EOF > Package.juvix
|
||||||
|
module Package;
|
||||||
|
import PackageDescription.Basic open;
|
||||||
|
package : Package := basicPackage;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
git add -A
|
||||||
|
git commit -m "commit1"
|
||||||
|
|
||||||
|
# create project that uses dependency
|
||||||
|
mkdir $temp/base
|
||||||
|
cd $temp/base
|
||||||
|
|
||||||
|
cat <<-EOF > Package.juvix
|
||||||
|
module Package;
|
||||||
|
import PackageDescription.V1 open;
|
||||||
|
package : Package := defaultPackage {dependencies := [defaultStdlib ; git "dep1" "$temp/dep" "main"]}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat <<-EOF > HelloWorld.juvix
|
||||||
|
-- HelloWorld.juvix
|
||||||
|
module HelloWorld;
|
||||||
|
|
||||||
|
import Stdlib.Prelude open;
|
||||||
|
import HelloDep;
|
||||||
|
|
||||||
|
main : IO := HelloDep.main;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# compile project to create lock file
|
||||||
|
juvix compile HelloWorld.juvix
|
||||||
|
|
||||||
|
cd $temp/dep
|
||||||
|
cat <<-EOF > HelloDep.juvix
|
||||||
|
module HelloDep;
|
||||||
|
import Stdlib.Prelude open;
|
||||||
|
main : IO := printStringLn "Hello from commit2";
|
||||||
|
EOF
|
||||||
|
|
||||||
|
git add -A
|
||||||
|
git commit -m "commit2"
|
||||||
|
|
||||||
|
cd $temp/base
|
||||||
|
juvix clean
|
||||||
|
juvix compile HelloWorld.juvix
|
||||||
|
./HelloWorld
|
||||||
|
|
||||||
|
# Update the Package file and recompile
|
||||||
|
# it should use the latest commit
|
||||||
|
echo "-- comment" >> Package.juvix
|
||||||
|
juvix clean
|
||||||
|
juvix compile HelloWorld.juvix
|
||||||
|
./HelloWorld
|
||||||
|
|
||||||
|
stderr: ""
|
||||||
|
stdout:
|
||||||
|
matches:
|
||||||
|
regex: "Hello from dep\n(.*?)Hello from commit2"
|
||||||
|
options:
|
||||||
|
- dot-all
|
||||||
|
exit-status: 0
|
||||||
|
|
||||||
- name: git-dependencies-no-fetch-if-ref-exists-in-clone
|
- name: git-dependencies-no-fetch-if-ref-exists-in-clone
|
||||||
command:
|
command:
|
||||||
shell:
|
shell:
|
||||||
|
Loading…
Reference in New Issue
Block a user