Skip to content
This repository

Implement the 'run' command. #1097

Merged
merged 2 commits into from over 1 year ago

2 participants

Mikhail Glushenkov Johan Tibell
Mikhail Glushenkov
Owner

This patch implements the run command, as discussed in #1088. I did not modify commandParseArgs, so -- is required for passing arguments to the executable.

Mikhail Glushenkov
Owner

One issue: should we also make runhaskell Setup.hs run work?

Johan Tibell tibbe commented on the diff November 05, 2012
cabal-install/Distribution/Client/Run.hs
((24 lines not shown))
  24
+import Distribution.Simple.Utils             (die, rawSystemExitWithEnv)
  25
+import Distribution.Verbosity                (Verbosity)
  26
+
  27
+import Data.Functor                          ((<$>))
  28
+import Data.List                             (find)
  29
+import System.Directory                      (canonicalizePath,
  30
+                                              getCurrentDirectory)
  31
+import System.Environment                    (getEnvironment)
  32
+import System.FilePath                       ((<.>), (</>))
  33
+
  34
+
  35
+run :: Verbosity -> BuildFlags -> [String] -> IO ()
  36
+run verbosity buildFlags args = do
  37
+  let distPref = fromFlagOrDefault (useDistPref defaultSetupScriptOptions)
  38
+                 (buildDistPref buildFlags)
  39
+  -- The package must have been configured by now.
3
Johan Tibell Owner
tibbe added a note November 05, 2012

Do we output a sensible error message (like e.g. build does) if not?

Mikhail Glushenkov Owner

It uses the same mechanism as cabal test (i.e., reconfigure and build).

Mikhail Glushenkov Owner

So it prints the same error message as build. By the time we enter run, we know that all is well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Johan Tibell
Owner

I think we can skip the support for Setup.hs for now.

Johan Tibell
Owner

Code looks good to me. I'll merge when I get home.

@dcoutts Do you think we should support ./Setup run as well, or do you want to move slower on adding commands to that UI (as it's more standardized)?

Mikhail Glushenkov
Owner

Code looks good to me. I'll merge when I get home.

Great. In the meanwhile, I'll update the users' guide.

Johan Tibell tibbe merged commit bd8efdf into from November 05, 2012
Johan Tibell tibbe closed this November 05, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 2 unique commits by 1 author.

Nov 06, 2012
Mikhail Glushenkov Implement the 'run' command.
See the discussion in #1088.
f551e91
Mikhail Glushenkov Describe the 'run' command in the user guide. bd8efdf
This page is out of date. Refresh to see the latest.
15  Cabal/doc/developing-packages.markdown
Source Rendered
@@ -488,6 +488,21 @@ information](#build-information)).
488 488
     using a preprocessor. The source file must be relative to one of the
489 489
     directories listed in `hs-source-dirs`.
490 490
 
  491
+#### Running executables ####
  492
+
  493
+You can have Cabal build and run your executables by using the `run` command:
  494
+
  495
+~~~~~~~~~~~~~~~~
  496
+$ cabal run EXECUTABLE [-- EXECUTABLE_FLAGS]
  497
+~~~~~~~~~~~~~~~~
  498
+
  499
+This command will configure, build and run the executable `EXECUTABLE`. The
  500
+double dash separator is required to distinguish executable flags from `run`'s
  501
+own flags. If there is only one executable defined in the whole package, the
  502
+executable's name can be omitted. See the output of `cabal help run` for a list
  503
+of options you can pass to `cabal run`.
  504
+
  505
+
491 506
 ### Test suites ###
492 507
 
493 508
 Test suite sections (if present) describe package test suites and must have an
70  cabal-install/Distribution/Client/Run.hs
... ...
@@ -0,0 +1,70 @@
  1
+-----------------------------------------------------------------------------
  2
+-- |
  3
+-- Module      :  Distribution.Client.Run
  4
+-- Maintainer  :  cabal-devel@haskell.org
  5
+-- Portability :  portable
  6
+--
  7
+-- Implementation of the 'run' command.
  8
+-----------------------------------------------------------------------------
  9
+
  10
+module Distribution.Client.Run ( run )
  11
+       where
  12
+
  13
+import Distribution.Client.Setup             (BuildFlags (..))
  14
+import Distribution.Client.SetupWrapper      (SetupScriptOptions (..),
  15
+                                              defaultSetupScriptOptions)
  16
+
  17
+import Distribution.PackageDescription       (Executable (..),
  18
+                                              PackageDescription (..))
  19
+import Distribution.Simple.Build.PathsModule (pkgPathEnvVar)
  20
+import Distribution.Simple.BuildPaths        (exeExtension)
  21
+import Distribution.Simple.Configure         (getPersistBuildConfig)
  22
+import Distribution.Simple.LocalBuildInfo    (LocalBuildInfo (..))
  23
+import Distribution.Simple.Setup             (fromFlagOrDefault)
  24
+import Distribution.Simple.Utils             (die, rawSystemExitWithEnv)
  25
+import Distribution.Verbosity                (Verbosity)
  26
+
  27
+import Data.Functor                          ((<$>))
  28
+import Data.List                             (find)
  29
+import System.Directory                      (canonicalizePath,
  30
+                                              getCurrentDirectory)
  31
+import System.Environment                    (getEnvironment)
  32
+import System.FilePath                       ((<.>), (</>))
  33
+
  34
+
  35
+run :: Verbosity -> BuildFlags -> [String] -> IO ()
  36
+run verbosity buildFlags args = do
  37
+  let distPref = fromFlagOrDefault (useDistPref defaultSetupScriptOptions)
  38
+                 (buildDistPref buildFlags)
  39
+  -- The package must have been configured by now.
  40
+  lbi <- getPersistBuildConfig distPref
  41
+
  42
+  curDir <- getCurrentDirectory
  43
+  let buildPref     = buildDir lbi
  44
+      pkg_descr     = localPkgDescr lbi
  45
+      exes          = executables pkg_descr
  46
+      dataDirEnvVar = (pkgPathEnvVar pkg_descr "datadir",
  47
+                       curDir </> dataDir pkg_descr)
  48
+
  49
+      exePath :: Executable -> FilePath
  50
+      exePath exe = buildPref </> exeName exe </> (exeName exe <.> exeExtension)
  51
+
  52
+      doRun :: Executable -> [String] -> IO ()
  53
+      doRun exe exeArgs = do
  54
+        path <- canonicalizePath $ exePath exe
  55
+        env <- (dataDirEnvVar:) <$> getEnvironment
  56
+        rawSystemExitWithEnv verbosity path exeArgs env
  57
+
  58
+  case exes of
  59
+    []    -> die "Couldn't find any executables."
  60
+    [exe] -> case args of
  61
+      []                        -> doRun exe []
  62
+      (x:xs) | x == exeName exe -> doRun exe xs
  63
+             | otherwise        -> doRun exe args
  64
+    _     -> case args of
  65
+      []     -> die $ "This package contains multiple executables. "
  66
+                ++ "You must pass the executable name as the first argument "
  67
+                ++ "to run."
  68
+      (x:xs) -> case find (\exe -> exeName exe == x) exes of
  69
+        Nothing  -> die $ "No executable named '" ++ x ++ "'."
  70
+        Just exe -> doRun exe xs
16  cabal-install/Distribution/Client/Setup.hs
@@ -25,6 +25,7 @@ module Distribution.Client.Setup
25 25
     , checkCommand
26 26
     , uploadCommand, UploadFlags(..)
27 27
     , reportCommand, ReportFlags(..)
  28
+    , runCommand
28 29
     , unpackCommand, UnpackFlags(..)
29 30
     , initCommand, IT.InitFlags(..)
30 31
     , sdistCommand, SDistFlags(..), SDistExFlags(..), ArchiveFormat(..)
@@ -430,6 +431,21 @@ checkCommand = CommandUI {
430 431
     commandOptions      = \_ -> []
431 432
   }
432 433
 
  434
+runCommand :: CommandUI BuildFlags
  435
+runCommand = CommandUI {
  436
+    commandName         = "run",
  437
+    commandSynopsis     = "Runs the compiled executable.",
  438
+    commandDescription  = Nothing,
  439
+    commandUsage        =
  440
+      (\pname -> "Usage: " ++ pname
  441
+                 ++ " run [FLAGS] [EXECUTABLE] [-- EXECUTABLE_FLAGS]\n\n"
  442
+                 ++ "Flags for run:"),
  443
+    commandDefaultFlags = mempty,
  444
+    commandOptions      = Cabal.buildOptions progConf
  445
+  }
  446
+  where
  447
+    progConf = defaultProgramConfiguration
  448
+
433 449
 -- ------------------------------------------------------------
434 450
 -- * Report flags
435 451
 -- ------------------------------------------------------------
14  cabal-install/Main.hs
@@ -27,6 +27,7 @@ import Distribution.Client.Setup
27 27
          , InfoFlags(..), infoCommand
28 28
          , UploadFlags(..), uploadCommand
29 29
          , ReportFlags(..), reportCommand
  30
+         , runCommand
30 31
          , InitFlags(initVerbosity), initCommand
31 32
          , SDistFlags(..), SDistExFlags(..), sdistCommand
32 33
          , Win32SelfUpgradeFlags(..), win32SelfUpgradeCommand
@@ -62,6 +63,7 @@ import Distribution.Client.Fetch              (fetch)
62 63
 import Distribution.Client.Check as Check     (check)
63 64
 --import Distribution.Client.Clean            (clean)
64 65
 import Distribution.Client.Upload as Upload   (upload, check, report)
  66
+import Distribution.Client.Run                (run)
65 67
 import Distribution.Client.SrcDist            (sdist)
66 68
 import Distribution.Client.Unpack             (unpack)
67 69
 import Distribution.Client.Index              (index)
@@ -150,6 +152,7 @@ mainWorker args = topHandler $
150 152
       ,sdistCommand           `commandAddAction` sdistAction
151 153
       ,uploadCommand          `commandAddAction` uploadAction
152 154
       ,reportCommand          `commandAddAction` reportAction
  155
+      ,runCommand             `commandAddAction` runAction
153 156
       ,initCommand            `commandAddAction` initAction
154 157
       ,configureExCommand     `commandAddAction` configureAction
155 158
       ,buildCommand           `commandAddAction` buildAction
@@ -555,6 +558,17 @@ reportAction reportFlags extraArgs globalFlags = do
555 558
     (flagToMaybe $ reportUsername reportFlags')
556 559
     (flagToMaybe $ reportPassword reportFlags')
557 560
 
  561
+runAction :: BuildFlags -> [String] -> GlobalFlags -> IO ()
  562
+runAction buildFlags extraArgs globalFlags = do
  563
+  let verbosity    = fromFlagOrDefault normal (buildVerbosity buildFlags)
  564
+      distPref     = fromFlagOrDefault (useDistPref defaultSetupScriptOptions)
  565
+                     (buildDistPref buildFlags)
  566
+
  567
+  reconfigure verbosity distPref mempty [] globalFlags (const Nothing)
  568
+  build verbosity distPref mempty []
  569
+
  570
+  run verbosity buildFlags extraArgs
  571
+
558 572
 unpackAction :: UnpackFlags -> [String] -> GlobalFlags -> IO ()
559 573
 unpackAction unpackFlags extraArgs globalFlags = do
560 574
   let verbosity = fromFlag (unpackVerbosity unpackFlags)
1  cabal-install/cabal-install.cabal
@@ -93,6 +93,7 @@ Executable cabal
93 93
         Distribution.Client.PackageIndex
94 94
         Distribution.Client.PackageUtils
95 95
         Distribution.Client.ParseUtils
  96
+        Distribution.Client.Run
96 97
         Distribution.Client.Sandbox
97 98
         Distribution.Client.Setup
98 99
         Distribution.Client.SetupWrapper
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.