| # Command line interface (CLI) tools guidelines |
| |
| |
| ## Overview |
| |
| The command line is the primary interface for engineers to interact with Fuchsia |
| and its tools, drivers, and devices. Providing clear, consistent, and coherent |
| tooling is critical to ensuring better productivity and satisfaction for all the |
| engineers and teams developing Fuchsia. This document provides guidance for |
| developing and evolving CLI tools for Fuchsia. |
| |
| The guidelines are divided into three main sections: |
| |
| * [Considerations](#considerations) |
| * [UX guidelines](#ux-guidelines) |
| * [Technical guidelines](#technical-guidelines) |
| |
| <br/> |
| |
| ## Considerations {#considerations} |
| |
| Fuchsia, and the devices running Fuchsia, make up a broad developer surface with |
| varying needs and requirements for users at all levels of the stack. When |
| developing Fuchsia tools and subtools, it’s important to ensure consistency, |
| architectural predictability, reliability, and ongoing support and maintenance |
| for end users. |
| |
| Depending on the distribution scope, different tools will have different |
| expectations. The following guidelines and rubric will help |
| tool developers understand the UX considerations, technical requirements, and |
| documentation expectations for Fuchsia CLI tools. |
| |
| |
| Note: These guidelines focus on host-side CLI tools for Fuchsia development. |
| Shell scripts, test tools, target-side tools, and generic 1P or 3P tools, such |
| as C or Rust compilers, are out of scope. |
| |
| |
| ## Audience |
| |
| Fuchsia CLI tools are built, maintained, and used by many different people and |
| teams. A one-size-fits-all approach will not serve users who are working in |
| separate contexts, for example in-tree versus out-of-tree or SDK users. |
| Additionally, some users may have unique workflows for specific areas of |
| development, such as drivers, kernel, or product configuration. |
| |
| When developing or updating Fuchsia tools, understanding the target audience, |
| their context, and their specific use cases is critical to building a better |
| developer experience. |
| |
| |
| ## Fuchsia CLI tools |
| |
| Ensuring that CLI tools are discoverable and well-documented will make it easier |
| for developers to find existing tools, understand workflows, and identify gaps. |
| In some cases, it may be more helpful to extend an existing tool to add new |
| features rather than creating a new subtool. For example, if you want to flash a |
| device over TCP, prefer adding a TCP option to `ffx target flash` rather than |
| creating a separate tool. |
| |
| |
| Tip: Refer to the [Tools overview](/reference/tools) to see what |
| Fuchsia CLI tools are currently available in the SDK and in the source code. You |
| can also run `ffx --help` in the command line to explore available ffx subtools, |
| commands, and options. |
| |
| |
| ### Which tool to use? |
| |
| Deciding which tool, script, or library to use will depend on your use case. |
| **ffx** is the CLI tool for interacting with target devices or developing |
| products that run Fuchsia, such as smart displays. In-tree tools like **fx** are |
| generally scripts that know about things outside of Fuchsia, for example, build |
| systems, repositories, and integrations. |
| |
| > **Examples** |
| > |
| > * Use ffx to interact with Fuchsia devices (e.g., `ffx target flash `to |
| > flash a Fuchsia image on a device, or `ffx component run `to interact with |
| > components on a device) |
| > * Use fx to develop Fuchsia in tree (e.g., `fx set` to configure a build, or |
| > `fx test` to run tests on a host machine) |
| |
| |
| #### CLI tools to interact with or manage Fuchsia devices |
| |
| * Distributed as part of the SDK; also used by developers developing for |
| Fuchsia, including in-tree developers. |
| * Emphasize discoverability, consistency, and stability by following UX |
| guidelines |
| * Higher expectations for documentation, and `--help` content in order to |
| support developers |
| * Some of these tools are used both directly by developers, and via |
| integration scripts or build systems. |
| |
| |
| #### In-tree tools for Fuchsia development in the platform source tree |
| |
| * For in-tree developers working in fuchsia.git |
| * Emphasize low barrier of entry and allowing rapid evolution for tools, |
| commonly the main user is the tool author |
| * Expected to change more often, may not be well-documented |
| |
| |
| #### Build system tools and scripts (e.g., cmc, fidlc) |
| |
| * Controlled exclusively through command line options and/or response files. |
| * Emphasize stability in CLI to aid use in build systems. |
| * Distributed as part of the SDK; the entire population of users is unknown, |
| and the integrations are not known/accessible. |
| * Typically never run directly by developers, only run as part of a build |
| system. |
| |
| |
| #### Alternatives to tools |
| |
| In addition to ffx, there are libraries for interacting with and scripting |
| interactions with Fuchsia targets from development hosts. |
| |
| * [Fuchsia Controller](/docs/contribute/governance/rfcs/0222_fuchsia_controller.md) |
| is a Python interface that allows developers to interact with targets via FIDL |
| * [Lacewing](/docs/reference/testing/what-tests-to-write.md) |
| is a host-side system interaction test built on top of Fuchsia Controller for |
| scripting tests that cannot run purely on the target side—e.g., tests that |
| require rebooting the target. |
| |
| |
| ## ffx overview |
| |
| ffx is the top-level tool that provides core developer functionality for |
| interacting with devices running Fuchsia. ffx has an extensible interface that |
| enables other tools which are useful for Fuchsia developers to be registered as |
| subtools, making it easier to discover them. |
| |
| The goal of ffx is to create a cohesive tooling platform that provides a stable |
| command line argument surface and a standardized JSON output for commands. |
| Ideally, ffx subtools will be able to use common services such as configuration, |
| logging, error handling, and testing frameworks. This will provide a robust |
| collection of tools that are loosely coupled and can be adapted to specific |
| project needs. |
| |
| |
| ### ffx subtool lifecycle |
| |
| Before developing, updating, or deprecating an ffx subtool, there are several |
| considerations to take into account. Who is the tool for? Will it be available |
| in the SDK or in-tree only? Does a similar tool already exist? |
| |
| Note: Internal Googlers see [Subtool lifecycle playbook](https://docs.google.com/presentation/d/1U1r6gHaBVhAYJe9Fu_tWs9SvrXyoijnGvWRRVMAiHFM/edit?usp=sharing&resourcekey=0-TOkvK6IUC8cq23l6WufjTw) |
| for detailed information on policy and process for developing or changing |
| Fuchsia tools, or making updates to the tooling platform. |
| |
| When building a new tool, use the following prompts as a guide. You can also |
| consult the [CLI tool development rubric](#rubric) to determine whether your |
| tool meets Fuchsia requirements. |
| |
| |
| #### UX considerations |
| |
| > Who are the intended users of the tool and how will they use it? |
| > |
| > * Where does the tool fit in the existing command structure? |
| > |
| > Can human users and scripts/other tools use the tool equally well? |
| > |
| > * Is it clearly defined which parts of the tool are intended for machine and |
| > automated workflows? |
| > * Is the machine interface well documented? |
| > |
| > Is the command interface in line with Fuchsia guidelines and best |
| > practices? |
| > |
| > * Does the tool follow UX guidelines? |
| > * Does the tool provide solid documentation and help for the user |
| > following the [CLI Help requirements](/docs/development/api/cli_help.md)? |
| > * Does the tool provide clear and useful error messages? |
| > * Have you considered [accessibility](/docs/concepts/accessibility/accessibility_framework.md)? |
| > |
| > Have other users tested the tool? |
| > |
| > * Ask someone outside of your team to run through the commands and outputs |
| > to see if they are usable. |
| |
| |
| #### Technical requirements |
| |
| > Is the tool compiled and independent of the runtime environment? |
| > |
| > * Does the tool minimize runtime link dependencies? |
| > * Is the tool built from the fuchsia.git source tree? |
| > |
| > Does the tool support machine interfaces? |
| > |
| > * Is there comprehensive documentation for machine interfaces? |
| > * Does the tool include manifest or JSON files for machine input? |
| > |
| > What are the tool’s compatibility guarantees? |
| > |
| > Does the tool collect metrics? |
| > |
| > * Is it compliant with privacy requirements for collecting metrics? |
| |
| |
| #### Product management |
| |
| > How will you distribute the tool? |
| > |
| > * Will it only be available in-tree or included in the SDK? |
| > |
| > Who will own the maintenance of the tool? |
| > |
| > * Is there a plan in place to update, evolve, or deprecate the tool? |
| > |
| > Where can users go to find answers to common questions or ask new |
| > questions? |
| > |
| > How are you tracking user-reported issues? |
| > |
| > * Does the help output and error output include a bug link? |
| > |
| > What events have been instrumented? Where can one find metrics for this |
| > tool? |
| |
| <br/> |
| |
| |
| ## CLI tool development rubric {#rubric} |
| |
| Tip: Score each criterion on a scale of 1-5 (low to high) based on how well your |
| tool meets it. Identify areas for improvement, then prioritize enhancements |
| based on user needs and project goals. |
| |
| <table> |
| <tr> |
| <td style="background-color: null"> |
| <strong>UX Considerations</strong> |
| </td> |
| <td style="background-color: null"><strong>Description</strong> |
| </td> |
| <td style="background-color: null"><strong>Score</strong> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Target audience |
| </td> |
| <td style="background-color: null">Clearly defined intended users and their |
| usage scenarios |
| </td> |
| <td style="background-color: null">(1-5) |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Human & machine usability |
| </td> |
| <td style="background-color: null">Tool is equally usable for both human |
| users and scripts/automation |
| </td> |
| <td style="background-color: null"> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Fuchsia CLI guidelines |
| </td> |
| <td style="background-color: null">Aligns with established guidelines and UX |
| design principles |
| </td> |
| <td style="background-color: null"> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Help & documentation |
| </td> |
| <td style="background-color: null">Tool provides clear documentation and help |
| output |
| </td> |
| <td style="background-color: null"> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Error messages |
| </td> |
| <td style="background-color: null">Error messages are clear, actionable, and |
| provide helpful context |
| </td> |
| <td style="background-color: null"> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Accessibility |
| </td> |
| <td style="background-color: null">Tool design accounts for accessibility |
| needs (e.g., color blindness, screen readers) |
| </td> |
| <td style="background-color: null"> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Testing |
| </td> |
| <td style="background-color: null">Tool has been tested by users outside of |
| the development team |
| </td> |
| <td style="background-color: null"> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">  |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null"><strong>Technical Requirements</strong> |
| </td> |
| <td style="background-color: null"><strong>Description</strong> |
| </td> |
| <td style="background-color: null"><strong>Score</strong> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Programming language |
| </td> |
| <td style="background-color: null">Tool is written in C++, Rust, or Go; not |
| Bash, Python, Perl, or JavaScript |
| </td> |
| <td style="background-color: null">(1-5) |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Source tree |
| </td> |
| <td style="background-color: null">Tool uses the same build and dependency |
| structure as the code in fuchsia.git |
| </td> |
| <td style="background-color: null"> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Machine readability |
| </td> |
| <td style="background-color: null">Tool supports machine-readable interfaces |
| </td> |
| <td style="background-color: null"> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Compatibility guarantees |
| </td> |
| <td style="background-color: null">Compatibility guarantees are well-defined |
| </td> |
| <td style="background-color: null"> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Build system |
| </td> |
| <td style="background-color: null">Tool is unbiased towards any build system |
| or environment |
| </td> |
| <td style="background-color: null"> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Tests |
| </td> |
| <td style="background-color: null">Tool includes both unit tests and |
| integration tests if distributed in the SDK or included in the build system |
| </td> |
| <td style="background-color: null"> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">  |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null"><strong>Product Management</strong> |
| </td> |
| <td style="background-color: null"><strong>Description</strong> |
| </td> |
| <td style="background-color: null"><strong>Score</strong> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Maintenance |
| </td> |
| <td style="background-color: null">Clear ownership and maintenance plan for |
| the tool |
| </td> |
| <td style="background-color: null">(1-5) |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">User support |
| </td> |
| <td style="background-color: null">Defined channels for user support (e.g., |
| forums, FAQs) |
| </td> |
| <td style="background-color: null"> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Issue tracking |
| </td> |
| <td style="background-color: null">System in place for tracking and |
| addressing user-reported issues |
| </td> |
| <td style="background-color: null"> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Metrics |
| </td> |
| <td style="background-color: null">Relevant events are instrumented, and |
| metrics are available |
| </td> |
| <td style="background-color: null"> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: null">Update/deprecation plan |
| </td> |
| <td style="background-color: null">Clear plan for the future of the tool |
| (updates, evolution, or deprecation) |
| </td> |
| <td style="background-color: null"> |
| </td> |
| </tr> |
| </table> |
| |
| |
| > **Key** |
| > |
| > 1. Needs significant improvement |
| > 2. Needs improvement |
| > 3. Meets minimum requirements |
| > 4. Exceeds expectations |
| > 5. Excellent |
| |
| <br/> |
| |
| * * * |
| |
| <br/> |
| |
| ## UX guidelines {#ux-guidelines} |
| |
| Providing clear, consistent, and coherent tooling is critical to ensuring better |
| productivity and satisfaction for all the engineers and teams developing |
| Fuchsia. These UX guidelines are designed to help people building and |
| integrating CLI tools create a consistent developer experience for users. |
| These guidelines use Fuchsia’s main developer tool, ffx, to illustrate best |
| practices. |
| |
| Key Point: [ffx](/reference/tools/sdk/ffx) is a unified tooling platform and |
| command line interface (CLI) for Fuchsia development. The ffx tool is the |
| top-level interface for connecting to, flashing, and communicating with a device |
| running Fuchsia. ffx tools are used by humans and in scripts, and should be |
| designed for readability and ease of use. |
| |
| |
| ### Design principles |
| |
| Always aim to make the ffx interface as simple as possible. |
| |
| * **Put the user first:** Consider the needs of all potential users: tool |
| users, tool integrators, tool builders, and tool platform builders. |
| * **Be clear:** Ensure the tool's purpose, usage, and feedback are easily |
| understandable. Provide helpful and actionable error messages and help text. |
| * **Be consistent:** Maintain consistency in input/output patterns, language, |
| and Fuchsia core concepts. |
| * **Take a holistic approach:** Ensure tools function effectively |
| independently and integrated with others, with consistent behavior across |
| contexts. |
| * **Build for efficiency:** Design tools to be performant and responsive, |
| minimizing latency and enabling a rapid iteration cycle. |
| * **Prioritize accessibility:** Use plain language and adhere to accessibility |
| guidelines for CLIs, ensuring usability for users with diverse abilities. |
| * **Plan ahead:** Strive for flexibility, extensibility, and scalability to |
| accommodate future needs and growth. |
| |
| |
| ### ffx user constituencies |
| |
| * **Tool users:** Direct users of ffx tools for Fuchsia workflows (either |
| platform or product) |
| * **Tool integrators:** uses ffx tools by integrating them with other tools or |
| in specific environments. This includes authoring new higher level tools that |
| wrap ffx functionality. |
| * **Tool builders:** author and maintain one or more tools hosted by ffx |
| * **Tool platform builders:** evolve and maintain the underlying tooling |
| platform for running ffx tools |
| |
| |
| <br/> |
| |
| ## Command structure |
| |
| ffx commands are structured as a tree under the root ffx command. This supports |
| a hierarchical organization which streamlines UX: instead of having to iterate |
| through a list of tools, users can traverse the tree of commands, eliminating |
| paths unrelated to their desired functionality. |
| |
| Paths on the ffx command tree should follow a **noun** **noun**… **verb** |
| structure. Command paths consist of internal nodes that are nouns with |
| increasing specificity that culminate in a leaf node that is a verb, which is |
| the actual command. |
| |
| For example, in `ffx component run <URL> `there is a root command noun (ffx), a |
| subtool noun (component), a subcommand verb (run), and an argument (URL), which |
| is the value passed to the command when it is executed. |
| |
| |
| ``` |
| ffx component run /core/ffx-laboratory:hello-world fuchsia-pkg://fuchsia.com/hello-world-rust#meta/hello-world-rust.cm |
| ``` |
| |
| <br/> |
| |
| ### Command structure design considerations |
| |
| When developing a new CLI tool, it’s important to consider the developer |
| experience across the platform. Keep the number of commands under a tool |
| organized and reasonable. Avoid repetition, or adding unrelated commands to a |
| tool. Provide sensible organization of the commands in the help and |
| documentation. |
| |
| In general, for tools that cover common workflows (such as host-to-target |
| interaction, system integration, and publishing), prefer extending an existing |
| tool rather than creating a new standalone tool. Add flags, options, or |
| subcommands to take advantage of shared code and functionality. |
| |
| However, if the overall workflow enabled does not exist, consider a new command |
| or a higher level subgrouping. Review the existing command surface [reference |
| documentation](/reference/tools/sdk/ffx.md) to understand |
| where the new command or tool may fit. |
| |
| |
| ### Audience |
| |
| Tools may be used for different development tasks. On a large team, these roles |
| may be separate people. Consider which users may use a tool and cater the tool |
| to the audience. |
| |
| > **Examples** |
| > |
| > * Component development |
| > * Driver development |
| > * Fuchsia development (SDK) |
| > * Build integration (GN, etc.) |
| > * System integrators (e.g., on-device network tools) |
| > * Publishing (from dev host to server) |
| > * Deployment (from server to customers) |
| |
| |
| Tools may have different integration expectations. For example, a developer |
| doing component development may expect tools to integrate with their Integrated |
| Development Environment (IDE), while a build integration tool may be called from |
| a script. |
| |
| |
| ### Group related commands |
| |
| Related commands for Fuchsia workflows should be grouped under a common tool. |
| For example, ffx is organized into subtools and command groups that map to |
| high-level Fuchsia subsystems. This helps encourage the team toward a shared |
| workflow and provides a single point of discovery. |
| |
| |
| ### Scope |
| |
| Command line tools can vary in scope depending on user needs and goals. Create |
| tools that are ergonomic for their purpose. Sometimes, a simple, single-purpose |
| tool may be useful to automate a time-consuming process. Larger, more featureful |
| tools should encompass an entire task at the user (developer) level. |
| |
| > **Examples** |
| > |
| > * Avoid making a tool that accomplishes one small step of a task; |
| > instead design a tool that will perform a complete task. |
| > * For example, when developing a C++ application: run the preprocessor, |
| > run the compiler, run the linker, start the built executable. |
| > * Prefer tools that will accomplish all the steps needed by default, but |
| > allow for an advanced user to do a partial step. |
| > * For example, passing an argument to ask the C++ compiler to only run |
| > the preprocessor. |
| |
| |
| ## ffx subtool design considerations |
| |
| ffx subtools (previously called plugins) are organized into command groups that |
| map to high-level Fuchsia subsystems. In `ffx target`, ffx is the root command |
| and target is the subtool (subcommand). ffx subtools may have their own |
| arguments and options (e.g., `ffx target list --format [format] [nodename]`). |
| |
| The ffx CLI should follow a standard structure and vocabulary so that users |
| experience ffx as an integrated whole rather than a patchwork of separate tools. |
| A user familiar with one ffx tool should be able to predict and understand the |
| command names in another tool. |
| |
| When designing ffx subtools, there will be tradeoffs between complexity and |
| brevity. In general, ffx subtools should map to documented Fuchsia concepts or |
| subsystems (e.g., `target, package, bluetooth`). When possible, subtool command |
| groups should be limited to a primary feature or capability, with additional |
| options added as flags. Adding a secondary command group is discouraged, but |
| sometimes is unavoidable. Clarity is more important than brevity. |
| |
| |
| ### Naming |
| |
| Use well-known US English nouns for ffx commands, which are also known as ffx |
| subtools. Subcommands should be imperative verbs. |
| |
| * Well-known nouns are those that appear in documentation as common use for |
| Fuchsia concepts or subsystems. See the [ffx reference documentation](/reference/tools/sdk/ffx) |
| for a list of current ffx commands. |
| * ffx subtool names should be three characters or longer. (e.g., `ffx |
| bluetooth`, not `ffx bt`) |
| * Commands and options should always be lowercase letters (a-z) |
| * Subtool names should not contain hyphens. Options (flags) may use single |
| hyphens to separate words if necessary (e.g., `--log-level`). |
| |
| <br/> |
| |
| <table> |
| <tr> |
| <td> |
| <strong>tool</strong> |
| </td> |
| <td><strong>subtool</strong> |
| </td> |
| <td><strong>command group (1)</strong> |
| </td> |
| <td><strong>command group (2)</strong> |
| </td> |
| <td><strong>subcommand</strong> |
| </td> |
| </tr> |
| <tr> |
| <td>Top level, root, or parent command. (Noun) |
| </td> |
| <td>Also called subcommand (formerly plugin). Maps to a Fuchsia concept or |
| subsystem. (Noun) |
| </td> |
| <td>Also called feature, capability, or subcommand. Primary feature related |
| to a Fuchsia concept. (Noun) |
| </td> |
| <td>Secondary feature or capability related to the command group. (Noun) |
| </td> |
| <td>Direct action or command to execute. (Verb) |
| </td> |
| </tr> |
| <tr> |
| <td><code>ffx</code> |
| </td> |
| <td><code>emu</code> |
| </td> |
| <td style="background-color: #666666"> |
| </td> |
| <td style="background-color: #666666"> |
| </td> |
| <td><code>start</code> |
| </td> |
| </tr> |
| <tr> |
| <td><code>ffx</code> |
| </td> |
| <td><code>component</code> |
| </td> |
| <td><code>storage</code> |
| </td> |
| <td style="background-color: #666666"> |
| </td> |
| <td><code>copy</code> |
| </td> |
| </tr> |
| <tr> |
| <td><code>ffx</code> |
| </td> |
| <td><code>target</code> |
| </td> |
| <td><code>update</code> |
| </td> |
| <td><code>channel</code> |
| </td> |
| <td><code>list</code> |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| ### Structure |
| |
| Follow the noun-noun-verb structure. Nest related commands as subcommands under |
| a parent tool. |
| |
| |
| <table> |
| <tr> |
| <td><code>ffx package build</code> |
| <p> |
| <code>ffx driver devices list</code> |
| <p> |
| <code>ffx component run</code> |
| </td> |
| <td><code>ffx-package package build </code> |
| <p> |
| <code>ffx driver list-devices</code> |
| <p> |
| <code>ffx run-component</code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| Don't create tools with hyphenated names, like `add-foo` and `remove-foo`. |
| Instead create a `foo` command that accepts `add` and `remove` subcommands. |
| |
| |
| <table> |
| <tr> |
| <td><code>ffx target add</code> |
| <p> |
| <code>ffx target remove</code> |
| <p> |
| <code>ffx bluetooth gap discovery start</code> |
| <p> |
| <code>ffx bluetooth gap discovery stop</code> |
| </td> |
| <td><code>ffx add-target</code> |
| <p> |
| <code>ffx remove-target</code> |
| <p> |
| <code>ffx bluetooth gap start-discovery</code> |
| <p> |
| <code>ffx bluetooth gap stop-discovery</code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| ### Actions |
| |
| Use clear, concise verbs that accurately reflect the command’s action. |
| |
| Prefer subcommands to multiple tools that are hyphenated (e.g., avoid `foo-start, |
| foo-stop, foo-reset`; instead have `foo` that accepts commands |
| `start|stop|reset`) |
| |
| <br/> |
| |
| <table> |
| <tr> |
| <td><code>ffx daemon start</code> |
| <p> |
| <code>ffx daemon stop</code> |
| <p> |
| <code>ffx package archive add</code> |
| <p> |
| <code>ffx package archive remove</code> |
| </td> |
| <td><code>ffx daemon launch</code> |
| <p> |
| <code>ffx daemon halt</code> |
| <p> |
| <code>ffx package archive create-new</code> |
| <p> |
| <code>ffx package archive delete</code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| ### Consistency |
| |
| Align with established Fuchsia terminology and patterns to minimize cognitive |
| load. Use common verb pairings (e.g., `start/stop, add/remove, import/export`) |
| and follow existing ffx command patterns. |
| |
| <br/> |
| |
| <table> |
| <tr> |
| <td><strong>Common verb pairings</strong> |
| <p> |
| <code>add/remove</code> |
| <p> |
| <code>start/stop</code> |
| <p> |
| <code>get/set/unset</code> |
| <p> |
| <code>enable/disable</code> |
| <p> |
| <code>connect/disconnect</code> |
| <p> |
| <code>create/delete</code> |
| <p> |
| <code>register/deregister</code> |
| </td> |
| <td><strong>Standard ffx subcommands (verbs)</strong> |
| <p> |
| <code>list</code> |
| <p> |
| <code>show</code> |
| <p> |
| <code>listen</code> |
| <p> |
| <code>watch</code> |
| <p> |
| <code>test</code> |
| <p> |
| <code>run</code> |
| <p> |
| <code>log</code> |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| ### Brevity |
| |
| Aim for the shortest command and option names without sacrificing clarity or |
| discoverability. Command names should be at least 3 characters long. |
| |
| Avoid acronyms or abbreviations with ambiguous definitions (e.g., `bt` could mean |
| bluetooth, Bigtable, or British Telecom on different Google products). |
| |
| <br/> |
| |
| <table> |
| <tr> |
| <td><code>ffx bluetooth</code> |
| </td> |
| <td><code>ffx bt</code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| ## Command line arguments |
| |
| An argument is a value that is passed to a command when it is executed. |
| Arguments in ffx can be exact text, ordered (also known as positional |
| arguments), or unordered options (also called flags). |
| |
| |
| ### Options |
| |
| Options (also called flags) are unordered, and can appear anywhere after the |
| group or command in which they're defined, including at the very end. See the |
| [top-level ffx options](/reference/tools/sdk/ffx). |
| |
| * Options should be at least 3 characters long and human readable |
| * Options may use single hyphens to separate words if necessary. Use a single |
| dash between words in multi-word option names (e.g., `--log-level`) |
| * Preface options with a double hyphen (--). Single hyphens (-) may be used |
| for single-character options, however short flags should be used sparingly to |
| avoid ambiguity. See [guidance on short aliases](#short-aliases) |
| |
| |
| Caution: Options should not overlap with top-level ffx commands (e.g., `ffx |
| target`) |
| |
| <table> |
| <tr> |
| <td><code>--peer-target</code> |
| </td> |
| <td><code>--target</code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| Do not use uppercase letters for options. Do not use numeric options. If a |
| numeric value is needed, make a keyed option, like `--repeat <number>`. |
| |
| <br/> |
| |
| <table> |
| <tr> |
| <td><code>--timeout</code> |
| <p> |
| <code>-v, --verbose</code> |
| </td> |
| <td><code>-T, --timeout</code> |
| <p> |
| <code>-V, --verbose</code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| ### Switches |
| |
| The presence of a switch means the feature it represents is 'on' while its |
| absence means that it is 'off.' Switches default to 'off.' |
| |
| * All switches must be documented (hidden switches are not allowed) |
| * Unlike keyed options, a switch does not accept a value. For example,` -v` |
| is a common switch meaning verbose; it doesn't take a value. |
| |
| Use switches to evolve the functionality of a tool. Switches are more easily |
| controlled than feature flags. |
| |
| <br/> |
| |
| <table> |
| <tr> |
| <td><code>--use-new-feature</code> |
| <p> |
| <code>--no-use-new-feature</code> |
| </td> |
| <td><code>--config new-feature=true</code> |
| <p> |
| <code>--config new-feature=false</code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| Running switches together is not allowed, e.g., `-xzf` or `-vv`, each |
| must be separate: `-x -z -f` or `-v -v`. |
| |
| |
| ### Short aliases {#short-aliases} |
| |
| In general, UX recommends avoiding short flags. However, we recognize that it |
| can be helpful for experts to use short aliases for some frequently used |
| options. Overuse of short aliases can introduce confusion and ambiguity (e.g., |
| does `-b` mean `--bootloader` or `--product-bundle` or `--build-dir`?). Short |
| aliases should be used sparingly. |
| |
| * Every option does not need an alias. When in doubt, spell it out. |
| * Commands with serious irreversible consequences should have long names, so |
| that they are not invoked as the result of a typographical error |
| * Only use lowercase letters; do not use numbers |
| |
| |
| Short aliases should be used in a consistent manner throughout the ffx CLI |
| (e.g., `-c` should not be shorthand for `--config` in the main ffx tool, |
| `--command` in one subtool, and `--font-color` in another). |
| |
| <br/> |
| |
| <table > |
| <tr> |
| <td><code>--capability</code> |
| <p> |
| <code>--console</code> |
| <p> |
| <code>--console-type</code> |
| </td> |
| <td><code>-c, --command</code> |
| <p> |
| <code>-c, --remote-component</code> |
| <p> |
| <code>-c, --font-color</code> |
| <p> |
| <code>-c, --cred</code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| ### Positional arguments |
| |
| Positional or ordered arguments must appear after the command name and are |
| identified by the order in which they appear. Only use ordered arguments for |
| parameters where the sequence is crucial for understanding (e.g., |
| `copy <source> <destination>`). In general, avoid positional arguments and |
| prefer exact text arguments with specific options. |
| |
| Caution: Avoid using more than one positional argument in the same command. |
| Positional arguments should relate to the same type of elements (e.g., filenames) |
| that are processed together. Do not use positional arguments that refer to |
| different elements. |
| |
| <table > |
| <tr> |
| <td><code>ffx product list --version <version></code> |
| </td> |
| <td><code>ffx product list <product> <version></code> |
| <p> |
| <code>ffx fuzz set <URL> <name> <value></code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| ## Help output |
| |
| The CLI help text, accessible via `--help`, is a vital communication tool for |
| users. It should be clear, concise, and provide essential information at a |
| glance as well as a path to more in-depth documentation where needed. See [CLI |
| tool help requirements](/docs/development/api/cli_help.md) |
| for more detail and examples. |
| |
| |
| ### Writing help text |
| |
| The terminal is a minimalistic text environment. Providing too much information |
| can make it difficult for users to get the help they need in the moment. Help |
| output should be standardized to provide users with actionable guidance and a |
| clear path to find more information when needed. |
| |
| **Required elements** |
| |
| * Description - _A summary of the tool's function and purpose including key |
| information on usage._ |
| * Usage - _A clear outline of how to use the command, including syntax and |
| arguments, using < > to denote required elements and [ ] for optional ones._ |
| * Options - _A detailed breakdown of all options, their effects, and default |
| values_ |
| * Subcommands - _A list and summary of all available subcommands_ |
| |
| **Recommended elements** |
| |
| * Notes - _Important details and reminders_ |
| * Examples - _Illustrative examples of how to use the tool_ |
| * Error Codes - _A list of tool-specific errors and their meanings_ |
| |
| <br/> |
| |
| Caution: Avoid recursive help explanations. That is, do not repurpose a |
| command's name to explain what it does. |
| |
| <table > |
| <tr> |
| <td><code>doctor - Run common checks for the ffx tool and host environment</code> |
| </td> |
| <td><code>daemon - Interact with the ffx daemon</code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| ### Formatting help text |
| |
| The help text should adhere to a clear structure and style for optimal |
| readability, including consistent indentation and line wrapping at 80 |
| characters. The text should be written in clear, grammatically correct US |
| English and follow Fuchsia’s [documentation standards](/docs/contribute/docs/documentation-standards.md). |
| |
| <br/> |
| |
| ## Error messages |
| |
| Errors provide critical information to developers when things are not working as |
| expected. Error messages and Warnings are an opportunity to educate developers |
| with an accurate mental model of how a system or tool works, and its intended |
| use. Fuchsia error messages should help a reasonably technical user understand |
| and resolve an issue quickly and easily. |
| |
| These guidelines apply to errors created as part of the Fuchsia platform. Errors |
| created by a particular runtime or language outside of Fuchsia may not follow |
| these guidelines. |
| |
| |
| ### Writing errors |
| |
| * **State the problem** - Identify what went wrong, why it happened, and where |
| to fix it. |
| * **Help the user fix the problem** - Offer solutions that are clear, |
| reasonable, and actionable. Provide links to get additional help. |
| * **Write for humans** - Avoid jargon, keep the tone positive, and be concise |
| and consistent. |
| |
| ### Identify cause and suggest solutions |
| |
| Users should know exactly what went wrong, where, and why. The error message |
| should offer a solution, next steps, or explain how the specific error can be |
| corrected. |
| |
| <br/> |
| |
| <table > |
| <tr> |
| <td><code>Failed to save network with SsidEmptyError. Add SSID and retry.</code> |
| </td> |
| <td><code>Failed to save network</code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| ### Include shortlink |
| |
| Use a shortlink to redirect users to correct documentation and assist with |
| troubleshooting by further explaining the problem. Follow [these guidelines](/docs/contribute/docs/shortlinks/README.md) |
| to create shortlinks. |
| |
| <br/> |
| |
| <table > |
| <tr> |
| <td><code>Broken pipe (os error 32) fuchsia.dev/go/<keyword> </code> |
| <p> |
| (link to an error catalog to define os error 32) |
| </td> |
| <td><code>Broken pipe (os error 32) </code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| ### State requirements |
| |
| Indicate if specific constraints or pre-conditions were not met. Users should |
| understand if an error occurred because of input validation (e.g., file not |
| found), processing (e.g., syntax errors in the file), or other unexpected reasons |
| (e.g., file corrupt, cannot read from disk). |
| |
| <br/> |
| |
| <table > |
| <tr> |
| <td><code>manifest or product_bundle must be specified</code> |
| </td> |
| <td><code>NotFound</code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| ### Be specific |
| |
| If the error involves values that the user can modify (text, settings, command- |
| line parameters, etc.), then the error message should indicate the offending |
| values. This makes it easier to debug the issue. However, very long values |
| should only be disclosed progressively or truncated. |
| |
| <br/> |
| |
| <table > |
| <tr> |
| <td><code>Path provided is not a directory</code> |
| </td> |
| <td><code>InvalidArgs</code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| ### Use consistent terms and structure |
| |
| Logs data can help users learn more about how and why the error occurred. Use |
| canonical names, categories, and values, and include clear descriptions in |
| documentation so an error can be easily referenced. |
| |
| <br/> |
| |
| <table> |
| <tr> |
| <td><code>No default target value</code> |
| </td> |
| <td><code>NotFound</code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| ### Recommended: Create error code catalog |
| |
| Including a unique identifier or standardized error code in addition to the |
| message can help users identify the error easily and find more information in an |
| error index or error catalog. For example, error codes in FIDL are always |
| rendered with the prefix fi- followed by a four digit code, like fi-0123. |
| |
| * See example: [FIDL compiler error catalog](/docs/reference/fidl/language/errcat.md) |
| |
| <br/> |
| |
| <table > |
| <tr> |
| <td> |
| <code>fi-0046: Unknown library</code> |
| </td> |
| <td><code>Unknown library</code> |
| </td> |
| </tr> |
| <tr> |
| <td style="background-color: #d9ead3">Do |
| </td> |
| <td style="background-color: #f4cccc">Don’t |
| </td> |
| </tr> |
| </table> |
| |
| <br/> |
| |
| * * * |
| |
| <br/> |
| |
| ## Technical guidelines {#technical-guidelines} |
| |
| To deliver a consistent developer experience across Fuchsia, CLI tools should |
| use standard libraries, consistent configuration, common logging and error |
| handling, and continuous support for users. |
| |
| Tip: See Fuchsia's [CLI tool development rubric](#rubric) for a quick |
| checklist of considerations and guidelines. |
| |
| |
| ### Programming languages |
| |
| Fuchsia CLI tools may be written in C++, Rust, and Go. Tools must be compiled |
| and be independent of the runtime environment. Programming languages like Bash, |
| Python, Perl, and JavaScript are not supported. |
| |
| |
| ### Runtime link dependencies |
| |
| To make compiled tools easier to distribute and maintain, minimize runtime link |
| dependencies. Prefer to statically link dependencies instead. On Linux, it is |
| acceptable to runtime link against the glibc suite of libraries (libm, etc.); |
| other runtime link dependencies are not allowed. |
| |
| |
| ### Building from source |
| |
| Fuchsia tools should be built from the fuchsia.git source tree. Use the same |
| build and dependency structure as the code in the platform source tree. Do not |
| make a separate system to build tools. |
| |
| |
| ### Metrics |
| |
| Metrics are important to drive quality and business decisions. The type and |
| content of the metrics collected must be carefully chosen. |
| |
| > **Questions to answer with metrics** |
| > |
| > * Which OS are our users using? - to prioritize work for various platforms |
| > * Which tools are they using? - to prioritize investments, and to learn |
| > which workflows are currently being used so we can prioritize investments or |
| > identify weak spots |
| > * How often do they use a tool? - so we know how to prioritize investments, |
| > and to learn which workflows are currently being used so we can prioritize |
| > investments or identify weak spots |
| > * Do our tools crash in the wild? How often? - so we know how to prioritize |
| > maintenance of tools |
| > * How do they use a tool? - assuming that a tool can do one or more things, |
| > we'd like to learn how to prioritize investments in particular workflows of a |
| > tool |
| |
| Note: For internal Googlers, every tool must file a Privacy Design Document |
| (PDD) in order to collect usage metrics. All tools must go through the |
| Google-standard PDD review process to ensure they are compliant with Google's |
| practices and policies. Tools must get approval on which metrics are collected |
| before collection. |
| |
| |
| ## Configuration and environment |
| |
| Tools often need to know something about the environment and context in which |
| they are running. This section provides guidelines on how that information |
| should be gathered and/or stored. |
| |
| |
| ### Reading information |
| |
| Tools should not attempt to gather or read settings or state files directly from |
| the environment in which they are running. Information such as an attached |
| target's IP address, the out directory for build products, or a directory for |
| writing temporary files should be gathered from a platform-independent source. |
| Separating out the code that performs platform-specific work will allow tools to |
| remain portable between disparate platforms. |
| |
| Where practical, configuration information should be stored in a way familiar to |
| the user of the host machine (e.g., on Windows, use the registry). Tools should |
| gather information from SDK files or platform-specific tools that encapsulate |
| the work of reading from the Windows registry or Linux environment. |
| |
| Tools should be unbiased towards any build system or environment. Accessing a |
| common file such as a build input dependency file is allowed. |
| |
| |
| ### Writing information |
| |
| Tools should not modify configuration or environment settings, except when the |
| tool is clearly designed for the purpose of modifying an expected portion of the |
| environment. |
| |
| If modifying the environment outside of the tool's normal scope may help the |
| user, the tool may do so with the express permission of the user. |
| |
| |
| ### Tests |
| |
| Tools that are distributed in the SDK or included in the build system must |
| include tests that guarantee correct behavior. Include both unit tests and |
| integration tests with each tool. Tests will run in Fuchsia continuous |
| integration. |
| |
| Note: Tests for fx tools are preferred, but not required. |
| |
| |
| ### Documentation |
| |
| All Fuchsia tools require documentation on how to use the tool and a |
| troubleshooting guide. Standard `--help` output must include: |
| |
| * **Description:** A summary of the tool's function and purpose including key |
| information on usage. |
| * **Usage:** A clear outline of how to use the command, including syntax and |
| arguments, using <> to denote required elements and [ ] for optional ones. |
| * **Options:** A detailed breakdown of all options, their effects, and default |
| values |
| * **Subcommands:** A list and summary of all available subcommands |
| |
| More verbose usage examples and explanations should be documented in markdown on |
| fuchsia.dev. |
| |
| |
| ## User vs. programmatic interaction |
| |
| A tool may be run interactively by a human user or programmatically via a script |
| (or other tool). |
| |
| While each tool will default to interactive or non-interactive mode if it can |
| determine what is preferred, it must also accept explicit instruction to run in |
| a given mode (e.g., allow the user to execute the programmatic interface even if |
| the tool is running in an interactive shell). |
| |
| |
| ### Stdin |
| |
| For tools that are not normally interactive, avoid requesting user input (e.g., |
| readline or linenoise). Don't add an unexpected prompt to ask the user a |
| question. |
| |
| For interactive tools (e.g., zxdb) prompting the user for input is expected. |
| |
| |
| ### Stdout |
| |
| When sending output to the user on stdout, use proper spelling and grammar. |
| Avoid unusual abbreviations. If an unusual abbreviation or term is used, be sure |
| it has an entry in the [glossary](/docs/glossary/README.md). |
| |
| |
| ### Stderr |
| |
| Use stderr for reporting invalid operation (diagnostic output) i.e. when the |
| tool is misbehaving. If the tool's purpose is to report issues (like a linter, |
| where the tool is not failing) output those results to stdout instead of stderr. |
| |
| |
| ### Exit code |
| |
| Exit code 0 is always treated as "no error" and exit code 1 is always a "general |
| error." Don’t rely on specific non-zero values. Use machine output to return a |
| specific error code and message. [See FIDL error catalog for an example](/docs/reference/fidl/language/errcat.md). |
| |
| * For success, return an exit code of zero |
| * For failure, return a non-zero exit code |
| |
| Avoid producing unnecessary output on success, unless the output includes |
| specific, critical information for a user to complete the next step in a |
| workflow (e.g., a file path). Don't print "succeeded" unless the user is asking |
| for verbose output. |
| |
| |
| ### Logging |
| |
| Logging is distinct from normal output and is usually configured to be |
| redirected to a file, or should be written to stderr. The audience for |
| logging is typically the tool developer or a user trying to debug an issue. |
| |
| * Logging from multiple threads will not interlace words within a line. The |
| minimum unit of output is a full text line. |
| * Each line will be prefixed with an indication of the severity: `detail, |
| info, warning, error, fatal` |
| |
| |
| ### Automation |
| |
| Include a programmatic interface where reasonable to allow for automation. If |
| there is an existing protocol for that domain, try to follow suit (or have a |
| good reason not to). MachineWriter (`--machine`) can be used to support |
| structured output in JSON. |
| |
| |
| ## Style guidelines |
| |
| To promote a consistent developer experience across Fuchsia, CLI tools should |
| follow existing style guidelines for [programming languages](/docs/development/languages/README.md) |
| and [Fuchsia documentation](/docs/contribute/docs/documentation-style-guide.md). For |
| example, if the tool is included with Zircon and written in C++, use the style |
| guide for [C++ in Zircon](/docs/development/languages/c-cpp/cxx.md). Avoid creating |
| separate style guides for CLI tools. |
| |
| All CLI tools, output, and documentation should follow the guidelines set forth |
| in Fuchsia’s [Respectful Code](/docs/contribute/respectful_code.md) policy. [Read more |
| about documentation standards on Fuchsia.](/docs/contribute/docs/documentation-standards.md) |
| |
| |
| ### Case sensitivity in file paths |
| |
| Don't rely on case sensitivity in file paths. Different platforms handle |
| uppercase and lowercase differently. Windows is case insensitive and Linux is |
| case sensitive. Be explicit about specific filenames. Don’t expect that |
| `src/BUILD` and `src/build` are different files. |
| |
| |
| ### Color |
| |
| You may use ANSI color in the command line interface to make text easier to read |
| or to highlight important information. When using color, be sure to use colors |
| that are distinct for readers who may not be able to see a full range of color |
| (e.g., color-blindness) |
| |
| * Use standard [8/16 colors](https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797#8-16-colors), |
| which are easier for users to remap than [256 colors](https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797#256-colors) |
| * When possible, check whether the terminal supports color, and suppress |
| color output if not. |
| * Always allow the user to manually suppress color output, e.g., with a |
| --no-color flag and/or by setting the NO\_COLOR environment variable |
| ([no-color.org](http://no-color.org/)) |
| |
| Never rely solely on color to convey information. Only use color as an |
| enhancement. Seeing the color must not be required to correctly interpret |
| output. [Read more about accessibility on Fuchsia](/docs/concepts/accessibility/accessibility_framework.md). |
| |
| |
| ### ASCII art |
| |
| All Fuchsia tools should use standard output formatting with a consistent look |
| and feel. Don’t use ASCII art to format tables or otherwise enhance the output. |
| ASCII art can make your interface difficult to read and is not compatible with |
| screen readers for accessibility. |