How to Enable Verbose Logging in IPATool: Command Line and Code Examples

Add the --verbose flag to any IPATool command to enable debug-level output, or set Verbose: true when programmatically creating a logger via log.NewLogger().

IPATool is a CLI utility for downloading and inspecting iOS app packages (IPA files) from the App Store. When troubleshooting download failures or analyzing API responses, you can enable verbose logging to expose detailed diagnostic information. This global setting switches the internal logger from Info to Debug level and is controlled through a persistent command-line flag and the pkg/log package.

Root Command Flag Implementation (cmd/root.go)

The entry point for verbose mode begins in the root command definition. IPATool registers a persistent boolean flag --verbose that defaults to false and applies to all subcommands.

In cmd/root.go, the flag is bound to a package-level variable:

cmd.PersistentFlags().BoolVar(&verbose, "verbose", false, "enables verbose logs")

Because this is a persistent flag, it is inherited by every subcommand (such as download, search, or purchase), allowing you to append --verbose to any operation without modifying individual command files.

Logger Initialization Chain (cmd/common.go)

Once the flag is parsed, its value propagates through the dependency injection chain. The newLogger helper function in cmd/common.go receives both the output format and the verbose boolean, forwarding them to the logging constructor:

func newLogger(format string, verbose bool) log.Logger {
    return log.NewLogger(log.Args{
        Format:  format,
        Verbose: verbose,  // Passes the CLI flag value
    })
}

This centralized initialization ensures that all commands receive a consistently configured logger instance that respects the user's verbosity preference.

Logger Internals (pkg/log/logger.go)

The core logging logic resides in pkg/log/logger.go, where the Logger interface implementation handles the verbose state. The constructor stores the flag in a verbose field and selects the appropriate zerolog level:

  • When verbose is true: the logger level is set to Debug
  • When verbose is false: the logger level remains at Info

The struct exposes a Verbose() method that returns a zerolog.Event only when verbose mode is enabled, allowing the rest of the codebase to emit debug messages without conditional checks:

func (l *logger) Verbose() *zerolog.Event {
    if l.verbose {
        return l.Logger.Debug()
    }
    return nil
}

Throughout IPATool's source, you will find calls like logger.Verbose().Msg("authenticating with Apple"). When verbose mode is off, these calls return nil and effectively become no-ops, preventing debug output from cluttering standard usage.

Practical Usage Examples

Command Line Usage

Append the global flag to any command to enable detailed output:


# Verbose download with debug logs

ipatool --verbose download com.example.app

# Verbose search

ipatool --verbose search "example app"

Programmatic Usage in Go

If you are importing IPATool as a library or writing extensions, manually enable verbose mode by setting the Verbose field in the arguments struct:

import (
    "os"
    "github.com/majd/ipatool/pkg/log"
)

func main() {
    logger := log.NewLogger(log.Args{
        Verbose: true,          // Enable debug level
        Writer:  os.Stdout,
    })
    
    // This emits a debug line only when verbose is true
    logger.Verbose().
        Str("bundle_id", "com.example.app").
        Msg("Starting download process")
}

Inside Command Implementations

When working within the existing command framework, access the pre-configured logger through the dependencies container:

// Inside a command implementation (e.g., cmd/download.go)
func runDownload(cmd *cobra.Command, args []string) error {
    // dependencies.Logger was created by newLogger(format, verbose)
    dependencies.Logger.Verbose().
        Str("app_id", args[0]).
        Msg("Resolving app metadata")
    
    // ... download logic continues
    return nil
}

Summary

  • Flag Definition: The --verbose flag is declared as a persistent boolean in cmd/root.go, making it available to all subcommands.
  • Propagation: The flag value flows through cmd/common.go via the newLogger() helper function.
  • Level Control: pkg/log/logger.go interprets the flag to set the zerolog level to Debug when enabled, or Info by default.
  • Safe Usage: The Verbose() method returns a proper event only when enabled, allowing debug logging statements to remain in production code without performance penalties.

Frequently Asked Questions

How do I enable verbose logging for a specific IPATool command?

Append the global --verbose flag to any command invocation. For example, ipatool download com.example.app --verbose or ipatool --verbose search "app name". Because the flag is persistent and defined at the root command level, it can appear before or after the subcommand name.

Does verbose logging affect all subcommands?

Yes. The flag is registered using PersistentFlags() in cmd/root.go, which means it is automatically inherited by every subcommand (download, search, purchase, etc.). You do not need to modify individual command files to support verbose output.

Can I enable verbose mode programmatically when using IPATool as a library?

Yes. When constructing a logger via log.NewLogger(), set Verbose: true in the log.Args struct. This configuration overrides the CLI default and forces the logger to emit debug-level messages regardless of command-line flags.

What logging library does IPATool use for verbose output?

IPATool uses zerolog for structured logging. The verbose mode works by returning l.Logger.Debug() from the Verbose() method when the flag is enabled, leveraging zerolog's level-based filtering to control output verbosity.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →