104 lines
3.1 KiB
Go
104 lines
3.1 KiB
Go
package configkit
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
|
|
"gitea.maximumdirect.net/eric/ConfigKit/internal/engine"
|
|
)
|
|
|
|
// SecretFileStatus describes the outcome for one file considered by
|
|
// LoadSecretsDir.
|
|
type SecretFileStatus string
|
|
|
|
const (
|
|
SecretFileLoaded SecretFileStatus = "loaded"
|
|
SecretFileSkippedExisting SecretFileStatus = "skipped_existing"
|
|
SecretFileNotApplied SecretFileStatus = "not_applied"
|
|
SecretFileFailed SecretFileStatus = "failed"
|
|
)
|
|
|
|
// SecretFileResult is the safe, value-free bootstrap result for one directory
|
|
// entry. ExistingEmpty is meaningful when Status is SecretFileSkippedExisting.
|
|
type SecretFileResult struct {
|
|
Name string
|
|
Path string
|
|
Status SecretFileStatus
|
|
ExistingEmpty bool
|
|
}
|
|
|
|
// SecretsReport is a detached snapshot of an explicit secrets-directory
|
|
// bootstrap. It does not retain file contents or environment values.
|
|
type SecretsReport struct{ value *engine.SecretsReport }
|
|
|
|
// Entries returns a copy of the report's filename-ordered entries.
|
|
func (r *SecretsReport) Entries() []SecretFileResult {
|
|
if r == nil || r.value == nil {
|
|
return nil
|
|
}
|
|
values := r.value.Entries()
|
|
if values == nil {
|
|
return nil
|
|
}
|
|
result := make([]SecretFileResult, len(values))
|
|
for index := range values {
|
|
result[index] = fromEngineSecretFileResult(values[index])
|
|
}
|
|
return result
|
|
}
|
|
|
|
// WriteTo renders one safe, deterministic line per entry. Names and paths are
|
|
// quoted so control characters cannot affect terminal output.
|
|
func (r *SecretsReport) WriteTo(output io.Writer) (int64, error) {
|
|
if r == nil || r.value == nil {
|
|
return (*engine.SecretsReport)(nil).WriteTo(output)
|
|
}
|
|
return r.value.WriteTo(output)
|
|
}
|
|
|
|
// SecretsError reports safe structured diagnostics for a failed explicit
|
|
// secrets-directory bootstrap. It intentionally does not unwrap filesystem or
|
|
// environment errors.
|
|
type SecretsError struct{ value *engine.SecretsError }
|
|
|
|
// Error implements error without rendering filenames, paths, or file contents.
|
|
func (e *SecretsError) Error() string {
|
|
if e == nil || e.value == nil {
|
|
return "configkit: secrets bootstrap failed"
|
|
}
|
|
return e.value.Error()
|
|
}
|
|
|
|
// Diagnostics returns a deep copy of the bootstrap diagnostics.
|
|
func (e *SecretsError) Diagnostics() []Diagnostic {
|
|
if e == nil || e.value == nil {
|
|
return nil
|
|
}
|
|
values := e.value.Diagnostics()
|
|
if values == nil {
|
|
return nil
|
|
}
|
|
result := make([]Diagnostic, len(values))
|
|
for index := range values {
|
|
result[index] = fromEngineDiagnostic(values[index])
|
|
}
|
|
return result
|
|
}
|
|
|
|
// LoadSecretsDir explicitly loads immediate regular files from directory into
|
|
// previously unset process environment variables. Applications should call it
|
|
// once during startup, before concurrent work; Load never calls it.
|
|
// Dot-prefixed entries are ignored and omitted from the report.
|
|
func LoadSecretsDir(directory string) (*SecretsReport, error) {
|
|
report, err := engine.LoadSecretsDir(directory)
|
|
result := &SecretsReport{value: report}
|
|
if err == nil {
|
|
return result, nil
|
|
}
|
|
var secretsError *engine.SecretsError
|
|
if errors.As(err, &secretsError) {
|
|
return result, &SecretsError{value: secretsError}
|
|
}
|
|
return result, &SecretsError{}
|
|
}
|