pw_watch: Update target/directory syntax

Since specifying which Ninja targets to build is now just as important
as which directory to build, update pw_watch's command line syntax to
better support specifying build targets and directories.

Before
  pw watch out#host#docs another/build/dir#stm32f429i

After
  pw watch out host docs --build-directory another/build/dir stm32f429i

Change-Id: Ic41dc6ce277ed240402877e9d875e8228aaac48b
diff --git a/docs/getting_started.md b/docs/getting_started.md
index d1fb372..1a46d86 100644
--- a/docs/getting_started.md
+++ b/docs/getting_started.md
@@ -43,7 +43,7 @@
 (4) Start the watcher. The watcher will invoke Ninja to build all the targets
 
 ```bash
-$ pw watch out#default#stm32f429i
+$ pw watch out default stm32f429i
 
  ▒█████▄   █▓  ▄███▒  ▒█    ▒█ ░▓████▒ ░▓████▒ ▒▓████▄
   ▒█░  █░ ░█▒ ██▒ ▀█▒ ▒█░ █ ▒█  ▒█   ▀  ▒█   ▀  ▒█  ▀█▌
@@ -246,7 +246,7 @@
 which Ninja targets to build:
 
 ```bash
-$ pw watch out#default#stm32f429i
+$ pw watch out default stm32f429i
 ```
 
 This is equivalent to the following Ninja invocation:
diff --git a/pw_watch/docs.rst b/pw_watch/docs.rst
index e7728b8..b5e78cc 100644
--- a/pw_watch/docs.rst
+++ b/pw_watch/docs.rst
@@ -38,7 +38,10 @@
 
 .. code:: sh
 
-  $ pw watch out/host out/disco
+  $ pw watch out/host
+
+  # Alternatively,
+  $ pw watch --build-directory out/host --build-directory out/disco
 
 The ``--patterns`` and ``--ignore_patterns`` arguments can be used to include
 and exclude certain file patterns that will trigger rebuilds.
diff --git a/pw_watch/py/pw_watch/watch.py b/pw_watch/py/pw_watch/watch.py
index 41a0d49..3c285bc 100755
--- a/pw_watch/py/pw_watch/watch.py
+++ b/pw_watch/py/pw_watch/watch.py
@@ -327,19 +327,23 @@
                         help=('directories to ignore during pw watch'),
                         default=[])
 
-    def build_dir_and_target(arg: str) -> BuildCommand:
-        args = arg.split('#')
-        return BuildCommand(pathlib.Path(args[0]), tuple(args[1:]))
+    parser.add_argument(
+        'build_targets',
+        nargs='*',
+        default=[],
+        help=('A Ninja directory to build, followed by specific targets to '
+              'build. For example, `out host docs` builds the `host` and '
+              '`docs` Ninja targets in the `out` directory. To build '
+              'additional directories, use `--build-directory`.'))
 
     parser.add_argument(
-        'build_commands',
-        nargs='*',
-        type=build_dir_and_target,
-        help=('Ninja directory to build. Can be specified multiple times to '
-              'build multiple configurations. Build targets may optionally be '
-              'specified by appending #TARGET to the directory. For example, '
-              'out/build_dir#pw_module#tests builds the pw_module and tests '
-              'targets in out/build_dir.'))
+        '--build-directory',
+        nargs='+',
+        action='append',
+        default=[],
+        metavar=('dir', 'target'),
+        help=('Allows additional build directories to be specified. Uses the '
+              'same syntax as `build_targets`.'))
 
 
 def _exit(code):
@@ -446,7 +450,8 @@
     return exclude_list + pigweed_exclude_list
 
 
-def watch(build_commands=None,
+def watch(build_targets=None,
+          build_directory=None,
           patterns=None,
           ignore_patterns=None,
           exclude_list=None):
@@ -472,9 +477,8 @@
     # If no build directory was specified, search the tree for GN build
     # directories and try to build them all. In the future this may cause
     # slow startup, but for now this is fast enough.
-    build_commands_tmp = build_commands
     build_commands = []
-    if not build_commands_tmp:
+    if not build_targets and not build_directory:
         _LOG.info('Searching for GN build dirs...')
         gn_args_files = []
         if os.path.isfile('out/args.gn'):
@@ -487,12 +491,14 @@
             if gn_build_dir.is_dir():
                 build_commands.append(BuildCommand(gn_build_dir))
     else:
+        if build_targets:
+            build_directory.append(build_targets)
         # Reformat the directory of build commands to be relative to the
         # currently directory.
-        for i, build_target in enumerate(build_commands_tmp, 1):
-            build_target_dir = build_target.build_dir
+        for build_target in build_directory:
             build_commands.append(
-                BuildCommand(build_target_dir, build_target.targets))
+                BuildCommand(pathlib.Path(build_target[0]),
+                             tuple(build_target[1:])))
 
     # Make sure we found something; if not, bail.
     if not build_commands:
diff --git a/targets/docs/target_docs.rst b/targets/docs/target_docs.rst
index dea7e26..4cfe192 100644
--- a/targets/docs/target_docs.rst
+++ b/targets/docs/target_docs.rst
@@ -17,20 +17,10 @@
 
 .. code:: sh
 
-  $ gn gen --args='pw_target_config = "//targets/docs/target_config.gni"' out/docs
-  $ ninja -C out/docs
-
-or
-
-.. code:: sh
-
-  $ gn gen out/docs
-  $ gn args
-  # Modify and save the args file to update the pw_target_config.
-  pw_target_config = "//targets/docs/target_config.gni"
-  $ ninja -C out/docs
+  $ gn gen out
+  $ ninja -C out docs
 
 Output
 ======
-Final HTML documentation will be placed in the ``gen/docs/html`` directory of
-the build.
+Final HTML documentation will be placed in the ``out/docs/gen/docs/html``
+directory of the build.