devflow

package module
v0.0.21 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 24, 2025 License: MIT Imports: 13 Imported by: 0

README

DevFlow

Project Badges

Complete Go development automation: project init, testing, versioning, updates, and backups. Single-line output optimized for AI agents and terminals.

Commands

  • gonew - Initialize new Go projects
  • gotest - Run tests, vet, race detection, coverage and badges
  • push - Git add, commit, tag, and push
  • gopush - Complete workflow: test + push + update dependents
  • devbackup - Configure and execute automated backups
  • badges - Generate SVG badges for README (test status, coverage, etc.)

Installation

go install github.com/tinywasm/devflow/cmd/gonew@latest
go install github.com/tinywasm/devflow/cmd/gotest@latest
go install github.com/tinywasm/devflow/cmd/push@latest
go install github.com/tinywasm/devflow/cmd/gopush@latest
go install github.com/tinywasm/devflow/cmd/devbackup@latest
go install github.com/tinywasm/devflow/cmd/badges@latest

Quick Start

# Test your project
gotest

# Create new project with specific owner
gonew myapp "My application" -owner=cdvelop

# Push changes 
push "fix: bug correction"

# Test + push + update dependents + backup
gopush "feat: new feature"

# Generate badges
badges

Library Usage

import "github.com/tinywasm/devflow"

// Git workflow
git := devflow.NewGit()
summary, _ := git.Push("commit message", "v1.0.0")

// Go project workflow
goHandler := devflow.NewGo(git)
summary, _ := goHandler.Push("commit message", "", false, false, "..")

// Optional: Enable logging for debugging
git.SetLog(log.Println)
goHandler.SetLog(log.Println)

Features

  • Zero config - Auto-detects tests, project structure, WASM environments
  • Minimal output - Single-line summaries for terminals and LLMs
  • Smart versioning - Auto-increments tags, skips duplicates
  • Multi-account - Switch GitHub orgs easily (cdvelop, veltylabs, tinywasm)
  • Dependency updates - Auto-updates dependent modules in workspace
  • Full testing - Combines vet, tests, race detection, coverage

License

MIT

Documentation

Index

Constants

View Source
const (
	ColorRed    = "\033[0;31m"
	ColorGreen  = "\033[0;32m"
	ColorYellow = "\033[0;33m"
	ColorCyan   = "\033[0;36m"
	ColorNone   = "\033[0m"
)

Variables

This section is empty.

Functions

func GenerateGitignore added in v0.0.13

func GenerateGitignore(targetDir string) error

GenerateGitignore generates .gitignore for Go

func GenerateHandlerFile added in v0.0.13

func GenerateHandlerFile(repoName, targetDir string) error

GenerateHandlerFile generates the main handler file

func GenerateLicense added in v0.0.13

func GenerateLicense(ownerName, targetDir string) error

GenerateLicense generates LICENSE (MIT)

func GenerateREADME added in v0.0.13

func GenerateREADME(repoName, description, targetDir string) error

GenerateREADME generates README.md

func PrintError added in v0.0.13

func PrintError(msg string)

PrintError prints an error message in red.

func PrintInfo added in v0.0.13

func PrintInfo(msg string)

PrintInfo prints an informational message in cyan.

func PrintSuccess added in v0.0.13

func PrintSuccess(msg string)

PrintSuccess prints a success message in green.

func PrintWarning added in v0.0.13

func PrintWarning(msg string)

PrintWarning prints a warning message in yellow.

func RunCommand

func RunCommand(name string, args ...string) (string, error)

RunCommand executes a shell command It returns the output (trimmed) and an error if the command fails

func RunCommandSilent

func RunCommandSilent(name string, args ...string) (string, error)

RunCommandSilent executes a command (alias for RunCommand now, as RunCommand is also silent on success) kept for backward compatibility if needed, or we can remove it. The previous implementation was identical except for logging.

func RunShellCommand added in v0.0.10

func RunShellCommand(command string) (string, error)

RunShellCommand executes a shell command in a cross-platform way On Windows: uses cmd.exe /C On Unix (Linux/macOS): uses sh -c

func RunShellCommandAsync added in v0.0.13

func RunShellCommandAsync(command string) error

RunShellCommandAsync starts a shell command asynchronously (non-blocking) Returns immediately after starting, does not wait for completion

func ValidateDescription added in v0.0.13

func ValidateDescription(desc string) error

ValidateDescription validates the repository description

func ValidateRepoName added in v0.0.13

func ValidateRepoName(name string) error

ValidateRepoName validates the repository name Only alphanumeric, dash, and underscore allowed

Types

type Badge added in v0.0.13

type Badge struct {
	Label string // The text displayed on the left side of the badge.
	Value string // The text displayed on the right side of the badge.
	Color string // The background color for the value part of the badge (e.g., "#4c1" or "green").
}

Badge represents a single badge with a label, value, and color. This is the primary struct used to define a badge's appearance and content.

For example, to create a "Go version" badge, you might use:

b := Badge{
  Label: "Go",
  Value: "1.18",
  Color: "#007d9c",
}

type Badges added in v0.0.13

type Badges struct {
	// contains filtered or unexported fields
}

Badges is responsible for creating and managing a collection of badges. It handles parsing input arguments, generating the SVG image, and preparing the necessary markdown to embed the badges in a file.

The handler is configured using a series of string arguments, where each argument defines a badge in the "label:value:color" format.

Special commands can be passed as arguments to control the output:

  • "output_svgfile:path/to/your.svg": Specifies the output file for the SVG image.
  • "readmefile:path/to/your/README.md": Specifies the markdown file to be updated.

func NewBadges added in v0.0.13

func NewBadges(args ...string) *Badges

NewBadges creates and initializes a new Badges.

It takes a variadic slice of strings as input. Each string can be a badge definition ("label:value:color") or a special command.

Example:

handler := NewBadges(
  "Go:1.18:#007d9c",
  "Tests:Passing:#4c1",
  "output_svgfile:docs/badges.svg",
)

func (*Badges) BadgeMarkdown added in v0.0.13

func (h *Badges) BadgeMarkdown() string

BadgeMarkdown generates the markdown snippet for embedding the badge image. The snippet is an HTML `<a>` tag containing an `<img>` tag, which is compatible with most markdown renderers.

Example output:

<a href="docs/img/badges.svg"><img src="docs/img/badges.svg" alt="Project Badges" title="..."></a>

func (*Badges) BuildBadges added in v0.0.13

func (h *Badges) BuildBadges() ([]string, error)

BuildBadges generates the SVG image, writes it to the specified output file, and returns a slice of strings intended for updating a markdown file.

The returned slice contains the following elements in order: 1. sectionID: The ID of the markdown section to update. 2. afterLine: The line number after which the content should be inserted. 3. content: The markdown content to be inserted. 4. readmeFile: The path to the markdown file to be updated.

This method centralizes the core logic of badge generation and file I/O.

func (*Badges) Err added in v0.0.13

func (h *Badges) Err() error

Err returns any error that occurred during the initialization or processing of the Badges. It's important to check this error before proceeding with badge generation.

func (*Badges) GenerateSVG added in v0.0.13

func (h *Badges) GenerateSVG() ([]byte, int, error)

GenerateSVG creates an SVG image from the configured badges.

It returns the SVG content as a byte slice, the number of badges included, and an error if the generation fails. This method is typically called by BuildBadges, but it can be used directly if you only need the SVG data.

Example of a generated SVG for two badges ("License:MIT:blue" and "Go:1.22:blue"):

<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" width="168" height="20" viewBox="0 0 168 20">

<!-- Badge: License -->
<g transform="translate(0, 0)">
  <rect x="0" y="0" width="58" height="20" fill="#6c757d"/>
  <rect x="58" y="0" width="46" height="20" fill="blue"/>
  <text x="29" y="14" text-anchor="middle" font-family="sans-serif" font-size="11" fill="white">License</text>
  <text x="81" y="14" text-anchor="middle" font-family="sans-serif" font-size="11" fill="white">MIT</text>
</g>
<!-- Badge: Go -->
<g transform="translate(109, 0)">
  <rect x="0" y="0" width="34" height="20" fill="#6c757d"/>
  <rect x="34" y="0" width="25" height="20" fill="blue"/>
  <text x="17" y="14" text-anchor="middle" font-family="sans-serif" font-size="11" fill="white">Go</text>
  <text x="46" y="14" text-anchor="middle" font-family="sans-serif" font-size="11" fill="white">1.22</text>
</g>

</svg>

func (*Badges) GoHandler added in v0.0.13

func (h *Badges) GoHandler() *Go

GoHandler returns the internal Go handler

func (*Badges) OutputFile added in v0.0.13

func (h *Badges) OutputFile() string

OutputFile returns the configured path for the output SVG file. This is the destination where the generated SVG image will be saved.

func (*Badges) ReadmeFile added in v0.0.13

func (h *Badges) ReadmeFile() string

ReadmeFile returns the configured path for the markdown file to be updated.

type Bashrc added in v0.0.10

type Bashrc struct {
	// contains filtered or unexported fields
}

Bashrc handles updates to .bashrc file using markers

func NewBashrc added in v0.0.10

func NewBashrc() *Bashrc

NewBashrc creates a new Bashrc handler for ~/.bashrc

func (*Bashrc) Get added in v0.0.10

func (b *Bashrc) Get(key string) (string, error)

Get reads a variable value from .bashrc file

func (*Bashrc) Set added in v0.0.10

func (b *Bashrc) Set(key, value string) error

Set updates or creates a variable in .bashrc If value is empty, removes the variable

type ConsoleFilter

type ConsoleFilter struct {
	// contains filtered or unexported fields
}

ConsoleFilter buffers console output and filters out passing tests when in quiet mode.

func NewConsoleFilter

func NewConsoleFilter(quiet bool, output func(string)) *ConsoleFilter

func (*ConsoleFilter) Add

func (cf *ConsoleFilter) Add(input string)

func (*ConsoleFilter) Flush

func (cf *ConsoleFilter) Flush()

type DevBackup added in v0.0.10

type DevBackup struct {
	// contains filtered or unexported fields
}

DevBackup handles backup operations

func NewDevBackup added in v0.0.10

func NewDevBackup() *DevBackup

NewDevBackup creates a new DevBackup instance

func (*DevBackup) GetCommand added in v0.0.10

func (d *DevBackup) GetCommand() (string, error)

GetCommand retrieves the backup command First checks environment variable, then falls back to .bashrc

func (*DevBackup) Run added in v0.0.10

func (d *DevBackup) Run() (string, error)

Run executes the backup command asynchronously Returns a message for the summary or empty string if not configured

func (*DevBackup) SetCommand added in v0.0.10

func (d *DevBackup) SetCommand(command string) error

SetCommand sets the backup command in .bashrc and current environment

type Git

type Git struct {
	// contains filtered or unexported fields
}

Git handler for Git operations

func NewGit

func NewGit() (*Git, error)

NewGit creates a new Git handler and verifies git is available

func (*Git) GenerateNextTag

func (g *Git) GenerateNextTag() (string, error)

GenerateNextTag calculates the next semantic version

func (*Git) GetConfigUserEmail added in v0.0.13

func (g *Git) GetConfigUserEmail() (string, error)

GetConfigUserEmail gets the git user.email

func (*Git) GetConfigUserName added in v0.0.13

func (g *Git) GetConfigUserName() (string, error)

GetConfigUserName gets the git user.name

func (*Git) GetLatestTag

func (g *Git) GetLatestTag() (string, error)

GetLatestTag gets the latest tag

func (*Git) InitRepo added in v0.0.13

func (g *Git) InitRepo(dir string) error

InitRepo initializes a new git repository

func (*Git) Push

func (g *Git) Push(message, tag string) (string, error)

Push executes the complete push workflow (add, commit, tag, push) Returns a summary of operations and error if any.

func (*Git) SetLog

func (g *Git) SetLog(fn func(...any))

SetLog sets the logger function

func (*Git) SetUserConfig added in v0.0.13

func (g *Git) SetUserConfig(name, email string) error

SetUserConfig sets git user name and email

type GitHub added in v0.0.13

type GitHub struct {
	// contains filtered or unexported fields
}

GitHub handler for GitHub operations

func NewGitHub added in v0.0.13

func NewGitHub() (*GitHub, error)

NewGitHub creates handler and verifies gh CLI availability

func (*GitHub) CreateRepo added in v0.0.13

func (gh *GitHub) CreateRepo(name, description, visibility string) error

CreateRepo creates a new repository on GitHub

func (*GitHub) GetCurrentUser added in v0.0.13

func (gh *GitHub) GetCurrentUser() (string, error)

GetCurrentUser gets the current authenticated user

func (*GitHub) GetHelpfulErrorMessage added in v0.0.13

func (gh *GitHub) GetHelpfulErrorMessage(err error) string

GetHelpfulErrorMessage returns a helpful message for common errors

func (*GitHub) IsNetworkError added in v0.0.13

func (gh *GitHub) IsNetworkError(err error) bool

IsNetworkError checks if an error is likely a network error

func (*GitHub) RepoExists added in v0.0.13

func (gh *GitHub) RepoExists(owner, name string) (bool, error)

RepoExists checks if a repository exists

func (*GitHub) SetLog added in v0.0.13

func (gh *GitHub) SetLog(fn func(...any))

SetLog sets the logger function

type Go

type Go struct {
	// contains filtered or unexported fields
}

Go handler for Go operations

func NewGo

func NewGo(gitHandler *Git) (*Go, error)

NewGo creates a new Go handler and verifies Go installation

func (*Go) DetectGoExecutable added in v0.0.13

func (g *Go) DetectGoExecutable() (string, error)

DetectGoExecutable returns the path to the go executable

func (*Go) GoVersion added in v0.0.13

func (g *Go) GoVersion() (string, error)

GoVersion reads the Go version from the go.mod file in the current directory. It returns the version string (e.g., "1.18") or an empty string if not found.

func (*Go) ModInit added in v0.0.13

func (g *Go) ModInit(modulePath, targetDir string) error

ModInit initializes a new go module

func (*Go) Push

func (g *Go) Push(message, tag string, skipTests, skipRace bool, searchPath string) (string, error)

Push executes the complete workflow for Go projects Parameters:

message: Commit message
tag: Optional tag
skipTests: If true, skips tests
skipRace: If true, skips race tests
searchPath: Path to search for dependent modules (default: "..")

func (*Go) SetLog

func (g *Go) SetLog(fn func(...any))

SetLog sets the logger function

func (*Go) Test

func (g *Go) Test(verbose bool) (string, error)

Test executes the test suite for the project

type GoNew added in v0.0.13

type GoNew struct {
	// contains filtered or unexported fields
}

GoNew orchestrator

func NewGoNew added in v0.0.13

func NewGoNew(git *Git, github *GitHub, goHandler *Go) *GoNew

NewGoNew creates orchestrator (all handlers must be initialized)

func (*GoNew) AddRemote added in v0.0.13

func (gn *GoNew) AddRemote(projectPath, visibility, owner string) (string, error)

AddRemote adds GitHub remote to existing local project

func (*GoNew) Create added in v0.0.13

func (gn *GoNew) Create(opts NewProjectOptions) (string, error)

Create executes full workflow with remote (or local-only fallback)

func (*GoNew) SetLog added in v0.0.13

func (gn *GoNew) SetLog(fn func(...any))

SetLog sets the logger function

type MarkDown added in v0.0.13

type MarkDown struct {
	// contains filtered or unexported fields
}

func NewMarkDown added in v0.0.13

func NewMarkDown(rootDir, destination string, writerFile func(name string, data []byte) error) *MarkDown

NewMarkDown creates a new MarkDown instance with the root directory. Destination (output directory) and input must be set via methods.

func (*MarkDown) Extract added in v0.0.13

func (m *MarkDown) Extract(outputFile string) error

Extract extracts code blocks from the configured input and writes to outputFile The output file extension determines which code type to extract (.go, .js, .css)

func (*MarkDown) InputByte added in v0.0.13

func (m *MarkDown) InputByte(content []byte) *MarkDown

InputByte sets the input as a byte slice (markdown content)

func (*MarkDown) InputEmbed added in v0.0.13

func (m *MarkDown) InputEmbed(path string, readerFile func(name string) ([]byte, error)) *MarkDown

InputEmbed sets the input as any ReaderFile implementation and a relative path inside it

func (*MarkDown) InputPath added in v0.0.13

func (m *MarkDown) InputPath(pathFile string, readerFile func(name string) ([]byte, error)) *MarkDown

InputPath sets the input as a file path (relative to rootDir)

func (*MarkDown) SetLogger added in v0.0.13

func (m *MarkDown) SetLogger(logger func(...any)) *MarkDown

SetLogger sets a custom logger function

func (*MarkDown) UpdateSection added in v0.0.13

func (m *MarkDown) UpdateSection(sectionID, content string, afterLine ...string) error

UpdateSection updates or creates a section in the input file based on identifier. sectionID: The identifier for the section (e.g., "BADGES"). content: The new content to insert. afterLine: Optional. Implementation tries to insert after this line number if section doesn't exist.

type NewProjectOptions added in v0.0.13

type NewProjectOptions struct {
	Name        string // Required, must be valid (alphanumeric, dash, underscore only)
	Description string // Required, max 350 chars
	Owner       string // GitHub owner/organization (default: detected from gh or git config)
	Visibility  string // "public" or "private" (default: "public")
	Directory   string // Supports ~/path, ./path, /abs/path (default: ./{Name})
	LocalOnly   bool   // If true, skip remote creation
	License     string // Default "MIT"
}

NewProjectOptions options for creating a new project

Directories

Path Synopsis
cmd
badges command
devbackup command
gonew command
gopush command
gotest command
push command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL