Skip to main content

One more dot file manager but an interesting and easy to use one.

Project description

dotman

A modern, Pythonic dotfile manager that uses symbolic links and Jinja2 templates to manage your configuration files across multiple machines.

Features

  • Simple Configuration - YAML-based configuration with package organization
  • Symlink Management - Create, remove, and track symlinks safely with backup support
  • Auto-Template Detection - Files ending with .j2 are automatically detected as templates
  • Template Change Detection - Status command shows "Modified" or "Synced" for template files with whitespace normalization
  • File Absorption - Automatically absorb new files from target directories into your dotfiles repository
  • Smart Template Handling - Absorb skips template outputs to avoid duplicates
  • Strict Dependency Enforcement - Dependencies must be defined in config.yaml and enabled in local.yaml with clear error messages
  • Circular Dependency Detection - Detects and prevents circular dependencies between packages with clear error messages
  • Machine-Specific Settings - Override configurations per machine with local.yaml
  • Dry-Run Mode - Preview changes before applying them
  • Rich Output - Beautiful terminal output with status tables and color-coded feedback
  • Hooks System - Execute shell commands before and after deployments with template support
  • Deployment History - Track all deployments with unique IDs for auditing
  • Rollback Support - Restore previous deployments from history
  • Watch Mode - Automatically deploy changes when files are modified
  • Remote Repository Support - Clone, push, and pull from GitHub/GitLab
  • Template Caching - Cache compiled templates for faster deployments
  • Package Include System - Include and compose configuration files

Quick Start

Installation

# Official method - install with pipx
pipx install dotman

# From source
git clone https://github.com/nimitbhardwaj/dotman
cd dotman
pipx install .

Basic Usage

# Initialize in your dotfiles repository
cd ~/.dotfiles
dotman init

# Edit .dotman/config.yaml with your configurations
dotman deploy --dry-run  # Preview changes
dotman deploy --force    # Apply changes

# Check status of deployed dotfiles
dotman status

# List all configured packages
dotman list

# Absorb new files from target directories
dotman absorb           # Absorb all unmanaged files
dotman absorb nvim      # Absorb only for nvim package

Configuration

Global Configuration (.dotman/config.yaml)

Define packages and file mappings:

settings:
  backup_dir: ".dotman/backups"

variables:
  editor: "nvim"
  theme: "dracula"

packages:
  bash:
    files:
      - source: "bash/bashrc"
        target: "~/.bashrc"
      - source: "bash/bash_profile"
        target: "~/.bash_profile"

  nvim:
    depends: []
    files:
      - source: "nvim"
        target: "~/.config/nvim"
    variables:
      theme: "dracula"

Local Configuration (.dotman/local.yaml)

Machine-specific overrides:

packages:
  - bash
  - nvim

variables:
  theme: "onedark"

file_overrides:
  bash_profile:
    target: "~/.bashrc"

File Mapping Options

packages:
  myconfig:
    files:
      # Simple symlink
      - source: "config.conf"
        target: "~/.config.conf"

      # Template file (rendered with variables, detected by .j2 extension)
      - source: "template.conf.j2"
        target: "~/.rendered.conf"

      # Directory (recursively symlinks all files)
      - source: "mydir"
        target: "~/.mydir"

Commands

Command Description
dotman init Initialize dotman in current directory
dotman deploy [packages] Deploy dotfiles (create symlinks)
dotman undeploy [packages] Remove deployed symlinks
dotman status [packages] Show status of deployed dotfiles
dotman list List all available packages
dotman absorb [packages] Absorb unmanaged files from target directories
dotman watch Watch for file changes and deploy automatically
dotman clone <repo> Clone a remote dotfiles repository
dotman push [remote] Push changes to remote repository
dotman pull [remote] Pull changes from remote repository
dotman history [--limit] Show deployment history
dotman rollback [id] Rollback a deployment by ID
dotman repo add <name> Register current directory as a repository
dotman repo list List all registered repositories
dotman doctor [packages] Check required executables are present

Options

  • --config-dir, -c - Override the config directory (default: .dotman/ in current directory or DOTMAN_CONFIG_DIR env var)
  • --dry-run, -n - Preview changes without applying them
  • --force, -f - Overwrite existing files (with backup)
  • Specific packages can be passed to commands for targeted operations

File Absorption

Dotman can absorb new files from your target directories into your dotfiles repository:

# Absorb all unmanaged files from configured targets
dotman absorb

# Absorb only for specific packages
dotman absorb nvim bash

How Absorption Works

When you run dotman absorb, dotman:

  1. Scans configured target directories for new/unmanaged files
  2. Copies each new file to the corresponding source location in your dotfiles repository
  3. Creates a symlink from the source to the target (replacing the original file)
  4. Preserves the directory structure relative to the target

Smart Skipping

Absorption automatically skips:

  • Symlinks - Already managed files
  • Template outputs - Files rendered from .j2 templates (avoids duplicates)
  • Existing files - Files already present in the package source
  • Ignored patterns - Files matching absorb_ignore patterns

Ignore Patterns

You can specify patterns to ignore during absorption using absorb_ignore:

packages:
  nvim:
    files:
      - source: "nvim"
        target: "~/.config/nvim"
        absorb_ignore:
          - "node_modules" # Ignore any path containing node_modules
          - "*.log" # Ignore log files
          - ".git/**" # Ignore git directories

The absorb_ignore field accepts a list of regex patterns that are matched against the full file path. If a file matches any pattern, it will be skipped during absorption.

Doctor Configuration

Dotman can check if required executables are present on your system before deploying packages. This helps identify missing dependencies early, preventing partial deployments and confusing errors.

Basic Configuration

Define executable requirements in your package configuration:

packages:
  nvim:
    depends: []
    files:
      - source: "nvim"
        target: "~/.config/nvim"
    doctor:
      executables:
        - name: nvim
          severity: error
        - name: git
          severity: error

Severity Levels

The severity field determines how missing executables are treated:

  • error: The executable is required for the package to work. If missing, dotman deploy may fail or produce unexpected results. The doctor command returns exit code 1.
  • warning: The executable is optional or only needed for certain features. If missing, the package may still work with reduced functionality. The doctor command returns exit code 0 but shows a warning.

Example Configuration

packages:
  nvim-base:
    description: "Neovim configuration with LazyVim for base"
    files:
      - source: "nvim/base/"
        target: "~/.config/nvim"
    doctor:
      executables:
        - name: nvim
          severity: error
        - name: git
          severity: error

  opencode:
    description: "OpenCode AI assistant configuration"
    files:
      - source: "opencode"
        target: "~/.config/opencode"
    doctor:
      executables:
        - name: node
          severity: warning
        - name: bun
          severity: warning

  zsh:
    description: "Zsh Config for the system"
    files:
      - source: "zsh/.zshrc"
        target: "~/.zshrc"
    doctor:
      executables:
        - name: zsh
          severity: error

Using the Doctor Command

# Check all enabled packages
dotman doctor

# Check specific packages
dotman doctor nvim zsh

# Check with custom config directory
dotman doctor --config-dir ~/.dotfiles

Example Output

$ dotman doctor

╭───────────────────────────────────────────────────────────────────────────╮
│ Doctor Check Results                                                      │
├───────────────────────────────────────────────────────────────────────────┤
│ Package: nvim-base                                                        │
├───────────────────────────────────────────────────────────────────────────┤
│ Executable   Status    Severity    Path                                  │
│ nvim         ✓ Found   error       /usr/bin/nvim                          │
│ git          ✓ Found   error       /usr/bin/git                           │
├───────────────────────────────────────────────────────────────────────────┤
│ Package: opencode                                                         │
├───────────────────────────────────────────────────────────────────────────┤
│ Executable   Status    Severity    Path                                  │
│ node         ✓ Found   warning     /usr/bin/node                          │
│ bun          ✗ Missing warning     Not in PATH                           │
├───────────────────────────────────────────────────────────────────────────┤
│ Package: zsh                                                              │
├───────────────────────────────────────────────────────────────────────────┤
│ Executable   Status    Severity    Path                                  │
│ zsh          ✓ Found   error       /usr/bin/zsh                           │
╰───────────────────────────────────────────────────────────────────────────╯

Summary: 0 errors, 1 warning, 4 passed

Exit Codes

  • Exit code 0: No error-severity executables are missing (warnings are acceptable)
  • Exit code 1: One or more error-severity executables are missing

How It Works

  1. The doctor command loads your configuration and resolves the package dependency tree
  2. For each package with doctor.executables defined, it checks if each executable exists in your system's PATH
  3. Executable lookup uses shutil.which() for cross-platform compatibility (Linux, macOS, Windows)
  4. Results are displayed in a formatted table grouped by package
  5. A summary shows totals for errors, warnings, and passed checks

Packages Without Doctor Config

Packages without a doctor configuration are still shown in the output with "No executable requirements":

$ dotman doctor

╭───────────────────────────────────────────────────────────────────────────╮
│ Doctor Check Results                                                      │
├───────────────────────────────────────────────────────────────────────────┤
│ Package: simple-config                                                    │
├───────────────────────────────────────────────────────────────────────────┤
│ Executable   Status    Severity    Path                                  │
│              No executable requirements                                   │
╰───────────────────────────────────────────────────────────────────────────╯

Summary: 0 errors, 0 warnings, 0 passed

Best Practices

  • Set severity: error for executables that are strictly required (e.g., nvim, git)
  • Set severity: warning for executables that are optional or only needed for specific features
  • Run dotman doctor before dotman deploy to catch missing dependencies early
  • Use --dry-run with deploy to preview changes after fixing any doctor issues

Overlapping Targets

If multiple packages target the same directory, the first package (alphabetically) processes the files, and subsequent packages are skipped with a warning. This ensures predictable behavior:

packages:
  nvim-base:
    files:
      - source: "nvim/base"
        target: "~/.config/nvim"

  nvim-home:
    files:
      - source: "nvim/home"
        target: "~/.config/nvim" # Will be skipped, nvim-base processes first

Dry Run Mode

Use --dry-run to preview what would be absorbed without making changes:

dotman absorb --dry-run

When a new file appears in a target directory (e.g., ~/.config/nvim/new_setting.json), dotman will:

  1. Move the file to the corresponding source directory in your dotfiles repository
  2. Replace the original file with a symlink pointing to the source

Absorb Ignore Patterns

You can specify patterns to ignore during absorption using regex:

packages:
  nvim:
    files:
      - source: "nvim"
        target: "~/.config/nvim"
        absorb_ignore:
          - "node_modules" # Ignore any path containing node_modules
          - "\\.git" # Ignore any path containing .git
          - ".*\\.log" # Ignore any .log files

Smart Template Handling

When absorbing files, dotman automatically skips files that are template outputs. If a .j2 template exists in your source (e.g., config.conf.j2), the rendered file in the target (e.g., config.conf) will not be absorbed to avoid duplicates.

Hooks System

Dotman supports executing shell commands before and after deployments via a hooks system.

Hook Types

  • pre_deploy - Commands executed before deploying a package's files
  • post_deploy - Commands executed after deploying a package's files

Configuration

Define hooks in your package configuration:

packages:
  nvim:
    depends: []
    files:
      - source: "nvim"
        target: "~/.config/nvim"
    hooks:
      pre_deploy:
        - "echo 'Starting neovim deployment'"
        - "mkdir -p ~/.config/nvim"
      post_deploy:
        - "echo 'Neovim deployment complete'"
        - "nvim --headless -c 'PlugInstall --sync' -c 'qall'"

Template Variables in Hooks

Hook commands support Jinja2 template rendering with the following special variables:

  • {{package_name}} - Name of the current package
  • {{dotfiles_dir}} - Path to your dotfiles repository
  • {{target_dir}} - Path to the target directory for the package
  • {{variable_name}} - Any variables defined in your configuration

Hook Examples

Using package variables:

packages:
  nvim:
    variables:
      theme: "dracula"
    hooks:
      post_deploy:
        - "echo 'Theme set to {{theme}}'"

Conditional execution with Jinja2:

packages:
  nvim:
    variables:
      debug: true
    hooks:
      pre_deploy:
        - "{% if debug %}echo 'Debug mode enabled'{% endif %}"

Executing in target directory:

packages:
  myconfig:
    files:
      - source: "config"
        target: "~/.myconfig"
    hooks:
      post_deploy:
        - "{{dotfiles_dir}}/scripts/reload-config.sh"

Hook Execution Behavior

  • Hooks run in the order they are defined
  • If a pre_deploy hook fails, deployment is aborted
  • post_deploy hooks run even if file deployment has issues
  • Commands are executed via shell, supporting pipes, redirects, and shell features
  • Failed hooks raise a HookExecutionError with exit code and output details

Dry Run and Hooks

When running with --dry-run, hooks are not executed (only displayed in the execution plan).

Dependency Management

Define dependencies between packages to ensure correct deployment order.

Basic Dependencies

packages:
  base:
    files:
      - source: "base/files"
        target: "~/.config/base"

  nvim:
    depends: ["base"]
    files:
      - source: "nvim"
        target: "~/.config/nvim"

When deploying nvim, dotman will automatically deploy base first.

Dependency Requirements

  • All dependencies must be defined in config.yaml
  • All dependencies must be enabled in local.yaml
  • Dependencies are deployed in topological order (dependencies before dependents)

Circular Dependency Detection

Dotman automatically detects circular dependencies between packages and prevents deployment with a clear error message.

Example circular dependency configuration (this will fail):

packages:
  a:
    depends: ["b"]
    files:
      - source: "a"
        target: "~/.a"

  b:
    depends: ["a"]
    files:
      - source: "b"
        target: "~/.b"

When you try to deploy, you'll see:

Dependency error: Circular dependency detected: a -> b -> a

To fix, remove one of the dependency relationships.

Deployment History

Dotman tracks all deployments in .dotman/history.yaml with unique deployment IDs.

Viewing History

# View last 10 deployments (default)
dotman history

# View last 5 deployments
dotman history --limit 5

The history shows:

  • ID - Unique deployment identifier (use for rollback)
  • Timestamp - When the deployment occurred
  • Packages - Which packages were deployed
  • Files - Number of files processed
  • Type - "Live" or "Dry Run"

Deployment IDs

Each deployment gets a unique 8-character ID (UUID prefix) that you can use for rollback:

dotman history
# Example output:
# ID          Timestamp           Packages    Files    Type
# a1b2c3d4    2024-01-15 10:30    nvim, bash  15       Live
# e5f6g7h8    2024-01-14 09:15    vim         8        Live

Rollback

Undo a previous deployment by restoring files from backups.

Basic Rollback

# Rollback the most recent deployment
dotman rollback

# Rollback a specific deployment by ID
dotman rollback a1b2c3d4

# Preview rollback without making changes
dotman rollback --dry-run

What Rollback Does

  1. Removes symlinks created during the deployment
  2. Restores original files from backups (if available)
  3. Removes rendered template files
  4. Removes the deployment from history

Rollback Summary

After rollback, you'll see a summary:

Rollback summary:
  Processed: 15
  Skipped: 2
  Failed: 0
  • Processed - Files successfully removed/restored
  • Skipped - Files already removed (not present)
  • Failed - Files that couldn't be restored

Rollback Limitations

  • Cannot rollback dry-run deployments (no changes were made)
  • Backup files are cleaned up after successful restoration
  • Rollback only affects files from the specified deployment
  • Files created after the deployment will not be affected

Example Workflow

# Deploy some packages
dotman deploy nvim vim

# Check history to get the deployment ID
dotman history
# ID: x9y8z7w6

# Oops, something went wrong!
# Rollback to restore previous state
dotman rollback x9y8z7w6

Watch Mode

Automatically deploy dotfiles when source files are modified.

# Start watching for changes
dotman watch

# Watch will:
# - Monitor your dotfiles repository for changes
# - Deploy modified files automatically
# - Use platform-specific file system watchers (inotify on Linux, kqueue on macOS)
# - Debounce rapid changes to avoid excessive deployments

How Watch Mode Works

  1. Watches all configured package directories recursively
  2. Detects file creation, modification, deletion, and movement
  3. Waits for a quiet period (debounce) before deploying
  4. Skips ACCESSED events to avoid unnecessary deployments
  5. Press Ctrl+C to stop watching

Platform Support

  • Linux: Uses inotify for efficient kernel-level file system events
  • macOS/BSD: Uses kqueue for optimal performance
  • Fallback: Polling-based watcher if native APIs are unavailable

Remote Repository Support

Clone, push, and pull dotfiles from GitHub, GitLab, or any Git remote.

Cloning a Repository

# Clone using GitHub shorthand
dotman clone user/dotfiles

# Clone using full URL
dotman clone https://github.com/user/dotfiles.git

# Clone a specific branch
dotman clone user/dotfiles --branch develop

# Clone and initialize dotman
dotman clone user/dotfiles --init

# Shallow clone (faster, less history)
dotman clone user/dotfiles --shallow

Pushing Changes

# Push to default remote (origin)
dotman push

# Push to a specific remote
dotman push origin

# Push a specific branch
dotman push origin main

# Push and set upstream tracking
dotman push --set-upstream origin develop

Pulling Changes

# Pull from default remote (origin)
dotman pull

# Pull from a specific remote
dotman pull origin

# Pull a specific branch
dotman pull origin main

URL Formats Supported

  • user/repo - GitHub shorthand
  • github:user/repo - Explicit GitHub prefix
  • gitlab:user/repo - GitLab prefix
  • Full HTTPS URLs
  • SSH URLs (for push operations)

Template Caching

Dotman caches compiled Jinja2 templates for faster repeated deployments.

How Caching Works

  1. First render: Template is compiled and cached
  2. Subsequent renders: Cached version is used if source and variables haven't changed
  3. Cache invalidation: Automatically invalidated when:
    • Source file modification time changes
    • Template variables change
    • Cache is explicitly cleared

Cache Management

# Templates are automatically cached during deployment
# No manual management required

# Cache is invalidated when:
# - Source file is modified
# - Variables change
# - dotman deploy --force is used

Performance Benefits

  • Faster repeated deployments (skips template rendering)
  • Reduced CPU usage for large template sets
  • Smart detection of unchanged templates

Package Include System

Compose configurations from multiple YAML files with the include system.

Basic Includes

Include additional YAML files in your configuration:

# config.yaml
includes:
  - "../shared/base.yaml"
  - "../os-specific/linux.yaml"

packages:
  myconfig:
    depends: []
    files:
      - source: "myconfig"
        target: "~/.myconfig"

Circular Include Detection

Dotman automatically detects circular references in includes:

# a.yaml
includes:
  - "b.yaml"

# b.yaml
includes:
  - "a.yaml"

This will produce an error:

CircularIncludeError: Circular reference detected: a.yaml -> b.yaml -> a.yaml

Include Resolution

  • Includes are resolved relative to the including file
  • Nested includes are fully supported
  • Each file is only processed once (prevents duplicate processing)
  • Variables from included files are merged with precedence rules

Multiple Repository Management

Register and manage multiple dotfiles repositories.

Registering a Repository

# Register current directory as a named repository
dotman repo add work

# Register with a description
dotman repo add personal "My personal dotfiles"

# With remote URL detection
dotman repo add home
# Automatically detects if it's a git repo with remote

Managing Repositories

# List all registered repositories
dotman repo list

# Show repository details
dotman repo show
dotman repo show work

# Set default repository
dotman repo default work

# Unregister a repository
dotman repo remove work

Using Multiple Repositories

# Use a non-default repository
dotman --repo work deploy
dotman --repo personal status

# Each repository has its own config.yaml and history

Architecture

dotman/
├── src/
│   └── dotman/              # Python package
│       ├── __init__.py
│       ├── main.py             # Entry point
│       ├── cli.py              # Typer CLI commands
│       ├── config.py           # Configuration loading and validation
│       ├── link_manager.py     # Symlink creation and management
│       ├── template_engine.py  # Jinja2 template rendering with caching
│       ├── hook_executor.py    # Hook execution for shell commands
│       ├── history.py          # Deployment history tracking
│       ├── exceptions.py       # Custom exceptions
│       ├── watcher.py          # File system watcher (inotify/kqueue/polling)
│       ├── remote.py           # Remote repository management
│       └── repository.py       # Multi-repository management
├── tests/                      # Test suite
│   ├── __init__.py
│   ├── test_config.py
│   ├── test_link_manager.py
│   ├── test_template_engine.py
│   ├── test_exceptions.py
│   ├── test_hooks.py
│   ├── test_cli_deploy.py
│   ├── test_cli_status.py
│   └── ...
├── pyproject.toml              # Project configuration
├── README.md                   # This file
├── AGENTS.md                   # Guidelines for AI agents
└── TODO.md                     # Development roadmap

Safety Features

  • Automatic Backups - Existing files are backed up before overwriting
  • Dry-Run Mode - Preview all operations before execution
  • Status Checking - Detects broken, missing, and conflicting symlinks
  • Confirmation Prompts - Destructive operations can require confirmation
  • Deployment History - Track all changes with unique IDs
  • Rollback Support - Restore previous deployments from history

Error Handling

Dotman uses a hierarchical exception system for clear and actionable error messages. All custom exceptions inherit from DotmanError.

Exception Hierarchy

Exception Description
DotmanError Base exception for all dotman errors
ConfigError Configuration-related errors
├─ ConfigNotFoundError Configuration file not found
├─ ConfigParseError Error parsing configuration file
├─ ConfigIncludeError Error including configuration file
└─ CircularIncludeError Circular reference in includes
LinkError Symlink-related errors
├─ LinkExistsError Target already exists
└─ LinkTargetMissingError Source file missing
TemplateError Template-related errors
└─ TemplateRenderError Error rendering template
PackageError Package-related errors
├─ PackageNotFoundError Package not in config
└─ DependencyError Dependency resolution errors
├─ MissingDependencyError Required dependency missing
└─ CircularDependencyError Circular dependency detected
HookError Hook-related errors
└─ HookExecutionError Error executing hook
HistoryError History-related errors
RollbackError Rollback-related errors
RemoteError Remote repository errors
├─ RemoteCloneError Error cloning repository
├─ RemoteFetchError Error fetching from remote
├─ RemoteNotFoundError Repository not found
├─ RemoteAuthenticationError Authentication failed
└─ RemotePushError Error pushing to remote
WatcherError File watcher errors
├─ WatcherBackendError Watcher backend error
└─ WatcherInitializationError Watcher init failed
RepositoryError Repository management errors
├─ RepositoryNotFoundError Repository not in registry
├─ RepositoryAlreadyExistsError Repository already exists
├─ RepositoryPathError Invalid repository path
└─ NothingToCommitError No changes to commit

Catching Exceptions

All dotman exceptions can be caught as DotmanError:

from dotman.exceptions import DotmanError

try:
    dotman.deploy()
except DotmanError as e:
    print(f"Error: {e}")

Error Messages

Exception messages are designed to be user-friendly and actionable:

ConfigNotFoundError: Configuration file not found: /path/to/config.yaml
CircularDependencyError: Circular dependency detected: a -> b -> a
NothingToCommitError: No changes to commit in repository 'dotfiles'

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Write tests for your changes
  4. Ensure all tests pass
  5. Submit a pull request

License

MIT License - see LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dotman_cli-0.3.0.tar.gz (53.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dotman_cli-0.3.0-py3-none-any.whl (57.7 kB view details)

Uploaded Python 3

File details

Details for the file dotman_cli-0.3.0.tar.gz.

File metadata

  • Download URL: dotman_cli-0.3.0.tar.gz
  • Upload date:
  • Size: 53.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for dotman_cli-0.3.0.tar.gz
Algorithm Hash digest
SHA256 37abfbf9e05d2a724b277b76731de27b663ac264f0dbcfc839bace81d9c5b8d1
MD5 79ede2c57bf472f6184b08f76f4a3375
BLAKE2b-256 a09c5f1e9d44cba590460f2bc2354b568b6d29b476e0ba3788201dadabe6bc58

See more details on using hashes here.

Provenance

The following attestation bundles were made for dotman_cli-0.3.0.tar.gz:

Publisher: release.yml on nimitbhardwaj/dotman-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dotman_cli-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: dotman_cli-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 57.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for dotman_cli-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a9d54882deb13ff0e7b3dba5b7f249b51c34232e93ffe3bfacd41724a8ef55dd
MD5 7d9d374fd5bbcea4e4bcdba102cb6e77
BLAKE2b-256 9b2d170c6b31f5b2a387fc9f0d222b69a689a82e667b116fdfde6e2c6c626b40

See more details on using hashes here.

Provenance

The following attestation bundles were made for dotman_cli-0.3.0-py3-none-any.whl:

Publisher: release.yml on nimitbhardwaj/dotman-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page