2026-01-29 02:10:16 +00:00
|
|
|
package devops
|
|
|
|
|
|
|
|
|
|
import (
|
2026-01-29 14:28:23 +00:00
|
|
|
"context"
|
2026-01-29 02:10:16 +00:00
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"testing"
|
2026-01-29 14:28:23 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/host-uk/core/pkg/devops/sources"
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
"github.com/stretchr/testify/require"
|
2026-01-29 02:10:16 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestImageManager_Good_IsInstalled(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
cfg := DefaultConfig()
|
|
|
|
|
mgr, err := NewImageManager(cfg)
|
2026-01-29 14:28:23 +00:00
|
|
|
require.NoError(t, err)
|
2026-01-29 02:10:16 +00:00
|
|
|
|
|
|
|
|
// Not installed yet
|
2026-01-29 14:28:23 +00:00
|
|
|
assert.False(t, mgr.IsInstalled())
|
2026-01-29 02:10:16 +00:00
|
|
|
|
|
|
|
|
// Create fake image
|
|
|
|
|
imagePath := filepath.Join(tmpDir, ImageName())
|
2026-01-29 14:28:23 +00:00
|
|
|
err = os.WriteFile(imagePath, []byte("fake"), 0644)
|
|
|
|
|
require.NoError(t, err)
|
2026-01-29 02:10:16 +00:00
|
|
|
|
|
|
|
|
// Now installed
|
2026-01-29 14:28:23 +00:00
|
|
|
assert.True(t, mgr.IsInstalled())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestNewImageManager_Good(t *testing.T) {
|
|
|
|
|
t.Run("creates manager with cdn source", func(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
cfg := DefaultConfig()
|
|
|
|
|
cfg.Images.Source = "cdn"
|
feat: git command, build improvements, and go fmt git-aware (#74)
* feat(go): make go fmt git-aware by default
- By default, only check changed Go files (modified, staged, untracked)
- Add --all flag to check all files (previous behaviour)
- Reduces noise when running fmt on large codebases
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(build): minimal output by default, add missing i18n
- Default output now shows single line: "Success Built N artifacts (dir)"
- Add --verbose/-v flag to show full detailed output
- Add all missing i18n translations for build commands
- Errors still show failure reason in minimal mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add root-level `core git` command
- Create pkg/gitcmd with git workflow commands as root menu
- Export command builders from pkg/dev (AddCommitCommand, etc.)
- Commands available under both `core git` and `core dev` for compatibility
- Git commands: health, commit, push, pull, work, sync, apply
- GitHub orchestration stays in dev: issues, reviews, ci, impact
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(qa): add docblock coverage checking
Implement docblock/docstring coverage analysis for Go code:
- New `core qa docblock` command to check coverage
- Shows compact file:line list when under threshold
- Integrate with `core go qa` as a default check
- Add --docblock-threshold flag (default 80%)
The checker uses Go AST parsing to find exported symbols
(functions, types, consts, vars) without documentation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- Fix doc comment: "status" → "health" in gitcmd package
- Implement --check flag for `core go fmt` (exits non-zero if files need formatting)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: add docstrings for 100% coverage
Add documentation comments to all exported symbols:
- pkg/build: ProjectType constants
- pkg/cli: LogLevel, RenderStyle, TableStyle
- pkg/framework: ServiceFor, MustServiceFor, Core.Core
- pkg/git: GitError.Error, GitError.Unwrap
- pkg/i18n: Handler Match/Handle methods
- pkg/log: Level constants
- pkg/mcp: Tool input/output types
- pkg/php: Service constants, QA types, service methods
- pkg/process: ServiceError.Error
- pkg/repos: RepoType constants
- pkg/setup: ChangeType, ChangeCategory constants
- pkg/workspace: AddWorkspaceCommands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: standardize line endings to LF
Add .gitattributes to enforce LF line endings for all text files.
Normalize all existing files to use Unix-style line endings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- cmd_format.go: validate --check/--fix mutual exclusivity, capture stderr
- cmd_docblock.go: return error instead of os.Exit(1) for proper error handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback (round 2)
- linuxkit.go: propagate state update errors, handle cmd.Wait() errors in waitForExit
- mcp.go: guard against empty old_string in editDiff to prevent runaway edits
- cmd_docblock.go: log parse errors instead of silently skipping
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:48:44 +00:00
|
|
|
|
2026-01-29 14:28:23 +00:00
|
|
|
mgr, err := NewImageManager(cfg)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.NotNil(t, mgr)
|
|
|
|
|
assert.Len(t, mgr.sources, 1)
|
|
|
|
|
assert.Equal(t, "cdn", mgr.sources[0].Name())
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
t.Run("creates manager with github source", func(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
cfg := DefaultConfig()
|
|
|
|
|
cfg.Images.Source = "github"
|
feat: git command, build improvements, and go fmt git-aware (#74)
* feat(go): make go fmt git-aware by default
- By default, only check changed Go files (modified, staged, untracked)
- Add --all flag to check all files (previous behaviour)
- Reduces noise when running fmt on large codebases
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(build): minimal output by default, add missing i18n
- Default output now shows single line: "Success Built N artifacts (dir)"
- Add --verbose/-v flag to show full detailed output
- Add all missing i18n translations for build commands
- Errors still show failure reason in minimal mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add root-level `core git` command
- Create pkg/gitcmd with git workflow commands as root menu
- Export command builders from pkg/dev (AddCommitCommand, etc.)
- Commands available under both `core git` and `core dev` for compatibility
- Git commands: health, commit, push, pull, work, sync, apply
- GitHub orchestration stays in dev: issues, reviews, ci, impact
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(qa): add docblock coverage checking
Implement docblock/docstring coverage analysis for Go code:
- New `core qa docblock` command to check coverage
- Shows compact file:line list when under threshold
- Integrate with `core go qa` as a default check
- Add --docblock-threshold flag (default 80%)
The checker uses Go AST parsing to find exported symbols
(functions, types, consts, vars) without documentation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- Fix doc comment: "status" → "health" in gitcmd package
- Implement --check flag for `core go fmt` (exits non-zero if files need formatting)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: add docstrings for 100% coverage
Add documentation comments to all exported symbols:
- pkg/build: ProjectType constants
- pkg/cli: LogLevel, RenderStyle, TableStyle
- pkg/framework: ServiceFor, MustServiceFor, Core.Core
- pkg/git: GitError.Error, GitError.Unwrap
- pkg/i18n: Handler Match/Handle methods
- pkg/log: Level constants
- pkg/mcp: Tool input/output types
- pkg/php: Service constants, QA types, service methods
- pkg/process: ServiceError.Error
- pkg/repos: RepoType constants
- pkg/setup: ChangeType, ChangeCategory constants
- pkg/workspace: AddWorkspaceCommands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: standardize line endings to LF
Add .gitattributes to enforce LF line endings for all text files.
Normalize all existing files to use Unix-style line endings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- cmd_format.go: validate --check/--fix mutual exclusivity, capture stderr
- cmd_docblock.go: return error instead of os.Exit(1) for proper error handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback (round 2)
- linuxkit.go: propagate state update errors, handle cmd.Wait() errors in waitForExit
- mcp.go: guard against empty old_string in editDiff to prevent runaway edits
- cmd_docblock.go: log parse errors instead of silently skipping
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:48:44 +00:00
|
|
|
|
2026-01-29 14:28:23 +00:00
|
|
|
mgr, err := NewImageManager(cfg)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.NotNil(t, mgr)
|
|
|
|
|
assert.Len(t, mgr.sources, 1)
|
|
|
|
|
assert.Equal(t, "github", mgr.sources[0].Name())
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestManifest_Save(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
path := filepath.Join(tmpDir, "manifest.json")
|
feat: git command, build improvements, and go fmt git-aware (#74)
* feat(go): make go fmt git-aware by default
- By default, only check changed Go files (modified, staged, untracked)
- Add --all flag to check all files (previous behaviour)
- Reduces noise when running fmt on large codebases
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(build): minimal output by default, add missing i18n
- Default output now shows single line: "Success Built N artifacts (dir)"
- Add --verbose/-v flag to show full detailed output
- Add all missing i18n translations for build commands
- Errors still show failure reason in minimal mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add root-level `core git` command
- Create pkg/gitcmd with git workflow commands as root menu
- Export command builders from pkg/dev (AddCommitCommand, etc.)
- Commands available under both `core git` and `core dev` for compatibility
- Git commands: health, commit, push, pull, work, sync, apply
- GitHub orchestration stays in dev: issues, reviews, ci, impact
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(qa): add docblock coverage checking
Implement docblock/docstring coverage analysis for Go code:
- New `core qa docblock` command to check coverage
- Shows compact file:line list when under threshold
- Integrate with `core go qa` as a default check
- Add --docblock-threshold flag (default 80%)
The checker uses Go AST parsing to find exported symbols
(functions, types, consts, vars) without documentation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- Fix doc comment: "status" → "health" in gitcmd package
- Implement --check flag for `core go fmt` (exits non-zero if files need formatting)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: add docstrings for 100% coverage
Add documentation comments to all exported symbols:
- pkg/build: ProjectType constants
- pkg/cli: LogLevel, RenderStyle, TableStyle
- pkg/framework: ServiceFor, MustServiceFor, Core.Core
- pkg/git: GitError.Error, GitError.Unwrap
- pkg/i18n: Handler Match/Handle methods
- pkg/log: Level constants
- pkg/mcp: Tool input/output types
- pkg/php: Service constants, QA types, service methods
- pkg/process: ServiceError.Error
- pkg/repos: RepoType constants
- pkg/setup: ChangeType, ChangeCategory constants
- pkg/workspace: AddWorkspaceCommands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: standardize line endings to LF
Add .gitattributes to enforce LF line endings for all text files.
Normalize all existing files to use Unix-style line endings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- cmd_format.go: validate --check/--fix mutual exclusivity, capture stderr
- cmd_docblock.go: return error instead of os.Exit(1) for proper error handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback (round 2)
- linuxkit.go: propagate state update errors, handle cmd.Wait() errors in waitForExit
- mcp.go: guard against empty old_string in editDiff to prevent runaway edits
- cmd_docblock.go: log parse errors instead of silently skipping
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:48:44 +00:00
|
|
|
|
2026-01-29 14:28:23 +00:00
|
|
|
m := &Manifest{
|
|
|
|
|
Images: make(map[string]ImageInfo),
|
|
|
|
|
path: path,
|
|
|
|
|
}
|
feat: git command, build improvements, and go fmt git-aware (#74)
* feat(go): make go fmt git-aware by default
- By default, only check changed Go files (modified, staged, untracked)
- Add --all flag to check all files (previous behaviour)
- Reduces noise when running fmt on large codebases
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(build): minimal output by default, add missing i18n
- Default output now shows single line: "Success Built N artifacts (dir)"
- Add --verbose/-v flag to show full detailed output
- Add all missing i18n translations for build commands
- Errors still show failure reason in minimal mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add root-level `core git` command
- Create pkg/gitcmd with git workflow commands as root menu
- Export command builders from pkg/dev (AddCommitCommand, etc.)
- Commands available under both `core git` and `core dev` for compatibility
- Git commands: health, commit, push, pull, work, sync, apply
- GitHub orchestration stays in dev: issues, reviews, ci, impact
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(qa): add docblock coverage checking
Implement docblock/docstring coverage analysis for Go code:
- New `core qa docblock` command to check coverage
- Shows compact file:line list when under threshold
- Integrate with `core go qa` as a default check
- Add --docblock-threshold flag (default 80%)
The checker uses Go AST parsing to find exported symbols
(functions, types, consts, vars) without documentation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- Fix doc comment: "status" → "health" in gitcmd package
- Implement --check flag for `core go fmt` (exits non-zero if files need formatting)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: add docstrings for 100% coverage
Add documentation comments to all exported symbols:
- pkg/build: ProjectType constants
- pkg/cli: LogLevel, RenderStyle, TableStyle
- pkg/framework: ServiceFor, MustServiceFor, Core.Core
- pkg/git: GitError.Error, GitError.Unwrap
- pkg/i18n: Handler Match/Handle methods
- pkg/log: Level constants
- pkg/mcp: Tool input/output types
- pkg/php: Service constants, QA types, service methods
- pkg/process: ServiceError.Error
- pkg/repos: RepoType constants
- pkg/setup: ChangeType, ChangeCategory constants
- pkg/workspace: AddWorkspaceCommands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: standardize line endings to LF
Add .gitattributes to enforce LF line endings for all text files.
Normalize all existing files to use Unix-style line endings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- cmd_format.go: validate --check/--fix mutual exclusivity, capture stderr
- cmd_docblock.go: return error instead of os.Exit(1) for proper error handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback (round 2)
- linuxkit.go: propagate state update errors, handle cmd.Wait() errors in waitForExit
- mcp.go: guard against empty old_string in editDiff to prevent runaway edits
- cmd_docblock.go: log parse errors instead of silently skipping
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:48:44 +00:00
|
|
|
|
2026-01-29 14:28:23 +00:00
|
|
|
m.Images["test.img"] = ImageInfo{
|
|
|
|
|
Version: "1.0.0",
|
|
|
|
|
Source: "test",
|
|
|
|
|
}
|
feat: git command, build improvements, and go fmt git-aware (#74)
* feat(go): make go fmt git-aware by default
- By default, only check changed Go files (modified, staged, untracked)
- Add --all flag to check all files (previous behaviour)
- Reduces noise when running fmt on large codebases
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(build): minimal output by default, add missing i18n
- Default output now shows single line: "Success Built N artifacts (dir)"
- Add --verbose/-v flag to show full detailed output
- Add all missing i18n translations for build commands
- Errors still show failure reason in minimal mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add root-level `core git` command
- Create pkg/gitcmd with git workflow commands as root menu
- Export command builders from pkg/dev (AddCommitCommand, etc.)
- Commands available under both `core git` and `core dev` for compatibility
- Git commands: health, commit, push, pull, work, sync, apply
- GitHub orchestration stays in dev: issues, reviews, ci, impact
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(qa): add docblock coverage checking
Implement docblock/docstring coverage analysis for Go code:
- New `core qa docblock` command to check coverage
- Shows compact file:line list when under threshold
- Integrate with `core go qa` as a default check
- Add --docblock-threshold flag (default 80%)
The checker uses Go AST parsing to find exported symbols
(functions, types, consts, vars) without documentation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- Fix doc comment: "status" → "health" in gitcmd package
- Implement --check flag for `core go fmt` (exits non-zero if files need formatting)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: add docstrings for 100% coverage
Add documentation comments to all exported symbols:
- pkg/build: ProjectType constants
- pkg/cli: LogLevel, RenderStyle, TableStyle
- pkg/framework: ServiceFor, MustServiceFor, Core.Core
- pkg/git: GitError.Error, GitError.Unwrap
- pkg/i18n: Handler Match/Handle methods
- pkg/log: Level constants
- pkg/mcp: Tool input/output types
- pkg/php: Service constants, QA types, service methods
- pkg/process: ServiceError.Error
- pkg/repos: RepoType constants
- pkg/setup: ChangeType, ChangeCategory constants
- pkg/workspace: AddWorkspaceCommands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: standardize line endings to LF
Add .gitattributes to enforce LF line endings for all text files.
Normalize all existing files to use Unix-style line endings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- cmd_format.go: validate --check/--fix mutual exclusivity, capture stderr
- cmd_docblock.go: return error instead of os.Exit(1) for proper error handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback (round 2)
- linuxkit.go: propagate state update errors, handle cmd.Wait() errors in waitForExit
- mcp.go: guard against empty old_string in editDiff to prevent runaway edits
- cmd_docblock.go: log parse errors instead of silently skipping
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:48:44 +00:00
|
|
|
|
2026-01-29 14:28:23 +00:00
|
|
|
err := m.Save()
|
|
|
|
|
assert.NoError(t, err)
|
feat: git command, build improvements, and go fmt git-aware (#74)
* feat(go): make go fmt git-aware by default
- By default, only check changed Go files (modified, staged, untracked)
- Add --all flag to check all files (previous behaviour)
- Reduces noise when running fmt on large codebases
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(build): minimal output by default, add missing i18n
- Default output now shows single line: "Success Built N artifacts (dir)"
- Add --verbose/-v flag to show full detailed output
- Add all missing i18n translations for build commands
- Errors still show failure reason in minimal mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add root-level `core git` command
- Create pkg/gitcmd with git workflow commands as root menu
- Export command builders from pkg/dev (AddCommitCommand, etc.)
- Commands available under both `core git` and `core dev` for compatibility
- Git commands: health, commit, push, pull, work, sync, apply
- GitHub orchestration stays in dev: issues, reviews, ci, impact
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(qa): add docblock coverage checking
Implement docblock/docstring coverage analysis for Go code:
- New `core qa docblock` command to check coverage
- Shows compact file:line list when under threshold
- Integrate with `core go qa` as a default check
- Add --docblock-threshold flag (default 80%)
The checker uses Go AST parsing to find exported symbols
(functions, types, consts, vars) without documentation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- Fix doc comment: "status" → "health" in gitcmd package
- Implement --check flag for `core go fmt` (exits non-zero if files need formatting)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: add docstrings for 100% coverage
Add documentation comments to all exported symbols:
- pkg/build: ProjectType constants
- pkg/cli: LogLevel, RenderStyle, TableStyle
- pkg/framework: ServiceFor, MustServiceFor, Core.Core
- pkg/git: GitError.Error, GitError.Unwrap
- pkg/i18n: Handler Match/Handle methods
- pkg/log: Level constants
- pkg/mcp: Tool input/output types
- pkg/php: Service constants, QA types, service methods
- pkg/process: ServiceError.Error
- pkg/repos: RepoType constants
- pkg/setup: ChangeType, ChangeCategory constants
- pkg/workspace: AddWorkspaceCommands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: standardize line endings to LF
Add .gitattributes to enforce LF line endings for all text files.
Normalize all existing files to use Unix-style line endings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- cmd_format.go: validate --check/--fix mutual exclusivity, capture stderr
- cmd_docblock.go: return error instead of os.Exit(1) for proper error handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback (round 2)
- linuxkit.go: propagate state update errors, handle cmd.Wait() errors in waitForExit
- mcp.go: guard against empty old_string in editDiff to prevent runaway edits
- cmd_docblock.go: log parse errors instead of silently skipping
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:48:44 +00:00
|
|
|
|
2026-01-29 14:28:23 +00:00
|
|
|
// Verify file exists and has content
|
|
|
|
|
_, err = os.Stat(path)
|
|
|
|
|
assert.NoError(t, err)
|
feat: git command, build improvements, and go fmt git-aware (#74)
* feat(go): make go fmt git-aware by default
- By default, only check changed Go files (modified, staged, untracked)
- Add --all flag to check all files (previous behaviour)
- Reduces noise when running fmt on large codebases
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(build): minimal output by default, add missing i18n
- Default output now shows single line: "Success Built N artifacts (dir)"
- Add --verbose/-v flag to show full detailed output
- Add all missing i18n translations for build commands
- Errors still show failure reason in minimal mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add root-level `core git` command
- Create pkg/gitcmd with git workflow commands as root menu
- Export command builders from pkg/dev (AddCommitCommand, etc.)
- Commands available under both `core git` and `core dev` for compatibility
- Git commands: health, commit, push, pull, work, sync, apply
- GitHub orchestration stays in dev: issues, reviews, ci, impact
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(qa): add docblock coverage checking
Implement docblock/docstring coverage analysis for Go code:
- New `core qa docblock` command to check coverage
- Shows compact file:line list when under threshold
- Integrate with `core go qa` as a default check
- Add --docblock-threshold flag (default 80%)
The checker uses Go AST parsing to find exported symbols
(functions, types, consts, vars) without documentation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- Fix doc comment: "status" → "health" in gitcmd package
- Implement --check flag for `core go fmt` (exits non-zero if files need formatting)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: add docstrings for 100% coverage
Add documentation comments to all exported symbols:
- pkg/build: ProjectType constants
- pkg/cli: LogLevel, RenderStyle, TableStyle
- pkg/framework: ServiceFor, MustServiceFor, Core.Core
- pkg/git: GitError.Error, GitError.Unwrap
- pkg/i18n: Handler Match/Handle methods
- pkg/log: Level constants
- pkg/mcp: Tool input/output types
- pkg/php: Service constants, QA types, service methods
- pkg/process: ServiceError.Error
- pkg/repos: RepoType constants
- pkg/setup: ChangeType, ChangeCategory constants
- pkg/workspace: AddWorkspaceCommands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: standardize line endings to LF
Add .gitattributes to enforce LF line endings for all text files.
Normalize all existing files to use Unix-style line endings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- cmd_format.go: validate --check/--fix mutual exclusivity, capture stderr
- cmd_docblock.go: return error instead of os.Exit(1) for proper error handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback (round 2)
- linuxkit.go: propagate state update errors, handle cmd.Wait() errors in waitForExit
- mcp.go: guard against empty old_string in editDiff to prevent runaway edits
- cmd_docblock.go: log parse errors instead of silently skipping
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:48:44 +00:00
|
|
|
|
2026-01-29 14:28:23 +00:00
|
|
|
// Reload
|
|
|
|
|
m2, err := loadManifest(path)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.Equal(t, "1.0.0", m2.Images["test.img"].Version)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestLoadManifest_Bad(t *testing.T) {
|
|
|
|
|
t.Run("invalid json", func(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
path := filepath.Join(tmpDir, "manifest.json")
|
|
|
|
|
err := os.WriteFile(path, []byte("invalid json"), 0644)
|
|
|
|
|
require.NoError(t, err)
|
feat: git command, build improvements, and go fmt git-aware (#74)
* feat(go): make go fmt git-aware by default
- By default, only check changed Go files (modified, staged, untracked)
- Add --all flag to check all files (previous behaviour)
- Reduces noise when running fmt on large codebases
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(build): minimal output by default, add missing i18n
- Default output now shows single line: "Success Built N artifacts (dir)"
- Add --verbose/-v flag to show full detailed output
- Add all missing i18n translations for build commands
- Errors still show failure reason in minimal mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add root-level `core git` command
- Create pkg/gitcmd with git workflow commands as root menu
- Export command builders from pkg/dev (AddCommitCommand, etc.)
- Commands available under both `core git` and `core dev` for compatibility
- Git commands: health, commit, push, pull, work, sync, apply
- GitHub orchestration stays in dev: issues, reviews, ci, impact
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(qa): add docblock coverage checking
Implement docblock/docstring coverage analysis for Go code:
- New `core qa docblock` command to check coverage
- Shows compact file:line list when under threshold
- Integrate with `core go qa` as a default check
- Add --docblock-threshold flag (default 80%)
The checker uses Go AST parsing to find exported symbols
(functions, types, consts, vars) without documentation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- Fix doc comment: "status" → "health" in gitcmd package
- Implement --check flag for `core go fmt` (exits non-zero if files need formatting)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: add docstrings for 100% coverage
Add documentation comments to all exported symbols:
- pkg/build: ProjectType constants
- pkg/cli: LogLevel, RenderStyle, TableStyle
- pkg/framework: ServiceFor, MustServiceFor, Core.Core
- pkg/git: GitError.Error, GitError.Unwrap
- pkg/i18n: Handler Match/Handle methods
- pkg/log: Level constants
- pkg/mcp: Tool input/output types
- pkg/php: Service constants, QA types, service methods
- pkg/process: ServiceError.Error
- pkg/repos: RepoType constants
- pkg/setup: ChangeType, ChangeCategory constants
- pkg/workspace: AddWorkspaceCommands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: standardize line endings to LF
Add .gitattributes to enforce LF line endings for all text files.
Normalize all existing files to use Unix-style line endings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- cmd_format.go: validate --check/--fix mutual exclusivity, capture stderr
- cmd_docblock.go: return error instead of os.Exit(1) for proper error handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback (round 2)
- linuxkit.go: propagate state update errors, handle cmd.Wait() errors in waitForExit
- mcp.go: guard against empty old_string in editDiff to prevent runaway edits
- cmd_docblock.go: log parse errors instead of silently skipping
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:48:44 +00:00
|
|
|
|
2026-01-29 14:28:23 +00:00
|
|
|
_, err = loadManifest(path)
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestCheckUpdate_Bad(t *testing.T) {
|
|
|
|
|
t.Run("image not installed", func(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
cfg := DefaultConfig()
|
|
|
|
|
mgr, err := NewImageManager(cfg)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
_, _, _, err = mgr.CheckUpdate(context.Background())
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
assert.Contains(t, err.Error(), "image not installed")
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestNewImageManager_Good_AutoSource(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
cfg := DefaultConfig()
|
|
|
|
|
cfg.Images.Source = "auto"
|
|
|
|
|
|
|
|
|
|
mgr, err := NewImageManager(cfg)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.NotNil(t, mgr)
|
|
|
|
|
assert.Len(t, mgr.sources, 2) // github and cdn
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestNewImageManager_Good_UnknownSourceFallsToAuto(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
cfg := DefaultConfig()
|
|
|
|
|
cfg.Images.Source = "unknown"
|
|
|
|
|
|
|
|
|
|
mgr, err := NewImageManager(cfg)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.NotNil(t, mgr)
|
|
|
|
|
assert.Len(t, mgr.sources, 2) // falls to default (auto) which is github + cdn
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestLoadManifest_Good_Empty(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
path := filepath.Join(tmpDir, "nonexistent.json")
|
|
|
|
|
|
|
|
|
|
m, err := loadManifest(path)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.NotNil(t, m)
|
|
|
|
|
assert.NotNil(t, m.Images)
|
|
|
|
|
assert.Empty(t, m.Images)
|
|
|
|
|
assert.Equal(t, path, m.path)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestLoadManifest_Good_ExistingData(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
path := filepath.Join(tmpDir, "manifest.json")
|
|
|
|
|
|
|
|
|
|
data := `{"images":{"test.img":{"version":"2.0.0","source":"cdn"}}}`
|
|
|
|
|
err := os.WriteFile(path, []byte(data), 0644)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
m, err := loadManifest(path)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.NotNil(t, m)
|
|
|
|
|
assert.Equal(t, "2.0.0", m.Images["test.img"].Version)
|
|
|
|
|
assert.Equal(t, "cdn", m.Images["test.img"].Source)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestImageInfo_Struct(t *testing.T) {
|
|
|
|
|
info := ImageInfo{
|
|
|
|
|
Version: "1.0.0",
|
|
|
|
|
SHA256: "abc123",
|
|
|
|
|
Downloaded: time.Now(),
|
|
|
|
|
Source: "github",
|
|
|
|
|
}
|
|
|
|
|
assert.Equal(t, "1.0.0", info.Version)
|
|
|
|
|
assert.Equal(t, "abc123", info.SHA256)
|
|
|
|
|
assert.False(t, info.Downloaded.IsZero())
|
|
|
|
|
assert.Equal(t, "github", info.Source)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestManifest_Save_Good_CreatesDirs(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
nestedPath := filepath.Join(tmpDir, "nested", "dir", "manifest.json")
|
|
|
|
|
|
|
|
|
|
m := &Manifest{
|
|
|
|
|
Images: make(map[string]ImageInfo),
|
|
|
|
|
path: nestedPath,
|
|
|
|
|
}
|
|
|
|
|
m.Images["test.img"] = ImageInfo{Version: "1.0.0"}
|
|
|
|
|
|
|
|
|
|
// Should fail because nested directories don't exist
|
|
|
|
|
// (Save doesn't create parent directories, it just writes to path)
|
|
|
|
|
err := m.Save()
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestManifest_Save_Good_Overwrite(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
path := filepath.Join(tmpDir, "manifest.json")
|
|
|
|
|
|
|
|
|
|
// First save
|
|
|
|
|
m1 := &Manifest{
|
|
|
|
|
Images: make(map[string]ImageInfo),
|
|
|
|
|
path: path,
|
|
|
|
|
}
|
|
|
|
|
m1.Images["test.img"] = ImageInfo{Version: "1.0.0"}
|
|
|
|
|
err := m1.Save()
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
// Second save with different data
|
|
|
|
|
m2 := &Manifest{
|
|
|
|
|
Images: make(map[string]ImageInfo),
|
|
|
|
|
path: path,
|
|
|
|
|
}
|
|
|
|
|
m2.Images["other.img"] = ImageInfo{Version: "2.0.0"}
|
|
|
|
|
err = m2.Save()
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
// Verify second data
|
|
|
|
|
loaded, err := loadManifest(path)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.Equal(t, "2.0.0", loaded.Images["other.img"].Version)
|
|
|
|
|
_, exists := loaded.Images["test.img"]
|
|
|
|
|
assert.False(t, exists)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestImageManager_Install_Bad_NoSourceAvailable(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
// Create manager with empty sources
|
|
|
|
|
mgr := &ImageManager{
|
|
|
|
|
config: DefaultConfig(),
|
|
|
|
|
manifest: &Manifest{Images: make(map[string]ImageInfo), path: filepath.Join(tmpDir, "manifest.json")},
|
|
|
|
|
sources: nil, // no sources
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := mgr.Install(context.Background(), nil)
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
assert.Contains(t, err.Error(), "no image source available")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestNewImageManager_Good_CreatesDir(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
imagesDir := filepath.Join(tmpDir, "images")
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", imagesDir)
|
|
|
|
|
|
|
|
|
|
cfg := DefaultConfig()
|
|
|
|
|
mgr, err := NewImageManager(cfg)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.NotNil(t, mgr)
|
|
|
|
|
|
|
|
|
|
// Verify directory was created
|
|
|
|
|
info, err := os.Stat(imagesDir)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.True(t, info.IsDir())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// mockImageSource is a test helper for simulating image sources
|
|
|
|
|
type mockImageSource struct {
|
|
|
|
|
name string
|
|
|
|
|
available bool
|
|
|
|
|
latestVersion string
|
|
|
|
|
latestErr error
|
|
|
|
|
downloadErr error
|
|
|
|
|
}
|
|
|
|
|
|
feat: git command, build improvements, and go fmt git-aware (#74)
* feat(go): make go fmt git-aware by default
- By default, only check changed Go files (modified, staged, untracked)
- Add --all flag to check all files (previous behaviour)
- Reduces noise when running fmt on large codebases
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(build): minimal output by default, add missing i18n
- Default output now shows single line: "Success Built N artifacts (dir)"
- Add --verbose/-v flag to show full detailed output
- Add all missing i18n translations for build commands
- Errors still show failure reason in minimal mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add root-level `core git` command
- Create pkg/gitcmd with git workflow commands as root menu
- Export command builders from pkg/dev (AddCommitCommand, etc.)
- Commands available under both `core git` and `core dev` for compatibility
- Git commands: health, commit, push, pull, work, sync, apply
- GitHub orchestration stays in dev: issues, reviews, ci, impact
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(qa): add docblock coverage checking
Implement docblock/docstring coverage analysis for Go code:
- New `core qa docblock` command to check coverage
- Shows compact file:line list when under threshold
- Integrate with `core go qa` as a default check
- Add --docblock-threshold flag (default 80%)
The checker uses Go AST parsing to find exported symbols
(functions, types, consts, vars) without documentation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- Fix doc comment: "status" → "health" in gitcmd package
- Implement --check flag for `core go fmt` (exits non-zero if files need formatting)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: add docstrings for 100% coverage
Add documentation comments to all exported symbols:
- pkg/build: ProjectType constants
- pkg/cli: LogLevel, RenderStyle, TableStyle
- pkg/framework: ServiceFor, MustServiceFor, Core.Core
- pkg/git: GitError.Error, GitError.Unwrap
- pkg/i18n: Handler Match/Handle methods
- pkg/log: Level constants
- pkg/mcp: Tool input/output types
- pkg/php: Service constants, QA types, service methods
- pkg/process: ServiceError.Error
- pkg/repos: RepoType constants
- pkg/setup: ChangeType, ChangeCategory constants
- pkg/workspace: AddWorkspaceCommands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: standardize line endings to LF
Add .gitattributes to enforce LF line endings for all text files.
Normalize all existing files to use Unix-style line endings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- cmd_format.go: validate --check/--fix mutual exclusivity, capture stderr
- cmd_docblock.go: return error instead of os.Exit(1) for proper error handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback (round 2)
- linuxkit.go: propagate state update errors, handle cmd.Wait() errors in waitForExit
- mcp.go: guard against empty old_string in editDiff to prevent runaway edits
- cmd_docblock.go: log parse errors instead of silently skipping
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:48:44 +00:00
|
|
|
func (m *mockImageSource) Name() string { return m.name }
|
2026-01-29 14:28:23 +00:00
|
|
|
func (m *mockImageSource) Available() bool { return m.available }
|
|
|
|
|
func (m *mockImageSource) LatestVersion(ctx context.Context) (string, error) {
|
|
|
|
|
return m.latestVersion, m.latestErr
|
|
|
|
|
}
|
|
|
|
|
func (m *mockImageSource) Download(ctx context.Context, dest string, progress func(downloaded, total int64)) error {
|
|
|
|
|
if m.downloadErr != nil {
|
|
|
|
|
return m.downloadErr
|
|
|
|
|
}
|
|
|
|
|
// Create a fake image file
|
|
|
|
|
imagePath := filepath.Join(dest, ImageName())
|
|
|
|
|
return os.WriteFile(imagePath, []byte("mock image content"), 0644)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestImageManager_Install_Good_WithMockSource(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
mock := &mockImageSource{
|
|
|
|
|
name: "mock",
|
|
|
|
|
available: true,
|
|
|
|
|
latestVersion: "v1.0.0",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mgr := &ImageManager{
|
|
|
|
|
config: DefaultConfig(),
|
|
|
|
|
manifest: &Manifest{Images: make(map[string]ImageInfo), path: filepath.Join(tmpDir, "manifest.json")},
|
|
|
|
|
sources: []sources.ImageSource{mock},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := mgr.Install(context.Background(), nil)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.True(t, mgr.IsInstalled())
|
|
|
|
|
|
|
|
|
|
// Verify manifest was updated
|
|
|
|
|
info, ok := mgr.manifest.Images[ImageName()]
|
|
|
|
|
assert.True(t, ok)
|
|
|
|
|
assert.Equal(t, "v1.0.0", info.Version)
|
|
|
|
|
assert.Equal(t, "mock", info.Source)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestImageManager_Install_Bad_DownloadError(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
mock := &mockImageSource{
|
|
|
|
|
name: "mock",
|
|
|
|
|
available: true,
|
|
|
|
|
latestVersion: "v1.0.0",
|
|
|
|
|
downloadErr: assert.AnError,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mgr := &ImageManager{
|
|
|
|
|
config: DefaultConfig(),
|
|
|
|
|
manifest: &Manifest{Images: make(map[string]ImageInfo), path: filepath.Join(tmpDir, "manifest.json")},
|
|
|
|
|
sources: []sources.ImageSource{mock},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := mgr.Install(context.Background(), nil)
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestImageManager_Install_Bad_VersionError(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
mock := &mockImageSource{
|
|
|
|
|
name: "mock",
|
|
|
|
|
available: true,
|
|
|
|
|
latestErr: assert.AnError,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mgr := &ImageManager{
|
|
|
|
|
config: DefaultConfig(),
|
|
|
|
|
manifest: &Manifest{Images: make(map[string]ImageInfo), path: filepath.Join(tmpDir, "manifest.json")},
|
|
|
|
|
sources: []sources.ImageSource{mock},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := mgr.Install(context.Background(), nil)
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
assert.Contains(t, err.Error(), "failed to get latest version")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestImageManager_Install_Good_SkipsUnavailableSource(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
unavailableMock := &mockImageSource{
|
|
|
|
|
name: "unavailable",
|
|
|
|
|
available: false,
|
|
|
|
|
}
|
|
|
|
|
availableMock := &mockImageSource{
|
|
|
|
|
name: "available",
|
|
|
|
|
available: true,
|
|
|
|
|
latestVersion: "v2.0.0",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mgr := &ImageManager{
|
|
|
|
|
config: DefaultConfig(),
|
|
|
|
|
manifest: &Manifest{Images: make(map[string]ImageInfo), path: filepath.Join(tmpDir, "manifest.json")},
|
|
|
|
|
sources: []sources.ImageSource{unavailableMock, availableMock},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := mgr.Install(context.Background(), nil)
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
// Should have used the available source
|
|
|
|
|
info := mgr.manifest.Images[ImageName()]
|
|
|
|
|
assert.Equal(t, "available", info.Source)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestImageManager_CheckUpdate_Good_WithMockSource(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
mock := &mockImageSource{
|
|
|
|
|
name: "mock",
|
|
|
|
|
available: true,
|
|
|
|
|
latestVersion: "v2.0.0",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mgr := &ImageManager{
|
|
|
|
|
config: DefaultConfig(),
|
|
|
|
|
manifest: &Manifest{
|
|
|
|
|
Images: map[string]ImageInfo{
|
|
|
|
|
ImageName(): {Version: "v1.0.0", Source: "mock"},
|
|
|
|
|
},
|
|
|
|
|
path: filepath.Join(tmpDir, "manifest.json"),
|
|
|
|
|
},
|
|
|
|
|
sources: []sources.ImageSource{mock},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current, latest, hasUpdate, err := mgr.CheckUpdate(context.Background())
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.Equal(t, "v1.0.0", current)
|
|
|
|
|
assert.Equal(t, "v2.0.0", latest)
|
|
|
|
|
assert.True(t, hasUpdate)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestImageManager_CheckUpdate_Good_NoUpdate(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
mock := &mockImageSource{
|
|
|
|
|
name: "mock",
|
|
|
|
|
available: true,
|
|
|
|
|
latestVersion: "v1.0.0",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mgr := &ImageManager{
|
|
|
|
|
config: DefaultConfig(),
|
|
|
|
|
manifest: &Manifest{
|
|
|
|
|
Images: map[string]ImageInfo{
|
|
|
|
|
ImageName(): {Version: "v1.0.0", Source: "mock"},
|
|
|
|
|
},
|
|
|
|
|
path: filepath.Join(tmpDir, "manifest.json"),
|
|
|
|
|
},
|
|
|
|
|
sources: []sources.ImageSource{mock},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current, latest, hasUpdate, err := mgr.CheckUpdate(context.Background())
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.Equal(t, "v1.0.0", current)
|
|
|
|
|
assert.Equal(t, "v1.0.0", latest)
|
|
|
|
|
assert.False(t, hasUpdate)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestImageManager_CheckUpdate_Bad_NoSource(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
unavailableMock := &mockImageSource{
|
|
|
|
|
name: "mock",
|
|
|
|
|
available: false,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mgr := &ImageManager{
|
|
|
|
|
config: DefaultConfig(),
|
|
|
|
|
manifest: &Manifest{
|
|
|
|
|
Images: map[string]ImageInfo{
|
|
|
|
|
ImageName(): {Version: "v1.0.0", Source: "mock"},
|
|
|
|
|
},
|
|
|
|
|
path: filepath.Join(tmpDir, "manifest.json"),
|
|
|
|
|
},
|
|
|
|
|
sources: []sources.ImageSource{unavailableMock},
|
2026-01-29 02:10:16 +00:00
|
|
|
}
|
2026-01-29 14:28:23 +00:00
|
|
|
|
|
|
|
|
_, _, _, err := mgr.CheckUpdate(context.Background())
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
assert.Contains(t, err.Error(), "no image source available")
|
2026-01-29 02:10:16 +00:00
|
|
|
}
|
2026-01-29 14:28:23 +00:00
|
|
|
|
|
|
|
|
func TestImageManager_CheckUpdate_Bad_VersionError(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
mock := &mockImageSource{
|
|
|
|
|
name: "mock",
|
|
|
|
|
available: true,
|
|
|
|
|
latestErr: assert.AnError,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mgr := &ImageManager{
|
|
|
|
|
config: DefaultConfig(),
|
|
|
|
|
manifest: &Manifest{
|
|
|
|
|
Images: map[string]ImageInfo{
|
|
|
|
|
ImageName(): {Version: "v1.0.0", Source: "mock"},
|
|
|
|
|
},
|
|
|
|
|
path: filepath.Join(tmpDir, "manifest.json"),
|
|
|
|
|
},
|
|
|
|
|
sources: []sources.ImageSource{mock},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current, _, _, err := mgr.CheckUpdate(context.Background())
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
assert.Equal(t, "v1.0.0", current) // Current should still be returned
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestImageManager_Install_Bad_EmptySources(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
mgr := &ImageManager{
|
|
|
|
|
config: DefaultConfig(),
|
|
|
|
|
manifest: &Manifest{Images: make(map[string]ImageInfo), path: filepath.Join(tmpDir, "manifest.json")},
|
|
|
|
|
sources: []sources.ImageSource{}, // Empty slice, not nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := mgr.Install(context.Background(), nil)
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
assert.Contains(t, err.Error(), "no image source available")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestImageManager_Install_Bad_AllUnavailable(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
mock1 := &mockImageSource{name: "mock1", available: false}
|
|
|
|
|
mock2 := &mockImageSource{name: "mock2", available: false}
|
|
|
|
|
|
|
|
|
|
mgr := &ImageManager{
|
|
|
|
|
config: DefaultConfig(),
|
|
|
|
|
manifest: &Manifest{Images: make(map[string]ImageInfo), path: filepath.Join(tmpDir, "manifest.json")},
|
|
|
|
|
sources: []sources.ImageSource{mock1, mock2},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := mgr.Install(context.Background(), nil)
|
|
|
|
|
assert.Error(t, err)
|
|
|
|
|
assert.Contains(t, err.Error(), "no image source available")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestImageManager_CheckUpdate_Good_FirstSourceUnavailable(t *testing.T) {
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
|
t.Setenv("CORE_IMAGES_DIR", tmpDir)
|
|
|
|
|
|
|
|
|
|
unavailable := &mockImageSource{name: "unavailable", available: false}
|
|
|
|
|
available := &mockImageSource{name: "available", available: true, latestVersion: "v2.0.0"}
|
|
|
|
|
|
|
|
|
|
mgr := &ImageManager{
|
|
|
|
|
config: DefaultConfig(),
|
|
|
|
|
manifest: &Manifest{
|
|
|
|
|
Images: map[string]ImageInfo{
|
|
|
|
|
ImageName(): {Version: "v1.0.0", Source: "available"},
|
|
|
|
|
},
|
|
|
|
|
path: filepath.Join(tmpDir, "manifest.json"),
|
|
|
|
|
},
|
|
|
|
|
sources: []sources.ImageSource{unavailable, available},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current, latest, hasUpdate, err := mgr.CheckUpdate(context.Background())
|
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
assert.Equal(t, "v1.0.0", current)
|
|
|
|
|
assert.Equal(t, "v2.0.0", latest)
|
|
|
|
|
assert.True(t, hasUpdate)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestManifest_Struct(t *testing.T) {
|
|
|
|
|
m := &Manifest{
|
|
|
|
|
Images: map[string]ImageInfo{
|
|
|
|
|
"test.img": {Version: "1.0.0"},
|
|
|
|
|
},
|
|
|
|
|
path: "/path/to/manifest.json",
|
|
|
|
|
}
|
|
|
|
|
assert.Equal(t, "/path/to/manifest.json", m.path)
|
|
|
|
|
assert.Len(t, m.Images, 1)
|
|
|
|
|
assert.Equal(t, "1.0.0", m.Images["test.img"].Version)
|
feat: git command, build improvements, and go fmt git-aware (#74)
* feat(go): make go fmt git-aware by default
- By default, only check changed Go files (modified, staged, untracked)
- Add --all flag to check all files (previous behaviour)
- Reduces noise when running fmt on large codebases
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(build): minimal output by default, add missing i18n
- Default output now shows single line: "Success Built N artifacts (dir)"
- Add --verbose/-v flag to show full detailed output
- Add all missing i18n translations for build commands
- Errors still show failure reason in minimal mode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add root-level `core git` command
- Create pkg/gitcmd with git workflow commands as root menu
- Export command builders from pkg/dev (AddCommitCommand, etc.)
- Commands available under both `core git` and `core dev` for compatibility
- Git commands: health, commit, push, pull, work, sync, apply
- GitHub orchestration stays in dev: issues, reviews, ci, impact
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(qa): add docblock coverage checking
Implement docblock/docstring coverage analysis for Go code:
- New `core qa docblock` command to check coverage
- Shows compact file:line list when under threshold
- Integrate with `core go qa` as a default check
- Add --docblock-threshold flag (default 80%)
The checker uses Go AST parsing to find exported symbols
(functions, types, consts, vars) without documentation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- Fix doc comment: "status" → "health" in gitcmd package
- Implement --check flag for `core go fmt` (exits non-zero if files need formatting)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: add docstrings for 100% coverage
Add documentation comments to all exported symbols:
- pkg/build: ProjectType constants
- pkg/cli: LogLevel, RenderStyle, TableStyle
- pkg/framework: ServiceFor, MustServiceFor, Core.Core
- pkg/git: GitError.Error, GitError.Unwrap
- pkg/i18n: Handler Match/Handle methods
- pkg/log: Level constants
- pkg/mcp: Tool input/output types
- pkg/php: Service constants, QA types, service methods
- pkg/process: ServiceError.Error
- pkg/repos: RepoType constants
- pkg/setup: ChangeType, ChangeCategory constants
- pkg/workspace: AddWorkspaceCommands
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: standardize line endings to LF
Add .gitattributes to enforce LF line endings for all text files.
Normalize all existing files to use Unix-style line endings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback
- cmd_format.go: validate --check/--fix mutual exclusivity, capture stderr
- cmd_docblock.go: return error instead of os.Exit(1) for proper error handling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: address CodeRabbit review feedback (round 2)
- linuxkit.go: propagate state update errors, handle cmd.Wait() errors in waitForExit
- mcp.go: guard against empty old_string in editDiff to prevent runaway edits
- cmd_docblock.go: log parse errors instead of silently skipping
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 10:48:44 +00:00
|
|
|
}
|