2019-04-05 20:34:23 +03:00
|
|
|
-- Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
|
|
|
|
-- SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
|
|
|
module DAML.Project.Consts
|
|
|
|
( damlPathEnvVar
|
|
|
|
, projectPathEnvVar
|
|
|
|
, sdkPathEnvVar
|
|
|
|
, sdkVersionEnvVar
|
2019-05-03 03:24:07 +03:00
|
|
|
, sdkVersionLatestEnvVar
|
2019-04-16 19:12:31 +03:00
|
|
|
, damlAssistantEnvVar
|
2019-04-25 21:52:23 +03:00
|
|
|
, damlAssistantVersionEnvVar
|
2019-04-05 20:34:23 +03:00
|
|
|
, damlConfigName
|
|
|
|
, projectConfigName
|
|
|
|
, sdkConfigName
|
|
|
|
, damlEnvVars
|
|
|
|
, getDamlPath
|
|
|
|
, getProjectPath
|
|
|
|
, getSdkPath
|
|
|
|
, getSdkVersion
|
2019-04-16 19:12:31 +03:00
|
|
|
, getDamlAssistant
|
2019-05-27 19:09:43 +03:00
|
|
|
, ProjectCheck(..)
|
2019-04-05 20:34:23 +03:00
|
|
|
, withProjectRoot
|
2019-05-28 16:36:42 +03:00
|
|
|
, withExpectProjectRoot
|
2019-04-05 20:34:23 +03:00
|
|
|
) where
|
|
|
|
|
2019-05-27 19:09:43 +03:00
|
|
|
import Control.Monad
|
2019-04-05 20:34:23 +03:00
|
|
|
import System.Directory
|
|
|
|
import System.Environment
|
2019-05-27 19:09:43 +03:00
|
|
|
import System.Exit
|
2019-04-05 20:34:23 +03:00
|
|
|
import System.FilePath
|
2019-05-27 19:09:43 +03:00
|
|
|
import System.IO
|
|
|
|
|
|
|
|
import DAML.Project.Types
|
2019-04-05 20:34:23 +03:00
|
|
|
|
|
|
|
-- | The DAML_HOME environment variable determines the path of the daml
|
|
|
|
-- assistant data directory. This defaults to:
|
|
|
|
--
|
|
|
|
-- System.Directory.getAppUserDataDirectory "daml"
|
|
|
|
--
|
|
|
|
-- On Linux and Mac, that's ~/.daml
|
|
|
|
-- On Windows, that's %APPDATA%/daml
|
|
|
|
damlPathEnvVar :: String
|
|
|
|
damlPathEnvVar = "DAML_HOME"
|
|
|
|
|
|
|
|
-- | The DAML_PROJECT environment variable determines the path of
|
|
|
|
-- the current daml project. By default, this is done by traversing
|
2019-04-10 13:06:38 +03:00
|
|
|
-- up the directory structure until we find a "daml.yaml" file.
|
2019-04-05 20:34:23 +03:00
|
|
|
projectPathEnvVar :: String
|
|
|
|
projectPathEnvVar = "DAML_PROJECT"
|
|
|
|
|
|
|
|
-- | The DAML_SDK environment variable determines the path of the
|
|
|
|
-- sdk folder. By default, this is calculated as
|
|
|
|
-- $DAML_HOME/sdk/$DAML_SDK_VERSION.
|
|
|
|
sdkPathEnvVar :: String
|
|
|
|
sdkPathEnvVar = "DAML_SDK"
|
|
|
|
|
|
|
|
-- | The DAML_SDK_VERSION environment variable determines the
|
|
|
|
-- current or preferred sdk version. By default this is, in order
|
|
|
|
-- of preference:
|
|
|
|
--
|
|
|
|
-- 1. taken from the current $DAML_PROJECT config file, if it exists
|
|
|
|
-- 2. read from $DAML_SDK/VERSION file, if DAML_SDK is explicitly set
|
2019-04-10 13:06:38 +03:00
|
|
|
-- 3. the latest stable SDK version available in $DAML_HOME/sdk.
|
2019-04-05 20:34:23 +03:00
|
|
|
sdkVersionEnvVar :: String
|
|
|
|
sdkVersionEnvVar = "DAML_SDK_VERSION"
|
|
|
|
|
2019-05-03 03:24:07 +03:00
|
|
|
-- | Latest stable version available from GitHub. Note that this is
|
|
|
|
-- updated based on the update-check property in the user's daml-config.yaml
|
|
|
|
-- file, which means it will possibly never be available.
|
|
|
|
sdkVersionLatestEnvVar :: String
|
|
|
|
sdkVersionLatestEnvVar = "DAML_SDK_VERSION_LATEST"
|
|
|
|
|
2019-04-16 19:12:31 +03:00
|
|
|
-- | The absolute path to the daml assistant executable.
|
|
|
|
damlAssistantEnvVar :: String
|
|
|
|
damlAssistantEnvVar = "DAML_ASSISTANT"
|
|
|
|
|
2019-04-25 21:52:23 +03:00
|
|
|
-- | The SDK version of the daml assistant. This does not necessarily equal
|
|
|
|
-- the DAML_SDK_VERSION, e.g. when working with a project with an older
|
|
|
|
-- pinned SDK version.
|
|
|
|
damlAssistantVersionEnvVar :: String
|
|
|
|
damlAssistantVersionEnvVar = "DAML_ASSISTANT_VERSION"
|
|
|
|
|
2019-04-05 20:34:23 +03:00
|
|
|
-- | File name of config file in DAML_HOME (~/.daml).
|
|
|
|
damlConfigName :: FilePath
|
2019-04-12 13:03:05 +03:00
|
|
|
damlConfigName = "daml-config.yaml"
|
2019-04-05 20:34:23 +03:00
|
|
|
|
|
|
|
-- | File name of config file in DAML_PROJECT (the project path).
|
|
|
|
projectConfigName :: FilePath
|
2019-04-10 13:06:38 +03:00
|
|
|
projectConfigName = "daml.yaml"
|
2019-04-05 20:34:23 +03:00
|
|
|
|
|
|
|
-- | File name of config file in DAML_SDK (the sdk path)
|
|
|
|
sdkConfigName :: FilePath
|
2019-04-12 13:01:48 +03:00
|
|
|
sdkConfigName = "sdk-config.yaml"
|
2019-04-05 20:34:23 +03:00
|
|
|
|
|
|
|
-- | List of all environment variables handled by daml assistant.
|
|
|
|
damlEnvVars :: [String]
|
2019-05-06 22:25:30 +03:00
|
|
|
damlEnvVars =
|
|
|
|
[ damlPathEnvVar
|
|
|
|
, projectPathEnvVar
|
|
|
|
, sdkPathEnvVar
|
|
|
|
, sdkVersionEnvVar
|
|
|
|
, sdkVersionLatestEnvVar
|
|
|
|
, damlAssistantEnvVar
|
|
|
|
, damlAssistantVersionEnvVar
|
|
|
|
]
|
2019-04-05 20:34:23 +03:00
|
|
|
|
|
|
|
-- | Returns the path to the daml assistant data directory.
|
|
|
|
--
|
|
|
|
-- This will throw an `IOException` if the environment has not been setup by
|
|
|
|
-- the assistant.
|
|
|
|
getDamlPath :: IO FilePath
|
|
|
|
getDamlPath = getEnv damlPathEnvVar
|
|
|
|
|
|
|
|
-- | Returns the path of the current daml project or
|
|
|
|
--`Nothing` if invoked outside of a project.
|
|
|
|
getProjectPath :: IO (Maybe FilePath)
|
|
|
|
getProjectPath = do
|
|
|
|
mbProjectPath <- lookupEnv projectPathEnvVar
|
|
|
|
pure ((\p -> if null p then Nothing else Just p) =<< mbProjectPath)
|
|
|
|
|
|
|
|
-- | Returns the path of the sdk folder.
|
|
|
|
--
|
|
|
|
-- This will throw an `IOException` if the environment has not been setup by
|
|
|
|
-- the assistant.
|
|
|
|
getSdkPath :: IO FilePath
|
|
|
|
getSdkPath = getEnv sdkPathEnvVar
|
|
|
|
|
|
|
|
-- | Returns the current SDK version.
|
|
|
|
--
|
|
|
|
-- This will throw an `IOException` if the environment has not been setup by
|
|
|
|
-- the assistant.
|
|
|
|
getSdkVersion :: IO String
|
|
|
|
getSdkVersion = getEnv sdkVersionEnvVar
|
|
|
|
|
2019-04-16 19:12:31 +03:00
|
|
|
-- | Returns the absolute path to the assistant.
|
|
|
|
--
|
|
|
|
-- This will throw an `IOException` if the environment has not been setup by
|
|
|
|
-- the assistant.
|
|
|
|
getDamlAssistant :: IO FilePath
|
|
|
|
getDamlAssistant = getEnv damlAssistantEnvVar
|
|
|
|
|
2019-05-27 19:09:43 +03:00
|
|
|
-- | Whether we should check if a command is invoked inside of a project.
|
|
|
|
-- The string is the command name used in error messages
|
|
|
|
data ProjectCheck = ProjectCheck String Bool
|
|
|
|
|
2019-05-28 16:36:42 +03:00
|
|
|
-- | Execute an action within the project root, if available.
|
2019-04-05 20:34:23 +03:00
|
|
|
--
|
2019-05-28 16:36:42 +03:00
|
|
|
-- Determines the project root, if available, using 'getProjectPath' unless it
|
|
|
|
-- is passed explicitly.
|
|
|
|
--
|
|
|
|
-- If no project root is found and 'ProjectCheck' requires a project root, then
|
|
|
|
-- an error is printed and the program is terminated before executing the given
|
|
|
|
-- action.
|
|
|
|
--
|
|
|
|
-- The provided action is executed on 'Just' the project root, if available,
|
|
|
|
-- otherwise on 'Nothing'. Additionally, it is passed a function to make
|
|
|
|
-- filepaths relative to the new working directory.
|
|
|
|
withProjectRoot
|
|
|
|
:: Maybe ProjectPath
|
|
|
|
-> ProjectCheck
|
|
|
|
-> (Maybe FilePath -> (FilePath -> IO FilePath) -> IO a)
|
|
|
|
-> IO a
|
2019-05-27 19:09:43 +03:00
|
|
|
withProjectRoot mbProjectDir (ProjectCheck cmdName check) act = do
|
2019-04-05 20:34:23 +03:00
|
|
|
previousCwd <- getCurrentDirectory
|
2019-05-27 19:09:43 +03:00
|
|
|
mbProjectPath <- maybe getProjectPath (pure . Just . unwrapProjectPath) mbProjectDir
|
2019-04-05 20:34:23 +03:00
|
|
|
case mbProjectPath of
|
2019-05-27 19:09:43 +03:00
|
|
|
Nothing -> do
|
|
|
|
when check $ do
|
|
|
|
hPutStrLn stderr (cmdName <> ": Not in project.")
|
|
|
|
exitFailure
|
2019-05-28 16:36:42 +03:00
|
|
|
act mbProjectPath pure
|
2019-04-05 20:34:23 +03:00
|
|
|
Just projectPath -> do
|
|
|
|
projectPath <- canonicalizePath projectPath
|
2019-05-28 16:36:42 +03:00
|
|
|
withCurrentDirectory projectPath $ act mbProjectPath $ \f -> do
|
2019-04-05 20:34:23 +03:00
|
|
|
absF <- canonicalizePath (previousCwd </> f)
|
|
|
|
pure (projectPath `makeRelative` absF)
|
2019-05-28 16:36:42 +03:00
|
|
|
|
|
|
|
-- | Same as 'withProjectRoot' but always requires project root.
|
|
|
|
withExpectProjectRoot
|
|
|
|
:: Maybe ProjectPath -- ^ optionally specified project root
|
|
|
|
-> String -- ^ command name for error message
|
|
|
|
-> (FilePath -> (FilePath -> IO FilePath) -> IO a) -- ^ action
|
|
|
|
-> IO a
|
|
|
|
withExpectProjectRoot mbProjectDir cmdName act = do
|
|
|
|
withProjectRoot mbProjectDir (ProjectCheck cmdName True) $ \case
|
|
|
|
Nothing -> error "withProjectRoot should terminated the program"
|
|
|
|
Just projectPath -> act projectPath
|