The repo: https://github.com/robzolkos/fizzy-cli
The fizzy-cli application uses the Thor gem to create a structured and modular command-line interface. Here's an explanation of how the commands are created and used, based on the analysis of the codebase.
- The Core Framework: Thor
The application is built on top of Thor, a powerful toolkit for building CLIs in Ruby. Thor provides a simple way to define commands, options, and subcommands, and it automatically generates help text.
The main entry point is the Fizzy::CLI class in lib/fizzy/cli.rb. This class inherits from Thor and is responsible for setting up global options and registering the main command groups.
1 # lib/fizzy/cli.rb
2 # frozen_string_literal: true
3
4 require_relative 'commands/auth'
5 # ... other requires
6
7 module Fizzy
8 class CLI < Thor
9 # ...
10 end
11 end- The Three-Tiered Command Structure
The application has a well-organized three-tiered structure for managing commands:
- Tier 1: The Main CLI (
lib/fizzy/cli.rb) This is the top-level router. It defines global options that can be used with any command (e.g., --token) and registers the available command "groups" (like board, card, etc.) using Thor's subcommand method.
1 # lib/fizzy/cli.rb
2 module Fizzy
3 class CLI < Thor
4 # ...
5 desc "board SUBCOMMAND", "Manage boards"
6 subcommand "board", Commands::Board
7 # ...
8 end
9 end- Tier 2: The Base Command (
lib/fizzy/commands/base.rb) This is a crucial abstract base class that all command groups inherit from. It provides essential shared functionality, preventing code duplication and ensuring a consistent experience across all commands. Its key responsibilities include:- API Client Initialization: It provides a client method that all subcommands can use to make API calls.
- Configuration Access: It offers a config method to access global configuration settings.
- Standardized Output: It includes output and output_error methods to ensure that all commands return results in a consistent JSON format.
1 # lib/fizzy/commands/base.rb
2 module Fizzy
3 module Commands
4 class Base < Thor
5 # ...
6 private
7
8 def client
9 # ... initializes and returns an API client
10 end
11
12 def config
13 # ... returns the configuration
14 end
15
16
17
18 def output(data)
19 # ... prints data as JSON
20 end
21 # ...
22 end
23 end
24 end-
Tier 3: The Command Groups (
lib/fizzy/commands/*.rb) Each file in the lib/fizzy/commands/ directory defines a class for a specific command group (e.g., Fizzy::Commands::Board). These classes inherit from Fizzy::Commands::Base and define the actual subcommands.Within each class, public methods map directly to subcommands. For example, the list method in the Fizzy::Commands::Board class becomes the fizzy board list command. Thor's desc method is used to provide a description for each subcommand, which is shown in the help text.
1 # lib/fizzy/commands/board.rb
2 module Fizzy
3 module Commands
4 class Board < Base
5 desc "list", "List all boards"
6 def list
7 response = client.get("boards")
8 output(response)
9 end
10
11 # ... other subcommands like show, create, etc.
12 end
13 end
14 endHow to Add a New Command
Adding a new command group (e.g., for managing "projects") is straightforward:
-
Create the Command File: Create a new file, lib/fizzy/commands/project.rb.
-
Define the Class: Inside the new file, define the class and inherit from the base class:
1 # lib/fizzy/commands/project.rb
2 module Fizzy
3 module Commands
4 class Project < Base
5 desc "list", "List all projects"
6 def list
7 response = client.get("projects")
8 output(response)
9 end
10
11 # Add other subcommands here...
12 end
13 end
14 end- Load the File: In lib/fizzy.rb, add the following line to ensure the new command file is loaded:
1 # lib/fizzy.rb 2 require_relative "fizzy/commands/project"
- Register the Command: In lib/fizzy/cli.rb, register the new command group so that Thor knows about it:
1 # lib/fizzy/cli.rb
2 module Fizzy
3 class CLI < Thor
4 # ...
5 desc "project SUBCOMMAND", "Manage projects"
6 subcommand "project", Commands::Project
7 # ...
8 end
9 endBy following this pattern, the fizzy-cli application can be easily extended with new commands while maintaining a clean and organized codebase.