Style Guide
Goals
User experience is at the core of Akamai CLI. This document contains our best practices and requirements to ensure a consistent, approachable, and above-all-else, usable experience when using Akamai CLI and its packages.
Overview
Akamai CLI provides a singular front-end to any number of individual packages, each of which is contained in a git repository. Each package contains one or more commands, that map 1:1 with an executable that is called by Akamai CLI. These executables can be written in any language, with full support for: Golang, Python, JavaScript, PHP and Ruby.
Naming Commands
Naming is a critical part of the usability of Akamai CLI, a short acronym-based name, while easy to type, may not clearly communicate what a command does, alternatively, a long verbose name can lead to typos and frustration.
- All executables must be named either
akamai-<command>
orakamai<Command>
(note: capital first letter on Command) - All executables must reside in either the repository root, or a
bin
sub-directory.
When choosing a command name, we recommend following the Principle of Least Astonishment (https://en.wikipedia.org/wiki/Principle_of_least_astonishment). This means that you should never use acronyms or abbreviations unless they are always used (e.g. HTTPS
or json
). However, if the name is overly long, say, more than 10–12 characters, or is tricky to type (such as “prioritization”), then adding an alias
is advised.
For example, visitor-prioritization
has the alias, vp
.
Arguments and Input
Most commands require input of some sort. There are three types of input
Flags and Arguments
Flags must always be prefixed with a double hyphen,
, and should separate words using a single hyphen. Examples are:--
--edgerc
--from-version
--output-file
Arguments are un-named positional values. These should be used sparingly, and typically only as a last variadic argument.
An example of this is the last argument for
which is any number of URLs to purge:akamai purge
$ akamai purge invalidate https://example.org/ https://example.org/about https://example.org/contact-us
Interactive input
A command may choose to run interactively, asking a user a series of questions to help them accomplish their task, however, to allow a user to fully script a command, you must provide an argument to provide the same inputs. You should also provide an environment variable in addition.
A prompt should be succinct, with a sane default when applicable. The default should be shown with the prompt like so:
Save output to [./data/foo]:
If the prompt has a set of possible answers, they should also be shown when possible, with the default shown in uppercase, or using bold text:
Are you sure? [Y/n]:
or:
What would you like to do? (S)ave/(v)iew/(d)iscard:[/prism:cli]
Overriding Confirmations
While it can be useful to require confirmations of destructive actions when running interactively, you must provide a --force flag that will explicitly override it.
STDIN
(i.e. redirected or piped input)
Akamai CLI will forward all STDIN
data to the underlying command, and should be used when streaming data in makes sense, for example a list of newline delimited URLs for akamai purge invalidate
.
Environment Variables
All environment variables should be uppercase and prefixed with AKAMAI_
, followed by the package name, and the flag name, e.g. Akamai CLI for Property Managers --clone
flag would become AKAMAI_PROPERTY_CLONE
. If you are providing environment variables for positional (unnamed) parameters, you should use an obvious name, for example AKAMAI_PROPERTY_HOSTNAME
.
Credentials
If the command is using the APIs you must support the standard .edgerc file. We recommend using one of Akamai's API signing libraries as they automatically support environment variables out of the box.
You must also support the following two flags:
Flag | Example | Default | |
---|---|---|---|
--edgerc | The full path to the .edgerc file | /etc/akamai/.edgerc | $HOME/.edgerc |
--section | a section of the .edgerc to use | my-app | the same as the command name (e.g. purge) |
Both of these flags should be optional
Other Credentials and Secure Input
If you need other credentials or secure configuration beyond the --edgerc
and --section
flags, you must not allow input as a flag value (e.g. --password=MYPASSWORD
). Instead values must be passed in using environment variables, or interactively.
You should implement both environment variables and interactive input. If a flag is used to indicate that you are passing in secure credentials, the interactive input should override any environment variables e.g.:
$ export AKAMAI_EXAMPLE_PASSWORD=foobar
$ akamai example --password
Enter your password: # this input will override the environment variable
NOTE: Prompts for secure data should have no output when input is entered
Output
All regular output should be sent to STDOUT
. All errors and other out-of-band (e.g. progress information) should be sent to STDERR
.
You should not output raw errors (e.g. uncaught exceptions, stack traces) if at all possible.
You are encouraged to use “spinners”, progress bars, or similar devices to indicate that progress is being made.
Status Messages
For reporting task status, we recommend using the following format:
Attempting to fetch command
..
..
..
[
<
STATUS
>
]
Installing
..
..
..
[
<
STATUS
>
]
Where <STATUS>
is one of OK
, FAIL
, or WARN
(see the colors section for more details).
If the status is not OK
, then a relevant error or warning should follow:
Attempting to fetch command
..
..
..
[OK]
Installing
..
..
..
[FAIL]
Unable to
locate
Node.js runtime
Enabling Scripting
Along with usability, another goal is to align with the UNIX philosophy of “Do one thing and do it well”. This means that actions should be built in a way that makes them composable, rather than all-encompassing.
With this in mind, you can imagine creating scripts that do something like:
$
HOST
=
example.org
$
akamai
cert
create
$HOST
|
akamai
property
add-cert
$HOST
&&
akamai
property
activate
$HOST
--network PROD
Note: the above is an example meant only for documentation purposes
JSON Output
You may choose to include a JSON output mode for your command that allows you to pipe the output to a file for further processing, or pipe it through a utility such as jq
.
If you do allow this, the flag --json
or environment variable AKAMAI_OUTPUT_JSON
should be used to enable this mode.
Colors
For Akamai CLI the use of color in output is a critical part of ensuring that output is easily readable.
There are several conventions that you should adhere to if you wish to ensure consistency within Akamai CLI:
- Headers should be yellow
- Success messages should be green
- Errors should be red
- Warnings should be cyan
NOTE: The colors listed above use the ANSI color names and may show differently on a users local terminal.
You are encouraged to use color to highlight relevant output appropriately, however you should try to keep it to no more than the colors above and two additional colors. You may additionally use bright variants, bold, and underline to further differentiate if necessary.
Status Messages
When displaying task statuses you should use the following colors:
- Success: Green
OK
- Success with warnings: Cyan
WARN
- Failure: Red
FAIL
Documentation
All packages must have both a README.md
and LICENSE
file.
Package documentation should try to follow the outline set out here:
Akamai CLI for <thing>
Brief introduction about the package
Install
Installation instructions
$
akamai
install
<
package
>
Usage
A usage example e.g.
$
akamai
<
command
>
[command flags]
<
action
>
[--important-flag]
[positional arguments]
Actions
A linked list of actions with brief descriptions (e.g. what would display in akamai <command> help
)
Action Name
Full documentation on each action including:
Flags
$
akamai
install
<
package
>
Usage
A usage example e.g.
--list Description
--of Description
--flags Description
Example
$
akamai
action
example
When writing documentation, you must use example.com
, example.org
, or example.net
for all hostnames (per IANA), and all shell command examples must use a $
prompt.