Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

global -p option #542

Merged
merged 13 commits into from
Jul 11, 2015
29 changes: 25 additions & 4 deletions src/Stack/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import qualified Codec.Archive.Tar as Tar
import qualified Codec.Compression.GZip as GZip
import Control.Applicative
import Control.Concurrent (getNumCapabilities)
import Control.Exception (IOException)
import Control.Monad
import Control.Monad.Catch
import Control.Monad.IO.Class
Expand Down Expand Up @@ -146,9 +147,23 @@ configFromConfigMonoid configStackRoot mproject configMonoid@ConfigMonoid{..} =
return $ progsDir </> $(mkRelDir stackProgName) </> platform
_ -> return $ configStackRoot </> $(mkRelDir "programs") </> platform

configLocalBin <- do
localDir <- liftIO (getAppUserDataDirectory "local") >>= parseAbsDir
return $ localDir </> $(mkRelDir "bin")
configLocalBin <-
case configMonoidLocalBin of
Nothing -> do
localDir <- liftIO (getAppUserDataDirectory "local") >>= parseAbsDir
return $ localDir </> $(mkRelDir "bin")
Just userPath ->
(liftIO $ canonicalizePath userPath >>= parseAbsDir)
`catches`
[Handler (\(ex :: IOException) -> error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not be using error, instead throw a new ConfigException constructor.

(unlines ["Could not install to user specified directory \""
++ userPath ++ "\""
,"IOException: " ++ (show ex)]))
,Handler (\(ex :: PathParseException) -> error
(unlines ["Could not parse user specified directory \""
++ userPath ++ "\""
,"PathParseException: " ++ (show ex)]))]


configJobs <-
case configMonoidJobs of
Expand All @@ -161,7 +176,7 @@ configFromConfigMonoid configStackRoot mproject configMonoid@ConfigMonoid{..} =
-- | Command-line arguments parser for configuration.
configOptsParser :: Bool -> Parser ConfigMonoid
configOptsParser docker =
(\opts systemGHC installGHC arch os jobs includes libs skipGHCCheck skipMsys -> mempty
(\opts systemGHC installGHC arch os jobs includes libs skipGHCCheck skipMsys localBin -> mempty
{ configMonoidDockerOpts = opts
, configMonoidSystemGHC = systemGHC
, configMonoidInstallGHC = installGHC
Expand All @@ -172,6 +187,7 @@ configOptsParser docker =
, configMonoidExtraIncludeDirs = includes
, configMonoidExtraLibDirs = libs
, configMonoidSkipMsys = skipMsys
, configMonoidLocalBin = localBin
})
<$> Docker.dockerOptsParser docker
<*> maybeBoolFlags
Expand Down Expand Up @@ -216,6 +232,11 @@ configOptsParser docker =
"skip-msys"
"skipping the local MSYS installation (Windows only)"
idm
<*> optional (strOption
( long "local-bin-path"
<> metavar "DIR"
<> help "Install binaries to DIR"
))

-- | Get the directory on Windows where we should install extra programs. For
-- more information, see discussion at:
Expand Down
5 changes: 5 additions & 0 deletions src/Stack/Types/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,8 @@ data ConfigMonoid =
-- ^ See: 'configExtraLibDirs'
,configMonoidConcurrentTests :: !(Maybe Bool)
-- ^ See: 'configConcurrentTests'
,configMonoidLocalBin :: !(Maybe FilePath)
-- ^ Used to override the binary installation dir
}
deriving Show

Expand All @@ -457,6 +459,7 @@ instance Monoid ConfigMonoid where
, configMonoidExtraIncludeDirs = Set.empty
, configMonoidExtraLibDirs = Set.empty
, configMonoidConcurrentTests = Nothing
, configMonoidLocalBin = Nothing
}
mappend l r = ConfigMonoid
{ configMonoidDockerOpts = configMonoidDockerOpts l <> configMonoidDockerOpts r
Expand All @@ -476,6 +479,7 @@ instance Monoid ConfigMonoid where
, configMonoidExtraIncludeDirs = Set.union (configMonoidExtraIncludeDirs l) (configMonoidExtraIncludeDirs r)
, configMonoidExtraLibDirs = Set.union (configMonoidExtraLibDirs l) (configMonoidExtraLibDirs r)
, configMonoidConcurrentTests = configMonoidConcurrentTests l <|> configMonoidConcurrentTests r
, configMonoidLocalBin = configMonoidLocalBin l <|> configMonoidLocalBin r
}

instance FromJSON ConfigMonoid where
Expand All @@ -500,6 +504,7 @@ instance FromJSON ConfigMonoid where
configMonoidExtraIncludeDirs <- obj .:? "extra-include-dirs" .!= Set.empty
configMonoidExtraLibDirs <- obj .:? "extra-lib-dirs" .!= Set.empty
configMonoidConcurrentTests <- obj .:? "concurrent-tests"
configMonoidLocalBin <- obj .:? "local-bin"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be "local-bin-path" for consistency with the command-line argument name?

return ConfigMonoid {..}

-- | Newtype for non-orphan FromJSON instance.
Expand Down
5 changes: 4 additions & 1 deletion stack.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ extra-source-files: README.md ChangeLog.md
test/package-dump/ghc-7.10.txt

new-template/src/Lib.hs
new-template/new-template.cabal
-- new-template/{{name}}.cabal
-- Cabal doesn't like curly braces.
-- Luckily this can be described via glob.
new-template/*.cabal
new-template/test/Spec.hs
new-template/app/Main.hs
new-template/LICENSE
Expand Down
22 changes: 18 additions & 4 deletions test/integration/lib/StackTest.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import System.Directory
import System.IO
import System.Process
import System.Exit
import System.Environment

run' :: FilePath -> [String] -> IO ExitCode
run' cmd args = do
Expand Down Expand Up @@ -44,11 +43,26 @@ stackErr args = do
doesNotExist :: FilePath -> IO ()
doesNotExist fp = do
putStrLn $ "doesNotExist " ++ fp
exists <- doesFileOrDirExist fp
case exists of
(Right msg) -> error msg
(Left _) -> return ()

doesExist :: FilePath -> IO ()
doesExist fp = do
putStrLn $ "doesExist " ++ fp
exists <- doesFileOrDirExist fp
case exists of
(Right msg) -> return ()
(Left _) -> error "No file or directory exists"

doesFileOrDirExist :: FilePath -> IO (Either () String)
doesFileOrDirExist fp = do
isFile <- doesFileExist fp
if isFile
then error $ "File exists: " ++ fp
then return (Right ("File exists: " ++ fp))
else do
isDir <- doesDirectoryExist fp
if isDir
then error $ "Directory exists: " ++ fp
else return ()
then return (Right ("Directory exists: " ++ fp))
else return (Left ())
25 changes: 25 additions & 0 deletions test/integration/tests/443-specify-path/Main.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import StackTest
import System.Directory

main :: IO ()
main = do
-- install in relative path
createDirectory "bin"
stack ["-p", "./bin", "install" , "happy"]
doesExist "./bin/happy"

-- Default install
-- This seems to fail due to direcory being cleaned up,
-- a manual test of the default stack install is required
-- defaultDir <- getAppUserDataDirectory "local"
-- stack ["install", "happy"]
-- doesExist (defaultDir ++ "/bin/happy")

-- install in current dir
stack ["-p", ".", "install", "happy" ]
doesExist "happy"

-- install in absolute path
tmpDirectory <- getTemporaryDirectory
stack ["-p", tmpDirectory, "install", "happy" ]
doesExist "/tmp/happy"