| 1 | # Makefile for parrot |
| 2 | # Intelligent CLI command failure assistant |
| 3 | |
| 4 | # Project configuration |
| 5 | PROJECT_NAME = parrot |
| 6 | VERSION = 1.6.1 |
| 7 | TARGET = parrot |
| 8 | |
| 9 | # Go configuration |
| 10 | GOCMD = go |
| 11 | GOBUILD = $(GOCMD) build |
| 12 | GOCLEAN = $(GOCMD) clean |
| 13 | GOTEST = $(GOCMD) test |
| 14 | GOGET = $(GOCMD) get |
| 15 | GOMOD = $(GOCMD) mod |
| 16 | |
| 17 | # Build flags |
| 18 | LDFLAGS = -ldflags="-w -s" |
| 19 | BUILD_FLAGS = $(LDFLAGS) |
| 20 | |
| 21 | # Directories |
| 22 | SRCDIR = . |
| 23 | BUILDDIR = build |
| 24 | RPMDIR = rpmbuild |
| 25 | DISTDIR = dist |
| 26 | |
| 27 | # RPM configuration |
| 28 | RPMVERSION = $(VERSION) |
| 29 | RPMRELEASE = 1 |
| 30 | RPM_TOPDIR = $(shell pwd)/$(RPMDIR) |
| 31 | SPEC_FILE = $(PROJECT_NAME).spec |
| 32 | |
| 33 | # Default target |
| 34 | .PHONY: all |
| 35 | all: build |
| 36 | |
| 37 | # Build the Go binary |
| 38 | .PHONY: build |
| 39 | build: |
| 40 | @echo "Building $(PROJECT_NAME)..." |
| 41 | $(GOMOD) download |
| 42 | $(GOBUILD) $(BUILD_FLAGS) -o $(TARGET) $(SRCDIR) |
| 43 | @echo "✓ Build complete: $(TARGET)" |
| 44 | |
| 45 | # Clean build artifacts |
| 46 | .PHONY: clean |
| 47 | clean: |
| 48 | @echo "Cleaning build artifacts..." |
| 49 | $(GOCLEAN) |
| 50 | rm -f $(TARGET) |
| 51 | rm -rf $(BUILDDIR) |
| 52 | rm -rf $(RPMDIR) |
| 53 | rm -rf $(DISTDIR) |
| 54 | @echo "✓ Clean complete" |
| 55 | |
| 56 | # Run tests |
| 57 | .PHONY: test |
| 58 | test: |
| 59 | @echo "Running tests..." |
| 60 | $(GOTEST) -v ./... |
| 61 | |
| 62 | # Install locally |
| 63 | .PHONY: install |
| 64 | install: build |
| 65 | @echo "Installing $(TARGET)..." |
| 66 | @mkdir -p $(HOME)/.local/bin |
| 67 | @mkdir -p $(HOME)/.local/share/$(PROJECT_NAME) |
| 68 | @mkdir -p $(HOME)/.config/$(PROJECT_NAME) |
| 69 | @cp $(TARGET) $(HOME)/.local/bin/ |
| 70 | @cp parrot-hook.sh $(HOME)/.local/share/$(PROJECT_NAME)/ |
| 71 | @cp config/parrot.toml.example $(HOME)/.config/$(PROJECT_NAME)/ 2>/dev/null || true |
| 72 | @echo "✓ Installed to ~/.local/bin/$(TARGET)" |
| 73 | @echo "Make sure ~/.local/bin is in your PATH" |
| 74 | @echo "Run '$(TARGET) setup' to complete configuration" |
| 75 | |
| 76 | # Uninstall locally |
| 77 | .PHONY: uninstall |
| 78 | uninstall: |
| 79 | @echo "Uninstalling $(PROJECT_NAME)..." |
| 80 | @rm -f $(HOME)/.local/bin/$(TARGET) |
| 81 | @rm -rf $(HOME)/.local/share/$(PROJECT_NAME) |
| 82 | @echo "✓ Uninstalled (config preserved in ~/.config/$(PROJECT_NAME))" |
| 83 | |
| 84 | # Create source tarball for RPM |
| 85 | .PHONY: tarball |
| 86 | tarball: clean |
| 87 | @echo "Creating source tarball..." |
| 88 | @mkdir -p $(DISTDIR) |
| 89 | @git archive --format=tar.gz --prefix=$(PROJECT_NAME)-$(VERSION)/ HEAD > $(DISTDIR)/$(PROJECT_NAME)-$(VERSION).tar.gz |
| 90 | @echo "✓ Created $(DISTDIR)/$(PROJECT_NAME)-$(VERSION).tar.gz" |
| 91 | |
| 92 | # Prepare RPM build environment |
| 93 | .PHONY: rpm-prep |
| 94 | rpm-prep: tarball |
| 95 | @echo "Preparing RPM build environment..." |
| 96 | @mkdir -p $(RPM_TOPDIR)/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS} |
| 97 | @cp $(DISTDIR)/$(PROJECT_NAME)-$(VERSION).tar.gz $(RPM_TOPDIR)/SOURCES/ |
| 98 | @cp $(SPEC_FILE) $(RPM_TOPDIR)/SPECS/ |
| 99 | @echo "✓ RPM environment ready" |
| 100 | |
| 101 | # Build source RPM |
| 102 | .PHONY: srpm |
| 103 | srpm: rpm-prep |
| 104 | @echo "Building source RPM..." |
| 105 | rpmbuild --define "_topdir $(RPM_TOPDIR)" -bs $(RPM_TOPDIR)/SPECS/$(SPEC_FILE) |
| 106 | @echo "✓ Source RPM created in $(RPMDIR)/SRPMS/" |
| 107 | |
| 108 | # Build binary RPM |
| 109 | .PHONY: rpm |
| 110 | rpm: rpm-prep |
| 111 | @echo "Building RPM package..." |
| 112 | rpmbuild --define "_topdir $(RPM_TOPDIR)" -ba $(RPM_TOPDIR)/SPECS/$(SPEC_FILE) |
| 113 | @echo "✓ RPM packages created:" |
| 114 | @find $(RPMDIR)/RPMS -name "*.rpm" -exec echo " {}" \; |
| 115 | @find $(RPMDIR)/SRPMS -name "*.rpm" -exec echo " {}" \; |
| 116 | |
| 117 | # Copy RPMs to repository structure (matching existing projects) |
| 118 | .PHONY: copy-rpms |
| 119 | copy-rpms: rpm |
| 120 | @echo "Copying RPMs to repository structure..." |
| 121 | @mkdir -p ../repos-musicsian-com/RPMS/ |
| 122 | @cp $(RPMDIR)/RPMS/x86_64/$(PROJECT_NAME)-*.rpm ../repos-musicsian-com/RPMS/ |
| 123 | @cp $(RPMDIR)/SRPMS/$(PROJECT_NAME)-*.src.rpm ../repos-musicsian-com/RPMS/ |
| 124 | @echo "✓ RPMs copied to ../repos-musicsian-com/RPMS/" |
| 125 | |
| 126 | # Sign and deploy to repository |
| 127 | .PHONY: deploy |
| 128 | deploy: copy-rpms |
| 129 | @echo "Deploying to live repository..." |
| 130 | @cd ../repos-musicsian-com && ./deploy.sh |
| 131 | @echo "🚀 Deployment complete!" |
| 132 | @echo "Users can now run: sudo dnf update $(PROJECT_NAME)" |
| 133 | |
| 134 | # Format Go code |
| 135 | .PHONY: format |
| 136 | format: |
| 137 | @echo "Formatting Go code..." |
| 138 | @command -v gofmt >/dev/null 2>&1 && gofmt -w . || echo "gofmt not found" |
| 139 | @command -v goimports >/dev/null 2>&1 && goimports -w . || echo "goimports not found" |
| 140 | |
| 141 | # Lint Go code |
| 142 | .PHONY: lint |
| 143 | lint: |
| 144 | @echo "Running Go linter..." |
| 145 | @command -v golangci-lint >/dev/null 2>&1 && golangci-lint run || echo "golangci-lint not found" |
| 146 | |
| 147 | # Run development cycle |
| 148 | .PHONY: dev |
| 149 | dev: clean format lint test build |
| 150 | |
| 151 | # Quick smoke test |
| 152 | .PHONY: smoke-test |
| 153 | smoke-test: build |
| 154 | @echo "Running smoke test..." |
| 155 | @./$(TARGET) --version >/dev/null && echo "✓ Version command works" |
| 156 | @./$(TARGET) --help >/dev/null && echo "✓ Help command works" |
| 157 | @./$(TARGET) status >/dev/null 2>&1 && echo "✓ Status command works" || echo "⚠ Status command needs configuration" |
| 158 | |
| 159 | # Create .repo file for YUM repository |
| 160 | .PHONY: repo-file |
| 161 | repo-file: |
| 162 | @echo "Creating repository file..." |
| 163 | @mkdir -p $(DISTDIR) |
| 164 | @echo "[$(PROJECT_NAME)]" > $(DISTDIR)/$(PROJECT_NAME).repo |
| 165 | @echo "name=Parrot - Intelligent CLI Assistant" >> $(DISTDIR)/$(PROJECT_NAME).repo |
| 166 | @echo "baseurl=https://repos.musicsian.com/" >> $(DISTDIR)/$(PROJECT_NAME).repo |
| 167 | @echo "enabled=1" >> $(DISTDIR)/$(PROJECT_NAME).repo |
| 168 | @echo "gpgcheck=0" >> $(DISTDIR)/$(PROJECT_NAME).repo |
| 169 | @echo "Created $(DISTDIR)/$(PROJECT_NAME).repo" |
| 170 | |
| 171 | # Show build information |
| 172 | .PHONY: info |
| 173 | info: |
| 174 | @echo "Project: $(PROJECT_NAME) v$(VERSION)" |
| 175 | @echo "Target: $(TARGET)" |
| 176 | @echo "Go version: $(shell $(GOCMD) version)" |
| 177 | @echo "RPM build directory: $(RPM_TOPDIR)" |
| 178 | |
| 179 | # Check dependencies |
| 180 | .PHONY: deps |
| 181 | deps: |
| 182 | @echo "Checking dependencies..." |
| 183 | @echo "Required tools:" |
| 184 | @command -v $(GOCMD) >/dev/null 2>&1 && echo " $(GOCMD) - $(shell $(GOCMD) version)" || echo " $(GOCMD) - REQUIRED" |
| 185 | @command -v make >/dev/null 2>&1 && echo " make" || echo " make - REQUIRED" |
| 186 | @echo "RPM build tools:" |
| 187 | @command -v rpmbuild >/dev/null 2>&1 && echo " rpmbuild" || echo " rpmbuild - for RPM building" |
| 188 | @echo "Optional tools:" |
| 189 | @command -v gofmt >/dev/null 2>&1 && echo " gofmt" || echo " gofmt - for formatting" |
| 190 | @command -v golangci-lint >/dev/null 2>&1 && echo " golangci-lint" || echo " golangci-lint - for linting" |
| 191 | @command -v goimports >/dev/null 2>&1 && echo " goimports" || echo " goimports - for import management" |
| 192 | |
| 193 | # Release workflow |
| 194 | .PHONY: release |
| 195 | release: |
| 196 | @echo "Starting release workflow..." |
| 197 | @echo "Usage: make release VERSION=x.y.z" |
| 198 | @if [ -z "$(VERSION)" ]; then \ |
| 199 | echo "Error: VERSION not specified"; \ |
| 200 | echo "Example: make release VERSION=1.0.5"; \ |
| 201 | exit 1; \ |
| 202 | fi |
| 203 | @./scripts/release.sh $(VERSION) |
| 204 | |
| 205 | # Help target |
| 206 | .PHONY: help |
| 207 | help: |
| 208 | @echo "$(PROJECT_NAME) Makefile" |
| 209 | @echo "" |
| 210 | @echo "Targets:" |
| 211 | @echo " build Build the Go binary" |
| 212 | @echo " clean Remove build artifacts" |
| 213 | @echo " test Run tests" |
| 214 | @echo " install Install locally to ~/.local/bin" |
| 215 | @echo " uninstall Remove local installation" |
| 216 | @echo " format Format Go code" |
| 217 | @echo " lint Run Go linter" |
| 218 | @echo " dev Development cycle (clean + format + lint + test + build)" |
| 219 | @echo " smoke-test Quick functionality check" |
| 220 | @echo "" |
| 221 | @echo "RPM Packaging:" |
| 222 | @echo " tarball Create source tarball" |
| 223 | @echo " rpm-prep Prepare RPM build environment" |
| 224 | @echo " srpm Build source RPM" |
| 225 | @echo " rpm Build binary RPM" |
| 226 | @echo " copy-rpms Copy RPMs to repository structure" |
| 227 | @echo " repo-file Create .repo file for YUM" |
| 228 | @echo " deploy Build and deploy to live repository" |
| 229 | @echo "" |
| 230 | @echo "Release Management:" |
| 231 | @echo " release Complete release workflow (requires VERSION=x.y.z)" |
| 232 | @echo "" |
| 233 | @echo "Utilities:" |
| 234 | @echo " info Show build information" |
| 235 | @echo " deps Check dependencies" |
| 236 | @echo " help Show this help" |
| 237 | @echo "" |
| 238 | @echo "Example workflow:" |
| 239 | @echo " make dev # Development cycle" |
| 240 | @echo " make release VERSION=1.0.5 # Complete release" |
| 241 | @echo " make deploy # Deploy to repository" |
| 242 | |
| 243 | .PHONY: all build clean test install uninstall tarball rpm-prep srpm rpm copy-rpms format lint dev smoke-test repo-file info deps help |