- first boilerplate generator implementation
- create e2e boilerplate.md Go template
- parametrize: title, solution subtitle and link
- load docs.tmpl file
- store file to path
- store generated boilerplate docs into correct folders
- create directories (if they don't exist)
- take three inputs: pattern, difficulty, title
- generate, then store
- create directories (if they don't exist)
- execute from cmd i.e. get inputs from cli
- refactoring
- WHAT YOU DID:
- command line args parsing and validation
- e2e creation of a sample in a temp dir:
go run . create arrays easy "Missing Number" - deletion of sample:
go run . delete arrays easy "Missing Number" - create Generator
- setup config data: target dir, template location, exercise metadata from args processing
- init generator with config data
- execute e2e generation
- move args parsing, exercise struct and validation to generator
- rename generator package to boilerplate
- refactor e2e test and design => make testable
- extracted metadata
- added validating "decorator" metadata
- moved args parsing to main, removed args.go
- WHAT YOU DID:
- Elegant Objects version
- WHAT YOU DID
- implementing new idea from Elegant Objects
- add
package generatorwithBoilerplatestruct andStrValuemethod so you can use it as:docs := NewBoilerplate(tmpl, "Missing Number"); docs.StrValue()- it represents a boilerplate file which knows how to generate itself => doesn't feel right
- add second implementation in
eoBoilerplate.go- implemented the structure from below using an interface for the Filesystem => we're getting there
- 22.03.25
- implement the FS so that you can test the EO version => works
- add DocsFile interface to use Content
- add docFilePath and smallKebab methods to DocsBoilerplate => doesn't feel right
- create
eoDocs.goentrypoint for manual testing => works
- 27.04.25
- understand eo implementation => not easy after a month
- next time read through the example code below
- go from EoDocsCreate object by object
- the boilerplate can save itself to provided Store and delete itself
- the store is implemented by the filesystem
- a common DocsFile interface is implemented by Boilerplate and Template so they can interact internally
- actual data is provided by DocsTemplateData and put into the Template by the Boilerplate
- add
Delete(fs filesystem)method to DocsBoilerplate - implement integration tests for Create and Delete
- understand eo implementation => not easy after a month
- 28.04.15
- fix ci test
- refactor docsFilePath and smallKebab
- CLI: reads command, pattern, difficulty and title from command line user input => separate package, no connection to DocsBoilerplate
- filesystem creates directory chain if needed
- create
Requestobject which contains everything the Boilerplate needs
- add
- chore: switch git setting repo to ssh
- implementing new idea from Elegant Objects
- NEXT:
- CONTINUE HERE: read what you did on 27.04.25, THEN: have something e2e and then refactor and try other implementations like from James Shore, Hexagonal Architecture, procedural etc.
- Whats left for E2E execution?
- implement
*-solution.mdboilerplate generation - generate both concurrently, use go go routines
-
Patternobject (like App/Entrypoint) which centralize the creation of all the boilerplate for one pattern- uses DocsBoilerplate
- uses CLI
- move filesystem to infrastructure
- create Nullable StubbedCli
- use polymorphism for Save/Delete
- tests for Save and Delete using Nullable filesystem
- implement
- can I use accessor functions w/o get? not sure tmpl.Execute accepts
- clean up main
- clarify what was this task: "exercise directory deletion => no test"
- idea: create Generator struct with ?Process(request) and ?Execute() methods
- WHAT YOU DID
This is procedural thinking:
- receive config info with:
- where is template, where to save boilerplate
- data for template parameters
- load template from disk
- replace template parameters with data which results in the boilerplate
- store boilerplate to disk
Is this living objects thinking?:
- The boilerplate docs file stores itself
- it wraps a template file
- which provides its content
- knows how to load itself
- it wraps a config to know where to store itself
- it wraps data which is used to populate the template
- it wraps a template file
Elegant Objects inspired prototype:
type Filesystem interface {
Load(from string) (string, error)
Save(data, to string) error
}
filesystem := Filesystem()
config := Config()
OnDiskFile( // StoredFile
config, // config.To
DocsBoilerplate(
InMemoryFile(config, filesystem), // config.From, LoadedFile
DocsTemplateData( /* ??? */),
),
).Save(filesystem)WHAT YOU DID
- 24.03.25
- add tests to assert package
- make FirstDimensionLengthEqual testable
- add first positive test
- add tests to assert package
CONTINUE HERE
- add tests to assert package
- add negative FirstDimensionLengthEqual test
- make other assert functions testable
- refactor FirstDimensionLengthEqual to assert all dimensions; update tests
- assert package: provide 'name' instead of input
WHAT YOU DID
- add Dockerfile => the image is large => you can run tests there
- run all tests in container using the Dockerfile
- you added a dsa-pod.yaml and you can deploy it in kind using
ko=> just executes main and prints the temp message - added a test-pod.yaml with command to run tests but it crashes => looks like
koimages are not supposed to run tests
CONTINUE HERE
- add pre-commit or pre-push hook to run CI
- remove tools installation in Pipeline use existing GitHub action
- use Copilot to build strong CI/CD
- setup.sh script
- add Makefile
- add golangci-lint with configuration
- add Github Actions CI/verify pipeline
- maybe testcontainers/devcontainers
- do the docker.com tutorial on Go images, multistage builds and kubernetes deployments here
- decide what to do: create an ephemeral pod to run tests in or stay with pure docker
- configure yaml extension => its not recognizing kubernetes manifests
- run CI on every push to master - see fabric samples
- add refactoring section with first sample
- practice theatrical sample
- page 14: Extracting Volume Credits
- add non refactored version
- resolve ci issues
- page 25: Splitting the Phases of Calculation and Formatting
- page 28: move amountFor and replace
- page 36: Creating a Performance Calculator
- page 39: at the top, polymorphic calculator
- page 34 at the end: add tests that probe the intermediate data structure
- practice retention => retained