depman
is a Go library for managing external system-level dependencies in your applications. It ensures that all required external tools and applications are properly installed before your main application runs.
Unlike traditional package managers that handle code libraries, depman
focuses on system dependencies like Node.js, Python, or database servers that your application needs to function properly.
With a single YAML configuration file, depman
validates, installs, and verifies external dependencies across Windows, Linux, and macOS, providing a seamless bootstrapping experience.
- Cross-platform support for Windows, Linux, and macOS
- Semantic versioning to specify exact versions or version constraints
- Dependency discovery across standard system locations
- Installation verification to ensure dependencies are correctly installed
- Customizable installation commands for platform-specific needs
- Environment variable management to configure dependencies properly
To add depman
to your Go project:
go get github.com/devnadeemashraf/depman
Create an app-dependencies.yml
file in your project root:
version: "1.0"
name: "My Application"
description: "Dependencies for my application"
dependencies:
- name: "nodejs"
description: "JavaScript runtime"
version:
required: "16.15.1"
constraint: "^16.0.0"
platforms:
windows:
installer:
type: "msi"
url: "https://nodejs.org/dist/v16.15.1/node-v16.15.1-x64.msi"
commands:
install: ["msiexec", "/i", "{download_path}", "/quiet"]
verify: ["node", "--version"]
uninstall: ["msiexec", "/x", "{product_id}", "/quiet"]
linux:
installer:
type: "binary"
url: "https://nodejs.org/dist/v16.15.1/node-v16.15.1-linux-x64.tar.xz"
commands:
install: ["tar", "-xf", "{download_path}", "-C", "/usr/local/"]
verify: ["node", "--version"]
darwin:
installer:
type: "pkg"
url: "https://nodejs.org/dist/v16.15.1/node-v16.15.1.pkg"
commands:
install: ["installer", "-pkg", "{download_path}", "-target", "/"]
verify: ["node", "--version"]
Import and use depman
to ensure dependencies are installed at application startup:
package main
import (
"fmt"
"log"
"os"
"github.com/devnadeemashraf/depman/pkg/depman"
)
func main() {
// Initialize dependency manager
manager, err := depman.NewManager("")
if err != nil {
log.Fatalf("Failed to initialize dependency manager: %v", err)
}
// Check and install dependencies
results, err := manager.EnsureDependencies()
if err != nil {
log.Fatalf("Dependency error: %v", err)
}
// Check if all dependencies are satisfied
for name, status := range results {
if !status.Installed || !status.Compatible {
log.Fatalf("Dependency %s is not properly installed or incompatible", name)
}
}
// Continue with your application logic
fmt.Println("All dependencies are installed and verified!")
// ...
}
func NewManager(configPath string) (*Manager, error)
Creates a new dependency manager using the specified configuration file path. If configPath
is empty, it searches for the file in standard locations.
func (m *Manager) EnsureDependencies() (map[string]*DependencyStatus, error)
Checks and installs all dependencies if needed, returning their status.
func (m *Manager) CheckDependency(dep *Dependency) (*DependencyStatus, error)
Checks if a specific dependency is installed and compatible.
func (m *Manager) InstallDependency(dep *Dependency) error
Installs a specific dependency according to platform requirements.
The app-dependencies.yml
file defines all the dependencies your project needs:
version: "1.0" # Configuration file version
name: "Application Name" # Your application name
description: "Description" # Brief description
dependencies:
- name: "dependency-name" # Unique identifier for the dependency
description: "..." # What this dependency is used for
version:
required: "1.2.3" # Exact version required
constraint: "^1.2.0" # Semver constraint (flexible version range)
platforms:
windows: # Windows-specific configuration
installer:
type: "msi" # Installation type (msi, exe, zip, etc.)
url: "https://..." # Download URL
checksum: "sha256:..." # Verification checksum
commands:
install: ["...", "..."] # How to install the dependency
verify: ["...", "..."] # How to verify the installation
uninstall: ["...", "..."] # How to uninstall
linux:# Linux-specific configuration
# Similar structure as Windows
darwin:# macOS-specific configuration
# Similar structure as Windows
environment:
path: ["{install_dir}/bin"] # Paths to add to PATH
variables: # Environment variables to set
KEY: "value"
dependencies: [] # Other dependencies this one requires
package main
import (
"fmt"
"github.com/devnadeemashraf/depman/pkg/depman"
)
func main() {
// Create a new dependency manager
manager, _ := depman.NewManager("")
// Just check dependencies without installing
statuses, _ := manager.CheckAllDependencies()
// Print status report
for name, status := range statuses {
fmt.Printf("Dependency: %s\n", name)
fmt.Printf(" Installed: %v\n", status.Installed)
fmt.Printf(" Current Version: %s\n", status.CurrentVersion)
fmt.Printf(" Update Required: %s\n", status.RequiredUpdate)
fmt.Printf(" Compatible: %v\n", status.Compatible)
if status.Error != nil {
fmt.Printf(" Error: %v\n", status.Error)
}
fmt.Println()
}
}
// Use a custom path for the dependency configuration
manager, err := depman.NewManager("./config/dependencies.yml")
- Go 1.19 or higher
- Make (for using the provided Makefile)
- golangci-lint (for linting)
The project includes a Makefile with several useful commands:
make help # Show available commands
make build # Build the library
make test # Run tests
make test-verbose # Run tests with verbose output
make coverage # Generate test coverage report
make lint # Run linters
make clean # Clean up build artifacts
Note: You should have make installed on your system to use the Makefile.
depman/
├── internal/ # Private application packages
├── pkg/
│ └── depman/ # Public API packages
├── .vscode/ # VS Code settings
├── coverage/ # Test coverage reports
├── Makefile # Build automation
├── go.mod # Go modules definition
└── README.md # This file
Q: How is this different from package managers like NPM, Pip, or Go Modules?
A: depman
focuses on system-level dependencies (like Node.js, Python, or Git), not code libraries used within your application.
Q: Does depman handle permission issues for system-level installations?
A: depman
will attempt to install dependencies with the current user's permissions. For system-level installations that require elevated privileges, you may need to run your application with appropriate permissions.
Q: What happens if a dependency can't be installed?
A: depman
returns detailed error information that your application can use to provide appropriate feedback to users.
Q: Can I use this to bootstrap CI/CD environments?
A: Yes! depman
is perfect for ensuring CI/CD environments have the correct dependencies installed.
Contributions are welcome! Here's how you can contribute:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature
- Commit your changes:
git commit -m 'Add amazing feature'
- Push to the branch:
git push origin feature/amazing-feature
- Open a Pull Request
Please read CONTRIBUTING.md for detailed contribution guidelines.
This project is licensed under the MIT License - see the LICENSE file for details.
- Masterminds/semver for semantic versioning support
- yaml.v3 for YAML parsing
Built with ❤️ by Nadeem Ashraf