Unverified Commit 67276f87 authored by Francesco Gazzetta's avatar Francesco Gazzetta Committed by GitHub
Browse files

Merge pull request #4861 from fgaz/new-run/allow-running-tests-benchs

Allow new-run to run tests and benchmarks too
parents 05f6f13f 1454b2ff
......@@ -375,6 +375,7 @@ cabal new-run
``cabal new-run [TARGET [ARGS]]`` runs the executable specified by the
target, which can be a component, a package or can be left blank, as
long as it can uniquely identify an executable within the project.
Tests and benchmarks are also treated as executables.
See `the new-build section <#cabal-new-build>`__ for the target syntax.
......
......@@ -29,7 +29,7 @@ import Distribution.Simple.Setup
import Distribution.Simple.Command
( CommandUI(..), usageAlternatives )
import Distribution.Types.ComponentName
( componentNameString )
( showComponentName )
import Distribution.Text
( display )
import Distribution.Verbosity
......@@ -68,12 +68,13 @@ runCommand = Client.installCommand {
commandUsage = usageAlternatives "new-run"
[ "[TARGET] [FLAGS] [-- EXECUTABLE_FLAGS]" ],
commandDescription = Just $ \pname -> wrapText $
"Runs the specified executable, first ensuring it is up to date.\n\n"
"Runs the specified executable-like component (an executable, a test, "
++ "or a benchmark), first ensuring it is up to date.\n\n"
++ "Any executable in any package in the project can be specified. "
++ "A package can be specified if contains just one executable. "
++ "The default is to use the package in the current directory if it "
++ "contains just one executable.\n\n"
++ "Any executable-like component in any package in the project can be "
++ "specified. A package can be specified if contains just one "
++ "executable-like. The default is to use the package in the current "
++ "directory if it contains just one executable-like.\n\n"
++ "Extra arguments can be passed to the program, but use '--' to "
++ "separate arguments for the program from arguments for " ++ pname
......@@ -87,11 +88,11 @@ runCommand = Client.installCommand {
commandNotes = Just $ \pname ->
"Examples:\n"
++ " " ++ pname ++ " new-run\n"
++ " Run the executable in the package in the current directory\n"
++ " Run the executable-like in the package in the current directory\n"
++ " " ++ pname ++ " new-run foo-tool\n"
++ " Run the named executable (in any package in the project)\n"
++ " Run the named executable-like (in any package in the project)\n"
++ " " ++ pname ++ " new-run pkgfoo:foo-tool\n"
++ " Run the executable 'foo-tool' in the package 'pkgfoo'\n"
++ " Run the executable-like 'foo-tool' in the package 'pkgfoo'\n"
++ " " ++ pname ++ " new-run foo -O2 -- dothing --fooflag\n"
++ " Build with '-O2' and run the program, passing it extra arguments.\n\n"
......@@ -99,9 +100,10 @@ runCommand = Client.installCommand {
}
-- | The @build@ command does a lot. It brings the install plan up to date,
-- selects that part of the plan needed by the given or implicit targets and
-- then executes the plan.
-- | The @run@ command runs a specified executable-like component, building it
-- first if necessary. The component can be either an executable, a test,
-- or a benchmark. This is particularly useful for passing arguments to
-- exes/tests/benchs by simply appending them after a @--@.
--
-- For more details on how this works, see the module
-- "Distribution.Client.ProjectOrchestration"
......@@ -259,6 +261,8 @@ singleExeOrElse :: IO (UnitId, UnqualComponentName) -> TargetsMap -> IO (UnitId,
singleExeOrElse action targetsMap =
case Set.toList . distinctTargetComponents $ targetsMap
of [(unitId, CExeName component)] -> return (unitId, component)
[(unitId, CTestName component)] -> return (unitId, component)
[(unitId, CBenchName component)] -> return (unitId, component)
_ -> action
-- | Filter the 'ElaboratedInstallPlan' keeping only the
......@@ -307,31 +311,35 @@ selectPackageTargets targetSelector targets
| otherwise
= Left (TargetProblemNoTargets targetSelector)
where
-- Targets that can be executed
targetsExecutableLike =
concatMap (\kind -> filterTargetsKind kind targets)
[ExeKind, TestKind, BenchKind]
(targetsExesBuildable,
targetsExesBuildable') = selectBuildableTargets'
. filterTargetsKind ExeKind
$ targets
targetsExesBuildable') = selectBuildableTargets' targetsExecutableLike
targetsExes = forgetTargetsDetail
. filterTargetsKind ExeKind
$ targets
targetsExes = forgetTargetsDetail targetsExecutableLike
-- | For a 'TargetComponent' 'TargetSelector', check if the component can be
-- selected.
--
-- For the @run@ command we just need to check it is a executable, in addition
-- For the @run@ command we just need to check it is a executable-like
-- (an executable, a test, or a benchmark), in addition
-- to the basic checks on being buildable etc.
--
selectComponentTarget :: SubComponentTarget
-> AvailableTarget k -> Either TargetProblem k
selectComponentTarget subtarget@WholeComponent t
| CExeName _ <- availableTargetComponentName t
= either (Left . TargetProblemCommon) return $
selectComponentTargetBasic subtarget t
| otherwise
= Left (TargetProblemComponentNotExe (availableTargetPackageId t)
(availableTargetComponentName t))
= case availableTargetComponentName t
of CExeName _ -> component
CTestName _ -> component
CBenchName _ -> component
_ -> Left (TargetProblemComponentNotExe pkgid cname)
where pkgid = availableTargetPackageId t
cname = availableTargetComponentName t
component = either (Left . TargetProblemCommon) return $
selectComponentTargetBasic subtarget t
selectComponentTarget subtarget t
= Left (TargetProblemIsSubComponent (availableTargetPackageId t)
......@@ -395,12 +403,13 @@ renderTargetProblem (TargetProblemNoTargets targetSelector) =
renderTargetProblem (TargetProblemMatchesMultiple targetSelector targets) =
"The run command is for running a single executable at once. The target '"
++ showTargetSelector targetSelector ++ "' refers to "
++ renderTargetSelector targetSelector ++ " which includes the executables "
++ renderListCommaAnd
[ display name
| cname@CExeName{} <- map availableTargetComponentName targets
, let Just name = componentNameString cname
]
++ renderTargetSelector targetSelector ++ " which includes "
++ renderListCommaAnd ( ("the "++) <$>
showComponentName <$>
availableTargetComponentName <$>
foldMap
(\kind -> filterTargetsKind kind targets)
[ExeKind, TestKind, BenchKind] )
++ "."
renderTargetProblem (TargetProblemMultipleTargets selectorMap) =
......
......@@ -7,6 +7,8 @@
* Completed the 'new-run' command (#4477). The functionality is the
same of the old 'run' command but using nix-style builds.
Additionally, it can run executables across packages in a project.
Tests and benchmarks are also treated as executables, providing a
quick way to pass them arguments.
* Completed the 'new-bench' command (#3638). Same as above.
* Completed the 'new-exec' command (#3638). Same as above.
* Added a preliminary 'new-install' command (#4558, nonlocal exes
......
......@@ -869,44 +869,15 @@ testTargetProblemsRun config reportSubCase = do
[ ( CmdRun.TargetProblemNoTargets, mkTargetPackage "p-0.1" )
]
reportSubCase "test-only"
reportSubCase "lib-only"
assertProjectTargetProblems
"targets/test-only" config
"targets/lib-only" config
CmdRun.selectPackageTargets
CmdRun.selectComponentTarget
CmdRun.TargetProblemCommon
[ ( CmdRun.TargetProblemNoExes, mkTargetPackage "p-0.1" )
]
reportSubCase "variety"
assertProjectTargetProblems
"targets/variety" config
CmdRun.selectPackageTargets
CmdRun.selectComponentTarget
CmdRun.TargetProblemCommon $
[ ( const (CmdRun.TargetProblemComponentNotExe "p-0.1" cname)
, mkTargetComponent "p-0.1" cname )
| cname <- [ CLibName, CFLibName "libp",
CTestName "a-testsuite", CBenchName "a-benchmark" ]
] ++
[ ( const (CmdRun.TargetProblemIsSubComponent
"p-0.1" cname (ModuleTarget modname))
, mkTargetModule "p-0.1" cname modname )
| (cname, modname) <- [ (CTestName "a-testsuite", "TestModule")
, (CBenchName "a-benchmark", "BenchModule")
, (CExeName "an-exe", "ExeModule")
, (CLibName, "P")
]
] ++
[ ( const (CmdRun.TargetProblemIsSubComponent
"p-0.1" cname (FileTarget fname))
, mkTargetFile "p-0.1" cname fname)
| (cname, fname) <- [ (CTestName "a-testsuite", "Test.hs")
, (CBenchName "a-benchmark", "Bench.hs")
, (CExeName "an-exe", "Main.hs")
]
]
testTargetProblemsTest :: ProjectConfig -> (String -> IO ()) -> Assertion
testTargetProblemsTest config reportSubCase = do
......
name: p
version: 0.1
build-type: Simple
cabal-version: >= 1.2
library
exposed-modules: P
build-depends: base
......@@ -16,6 +16,6 @@ Building executable 'bar' for MultipleExes-1.0..
# cabal new-run
Up to date
# cabal new-run
cabal: The run command is for running a single executable at once. The target '' refers to the package MultipleExes-1.0 which includes the executables foo and bar.
cabal: The run command is for running a single executable at once. The target '' refers to the package MultipleExes-1.0 which includes the executable 'foo' and the executable 'bar'.
# cabal new-run
cabal: The run command is for running a single executable at once. The target 'MultipleExes' refers to the package MultipleExes-1.0 which includes the executables foo and bar.
cabal: The run command is for running a single executable at once. The target 'MultipleExes' refers to the package MultipleExes-1.0 which includes the executable 'foo' and the executable 'bar'.
......@@ -25,7 +25,7 @@ Building executable 'foo-exe' for bar-1.0..
# cabal new-run
cabal: No targets given and there is no package in the current directory. Use the target 'all' for all packages in the project or specify packages or components by name or location. See 'cabal build --help' for more details on target options.
# cabal new-run
cabal: The run command is for running a single executable at once. The target 'bar' refers to the package bar-1.0 which includes the executables foo-exe and bar-exe.
cabal: The run command is for running a single executable at once. The target 'bar' refers to the package bar-1.0 which includes the executable 'foo-exe' and the executable 'bar-exe'.
# cabal new-run
cabal: Ambiguous target 'foo-exe'. It could be:
bar:foo-exe (component)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment