diff --git a/docs/user_profiles/developers/developer_workflow.md b/docs/user_profiles/developers/developer_workflow.md index f6f4e017..8bf1c989 100644 --- a/docs/user_profiles/developers/developer_workflow.md +++ b/docs/user_profiles/developers/developer_workflow.md @@ -61,7 +61,6 @@ To see the options for the command we can run it with the `--help` command. ```console quick-create-dev -h -+ spack-start ************************************************************* HELP MESSAGE: quick-create-dev sets up a developer environment @@ -143,7 +142,6 @@ git clone --recursive --branch main git@github.com:Exawind/exawind-driver.git ex git clone --recursive --branch master git@github.com:Exawind/nalu-wind.git git clone --recursive --branch main git@github.com:Exawind/amr-wind.git quick-create-dev -s exawind@main amr-wind@main nalu-wind@master -+ spack-start + spack manager create-dev-env -s exawind@master amr-wind@main nalu-wind@master ==> Configuring spec exawind@master for development at path exawind ==> Warning: included configuration files should be updated manually [files=include.yaml] @@ -181,6 +179,10 @@ If they are newer than the install time then it will trigger an incremental buil Any changes you make in a dependency will also trigger a rebuild of the upstream software too. In this environment if you make a change in `amr-wind` it will also trigger a rebuild of the `exawind` package as well. +If you wish to just do a quick incremental build you can use the `spack manager make` command: +```console +spack manager make amr-wind -j=16 +``` ## Running Tests and Coming Back @@ -188,6 +190,10 @@ To run tests in a one off manner you can use the `spack build-env` command to ru This is further documented [here](https://sandialabs.github.io/spack-manager/user_profiles/developers/snapshot_workflow.html#running). We also have a function `build-env-dive` which is a beta feature that launches this same subshell in your terminal and dives into it. It is further documented [here](https://sandialabs.github.io/spack-manager/user_profiles/developers/useful_commands.html#build-env-dive). +Finally, if a `test` target is implementd for your software you can use `spack manager make` +```console +spack manager make --args="test -j16" amr-wind +``` If you wish to come back to an environment later, or in a new shell you can just run ```console diff --git a/docs/user_profiles/developers/snapshot_workflow.md b/docs/user_profiles/developers/snapshot_workflow.md index d5b7eb7b..ae12828d 100644 --- a/docs/user_profiles/developers/snapshot_workflow.md +++ b/docs/user_profiles/developers/snapshot_workflow.md @@ -1,5 +1,9 @@ # Snapshot Developer Workflow Example +**WARNING:** This documentation is fairly specific to ExaWind and has not been generalized for an arbitrary `Spack-Manager` project. +THe information is still useful. However, you may not translate directly or be able to follow along. + + In this tutorial we will look at how to setup a developer workflow using snapshots if they are provided on your machine. ## Setup diff --git a/manager/cmd/manager.py b/manager/cmd/manager.py index 1d19bf79..e190a396 100644 --- a/manager/cmd/manager.py +++ b/manager/cmd/manager.py @@ -15,6 +15,7 @@ import spack.extensions.manager.manager_cmds.find_machine as find_machine import spack.extensions.manager.manager_cmds.include as include import spack.extensions.manager.manager_cmds.location as location +import spack.extensions.manager.manager_cmds.make as make # import spack.extensions.manager.manager_cmds.pin as pin # import spack.extensions.manager.manager_cmds.snapshot as snapshot @@ -44,6 +45,7 @@ def setup_parser(subparser): find_machine.add_command(sp, _subcommands) include.add_command(sp, _subcommands) location.add_command(sp, _subcommands) + make.add_command(sp, _subcommands) # pin.add_command(sp, _subcommands) # snapshot.add_command(sp, _subcommands) diff --git a/manager/manager_cmds/make.py b/manager/manager_cmds/make.py new file mode 100644 index 00000000..9e90653a --- /dev/null +++ b/manager/manager_cmds/make.py @@ -0,0 +1,94 @@ +# Copyright (c) 2022, National Technology & Engineering Solutions of Sandia, +# LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. +# Government retains certain rights in this software. +# +# This software is released under the BSD 3-clause license. See LICENSE file +# for more details. + +import os + +import llnl.util.tty as tty +from llnl.util.filesystem import working_dir + +import spack.build_environment as build_environment +import spack.builder +import spack.cmd +import spack.paths +from spack.util.executable import Executable + +""" +This was originally implemented by Tim Fuller @tjfulle +With his permission it is being published in the spack manager +subset of commands +""" +description = "make SPEC directly with `make` or `ninja`" +section = "manager" +level = "short" + + +def setup_parser(parser): + parser.add_argument( + "spec", metavar="SPEC", nargs="+", help="Spack package to build (must be a develop spec)" + ) + build_args = parser.add_mutually_exclusive_group() + build_args.add_argument( + "--args", + "-a", + default="", + required=False, + help="Additional arguments to pass to make as a string i.e. `--args='test -j16'`", + ) + build_args.add_argument( + "-j", + type=int, + required=False, + help="number of ranks to build with (specialized implementation of --args)", + ) + + +def make(parser, args): + env = spack.cmd.require_active_env(cmd_name="make") + specs = spack.cmd.parse_specs(args.spec) + if args.j: + extra_make_args = [f"-j{args.j}"] + else: + extra_make_args = args.args.split() + if not specs: + tty.die("You must supply a spec.") + if len(specs) != 1: + tty.die("Too many specs. Supply only one.") + spec = env.matching_spec(specs[0]) + if spec is None: + tty.die(f"{specs[0]}: spec not found in environment") + elif not spec.is_develop: + tty.die(f"{specs[0]}: must be a develop spec") + pkg = spec.package + builder = spack.builder.create(pkg) + if hasattr(builder, "build_directory"): + build_directory = os.path.normpath(os.path.join(pkg.stage.path, builder.build_directory)) + else: + build_directory = pkg.stage.source_path + try: + build_environment.setup_package(spec.package, False, "build") + except TypeError: + build_environment.setup_package(spec.package, False) + + if not os.path.isdir(build_directory): + tty.die( + ( + "Build directory does not exist. " + "Please run `spack install` to ensure the build is " + "configured properly" + ) + ) + + with working_dir(build_directory): + make_program = "ninja" if os.path.exists("build.ninja") else "make" + make = Executable(make_program) + make(*extra_make_args) + + +def add_command(parser, command_dict): + subparser = parser.add_parser("make", help=description) + setup_parser(subparser) + command_dict["make"] = make diff --git a/tests/test_make.py b/tests/test_make.py new file mode 100644 index 00000000..4df5ce67 --- /dev/null +++ b/tests/test_make.py @@ -0,0 +1,26 @@ +# Copyright (c) 2022, National Technology & Engineering Solutions of Sandia, +# LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. +# Government retains certain rights in this software. +# +# This software is released under the BSD 3-clause license. See LICENSE file +# for more details. + +import pytest + +import spack.environment as ev +import spack.extensions +import spack.main + +env = spack.main.SpackCommand("env") +manager = spack.main.SpackCommand("manager") +add = spack.main.SpackCommand("add") + + +@pytest.mark.usefixtures("mutable_mock_env_path_wh_manager", "mock_packages", "mock_fetch") +def test_spackManagerMakeRequiresDevelopSpec(): + env("create", "test") + with ev.read("test"): + add("mpich") + with pytest.raises(spack.main.SpackCommandError): + out = manager("make", "mpich") + assert "must be a develop spec" in str(out)