Step 1: Replace C++ prototype with Go project scaffolding.

Remove all old C++ source files, proto definitions, CMake build,
clang configs, IDE files, and Trunk linter config. Initialize Go
module (github.com/kisom/sgard) with cobra and yaml.v3 deps.
Set up cobra root command with --repo persistent flag.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-23 21:19:37 -07:00
parent b678ce572a
commit 6cadda01a8
23 changed files with 71 additions and 420 deletions

View File

@@ -1,67 +0,0 @@
# Generated from CLion C/C++ Code Style settings
BasedOnStyle: LLVM
AccessModifierOffset: -8
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: Consecutive
AlignOperands: Align
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Always
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterReturnType: TopLevel
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: true
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
ColumnLimit: 0
CompactNamespaces: false
ContinuationIndentWidth: 4
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 8
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
QualifierAlignment: Left
PointerAlignment: Right
ReflowComments: false
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 0
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 8
UseTab: ForContinuationAndIndentation

View File

@@ -1,31 +0,0 @@
Checks: >-
bugprone-*,
cppcoreguidelines-*,
google-*,
misc-*,
modernize-*,
performance-*,
readability-*,
-bugprone-lambda-function-name,
-bugprone-easily-swappable-parameters,
-bugprone-reserved-identifier,
-cppcoreguidelines-avoid-goto,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-avoid-non-const-global-variables,
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
-cppcoreguidelines-pro-type-vararg,
-google-readability-braces-around-statements,
-google-readability-function-size,
-misc-no-recursion,
-modernize-return-braced-init-list,
-modernize-use-nodiscard,
-modernize-use-trailing-return-type,
-performance-unnecessary-value-param,
-readability-identifier-length,
-readability-magic-numbers
CheckOptions:
readability-function-cognitive-complexity.Threshold: 100
readability-function-cognitive-complexity.IgnoreMacros: true
readability-identifier-naming.ClassCase: CamelCase

6
.gitignore vendored
View File

@@ -1,5 +1 @@
*.o
build
cmake-build-*
sgard
/sgard

8
.idea/.gitignore generated vendored
View File

@@ -1,8 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

4
.idea/misc.xml generated
View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
</project>

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/sgard.iml" filepath="$PROJECT_DIR$/.idea/sgard.iml" />
</modules>
</component>
</project>

2
.idea/sgard.iml generated
View File

@@ -1,2 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="CMake" type="CPP_MODULE" version="4" />

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

8
.trunk/.gitignore vendored
View File

@@ -1,8 +0,0 @@
*out
*logs
*actions
*notifications
*tools
plugins
user_trunk.yaml
user.yaml

View File

@@ -1,7 +0,0 @@
enable=all
source-path=SCRIPTDIR
disable=SC2154
# If you're having issues with shellcheck following source, disable the errors via:
# disable=SC1090
# disable=SC1091

View File

@@ -1,10 +0,0 @@
rules:
quoted-strings:
required: only-when-needed
extra-allowed: ["{|}"]
empty-values:
forbid-in-block-mappings: true
forbid-in-flow-mappings: true
key-duplicates: {}
octal-values:
forbid-implicit-octal: true

View File

@@ -1,34 +0,0 @@
# This file controls the behavior of Trunk: https://docs.trunk.io/cli
# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml
version: 0.1
cli:
version: 1.17.1
plugins:
sources:
- id: trunk
ref: v1.2.6
uri: https://github.com/trunk-io/plugins
runtimes:
enabled:
- go@1.21.0
- node@18.12.1
- python@3.10.8
lint:
enabled:
- checkov@2.5.9
- clang-format@16.0.3
- clang-tidy@16.0.3
- git-diff-check
- prettier@3.0.3
- shellcheck@0.9.0
- shfmt@3.6.0
- trivy@0.46.0
- trufflehog@3.60.0
- yamllint@1.32.0
actions:
disabled:
- trunk-announce
- trunk-check-pre-push
- trunk-fmt-pre-commit
enabled:
- trunk-upgrade-available

View File

@@ -1,38 +0,0 @@
cmake_minimum_required(VERSION 3.22)
project(sgard VERSION 0.0.1
LANGUAGES CXX
DESCRIPTION "Shimmer Clarity Gardener: A dot-files manager.")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_VERBOSE_MAKEFILES TRUE)
find_package(Protobuf REQUIRED)
find_package(scsl REQUIRED)
file(GLOB ProtoFiles "${CMAKE_CURRENT_SOURCE_DIR}/proto/*.proto")
PROTOBUF_GENERATE_CPP(ProtoSources ProtoHeaders ${ProtoFiles})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
include_directories(${SCSL_INCLUDE_DIRS})
add_library(protolib STATIC ${ProtoSources} ${ProtoHeaders})
target_link_libraries(protolib INTERFACE ${Protobuf_LIBRARIES})
add_compile_options(
"-static"
"-Werror" "-Wextra" "-Wall"
"-Weffc++"
)
if (CMAKE_BUILD_TYPE STREQUAL Debug)
add_compile_options("-g" "-fsanitize=address")
endif ()
set(HEADER_FILES
)
set(SOURCE_FILES sgard.cc)
add_executable(sgard ${SOURCE_FILES})
target_link_libraries(sgard protolib ${SCSL_LIBRARIES})

View File

@@ -7,22 +7,24 @@ ARCHITECTURE.md for design details.
## Current Status
**Phase:** Pre-implementation — design complete, ready to begin Step 1.
**Phase:** Step 1 complete. Ready for Steps 2 & 3 (can be parallel).
**Last updated:** 2026-03-23
## Completed Steps
(none yet)
- **Step 1: Project Scaffolding** — removed old C++ files and `.trunk/` config,
initialized Go module, added cobra + yaml.v3 deps, created package dirs,
set up cobra root command with `--repo` flag.
## In Progress
(none yet)
(none)
## Up Next
Step 1: Project Scaffolding — remove old C++ files, initialize Go module,
create directory structure, set up cobra root command.
Step 2 (Manifest Package) and Step 3 (Store Package) — these can be done
in parallel.
## Known Issues / Decisions Deferred
@@ -36,3 +38,4 @@ create directory structure, set up cobra root command.
| Date | Step | Summary |
|---|---|---|
| 2026-03-23 | — | Design phase complete. ARCHITECTURE.md and PROJECT_PLAN.md written. |
| 2026-03-23 | 1 | Scaffolding complete. Old C++ removed, Go module initialized, cobra root command. |

View File

@@ -6,13 +6,13 @@ Implementation plan for sgard. See ARCHITECTURE.md for design details.
Remove old C++ source files and set up the Go project.
- [ ] Remove old files: `sgard.cc`, `proto/`, `CMakeLists.txt`, `scripts/`, `.clang-format`, `.clang-tidy`, `.idea/`
- [ ] `go mod init github.com/kisom/sgard`
- [ ] Add dependencies: `gopkg.in/yaml.v3`, `github.com/spf13/cobra`
- [ ] Create directory structure: `cmd/sgard/`, `manifest/`, `store/`, `garden/`
- [ ] Set up `cmd/sgard/main.go` with cobra root command and `--repo` persistent flag
- [ ] Update CLAUDE.md to reflect Go project
- [ ] Verify: `go build ./...` compiles clean
- [x] Remove old files: `sgard.cc`, `proto/`, `CMakeLists.txt`, `scripts/`, `.clang-format`, `.clang-tidy`, `.idea/`, `.trunk/`
- [x] `go mod init github.com/kisom/sgard`
- [x] Add dependencies: `gopkg.in/yaml.v3`, `github.com/spf13/cobra`
- [x] Create directory structure: `cmd/sgard/`, `manifest/`, `store/`, `garden/`
- [x] Set up `cmd/sgard/main.go` with cobra root command and `--repo` persistent flag
- [x] Update CLAUDE.md to reflect Go project
- [x] Verify: `go build ./...` compiles clean
## Step 2: Manifest Package

33
cmd/sgard/main.go Normal file
View File

@@ -0,0 +1,33 @@
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/spf13/cobra"
)
var repoFlag string
var rootCmd = &cobra.Command{
Use: "sgard",
Short: "Shimmering Clarity Gardener: dotfile management",
}
func defaultRepo() string {
home, err := os.UserHomeDir()
if err != nil {
return ".sgard"
}
return filepath.Join(home, ".sgard")
}
func main() {
rootCmd.PersistentFlags().StringVar(&repoFlag, "repo", defaultRepo(), "path to sgard repository")
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}

10
go.mod Normal file
View File

@@ -0,0 +1,10 @@
module github.com/kisom/sgard
go 1.25.7
require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/cobra v1.10.2 // indirect
github.com/spf13/pflag v1.0.9 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

12
go.sum Normal file
View File

@@ -0,0 +1,12 @@
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -1,12 +0,0 @@
syntax = 'proto3';
package sgardpb;
import "google/protobuf/timestamp.proto";
// Header defines common metadata for messages in sgard.
message Header
{
uint32 version = 1;
google.protobuf.Timestamp created = 2;
google.protobuf.Timestamp updated = 3;
}

View File

@@ -1,12 +0,0 @@
syntax = 'proto3';
package sgardpb;
import 'header.proto';
import 'path.proto';
message HomeDir
{
Header header = 1;
map<string, Source> files = 5;
};

View File

@@ -1,33 +0,0 @@
syntax = 'proto3';
package sgardpb;
import 'header.proto';
import "google/protobuf/timestamp.proto";
enum PathType {
PATHTYPE_UNSPECIFIED = 0;
PATHTYPE_FILE = 1;
PATHTYPE_DIRECTORY = 2;
PATHTYPE_LINK = 3;
};
message FilePath
{
Header header = 1;
string source_path = 2;
string dest_path = 3;
// todo: add mode, action (e.g. copy vs link)
};
message Source
{
Header header = 1;
PathType path_type = 2;
oneof path
{
FilePath file = 5;
};
};

View File

@@ -1,98 +0,0 @@
#!/usr/bin/env bash
#####################################################################
# This script attempts to install the appopriate build dependencies #
# for the host system. #
# #
# For platforms marked as unverified, it means that I was able to #
# start a Docker container for that platform and could look up the #
# right package names. I haven't actually tried building on these #
# platforms. #
# #
# This is primarily developed on the latest Ubuntu LTS release and #
# MacOS; other platforms are best-effort. #
#####################################################################
set -eu
install_debianesque() {
echo "[+] distribution is ${DISTRIB_ID}, choosing Debianesque install."
echo "[+] installing tools"
sudo apt-get install git cmake clang scdoc
echo "[+] installing protobuf libraries and development headers"
sudo apt-get install protobuf-compiler libprotobuf-dev
echo "[+] installing gRPC libraries and development headers"
sudo apt-get install protobuf-compiler-grpc grpc-proto libgrpc++-dev
}
install_redhat() {
echo "[+] distribution is ${DISTRIB_ID}, choosing Redhat install."
echo "[!] WARNING: installation for Redhat systems is unverified."
echo "[+] installing tools"
sudo dnf install git cmake clang scdoc
echo "[+] installing libraries and development headers"
sudo dnf install protobuf-compiler libprotobuf-dev
}
install_alpine() {
echo "[+] distribution is ${DISTRIB_ID}, choosing Alpine install."
echo "[!] WARNING: installation for Alpine systems is unverified."
echo "[+] installing tools"
sudo dnf install git cmake clang scdoc
echo "[+] installing libraries and development headers"
sudo dnf install sdl2-dev freetype-dev protobuf-compiler-grpc
}
install_macos() {
# TODO: consider supporting macports?
echo "[+] host system is MacOS"
echo "[+] installing tools"
brew install git cmake scdoc
echo "[+] installing libraries and development headers"
# TODO: look up proper package names in homebrew
}
install_linux() {
echo "[+] host system is Linux"
[[ -f "/etc/lsb-release" ]] && source /etc/lsb-release
if [ -z "${DISTRIB_ID}" ]; then
if [ -d /etc/apt ]; then
DISTRIB_ID="apt-based"
elif [ -f /etc/alpine-release ]; then
DISTRIB_ID=Alpine
elif [ -d /etc/dnf -o /etc/yum.repos.d ]; then
# I don't use Fedora, this is based on a cursory
# glance at the filesystem on a Docker image.
DISTRIB_ID="Fedora"
fi
fi
case ${DISTRIB_ID} in
Ubuntu) install_debianesque ;;
Debian) install_debianesque ;;
apt-based) install_debianesque ;;
Fedora) install_redhat ;;
Alpine) install_alpine ;;
*)
echo "[!] distribution ${DISTRIB_ID} isn't supported in this script." >/dev/null
;;
esac
}
case "$(uname -s)" in
Linux) install_linux ;;
Darwin) install_macos ;;
*)
echo "[!] platform $(uname -s) isn't supported in this script." >/dev/null
;;
esac

View File

@@ -1,25 +0,0 @@
///
/// \file sgard.cc
/// \author K. Isom <kyle@imap.cc>
/// \date 2023-10-17
/// \brief Shimmering Clarity Gardener: dot-file management.
///
#include <iostream>
#include <scsl/Flags.h>
int
main(int argc, char *argv[])
{
auto flag = new scsl::Flags("sgard", "Shimmering Clarity Gardener: dot-file management");
auto parseResult = flag->Parse(argc, argv);
if (parseResult != scsl::Flags::ParseStatus::OK) {
std::cerr << "failed to parse flags: "
<< scsl::Flags::ParseStatusToString(parseResult)
<< "\n";
flag->Usage(std::cerr, 1);
}
}