Compare commits

..

3 commits

Author SHA1 Message Date
Claude
5874fd3e77
ci: add Forgejo Actions test and security scan workflows
Some checks failed
Security Scan / security (push) Failing after 14s
Test / test (push) Successful in 4m51s
Uses reusable workflows from core/go-devops for Go testing
(with race detector and coverage) and security scanning
(govulncheck, gitleaks, trivy).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 03:28:30 +00:00
Claude
1a0db9bb2a
chore: sync workspace dependency versions
Some checks failed
Go / build (push) Failing after 2s
Publish Docs / build (push) Failing after 6s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 22:04:45 +00:00
Claude
c8531fa66b
chore: migrate module path from github.com to forge.lthn.ai
Some checks failed
Go / build (push) Failing after 27s
Publish Docs / build (push) Failing after 1m0s
Move module declaration and all internal imports from
github.com/Snider/Enchantrix to forge.lthn.ai/Snider/Enchantrix.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 21:34:26 +00:00
25 changed files with 76 additions and 426 deletions

View file

@ -0,0 +1,12 @@
name: Security Scan
on:
push:
branches: [main, dev, 'feat/*']
pull_request:
branches: [main]
jobs:
security:
uses: core/go-devops/.forgejo/workflows/security-scan.yml@main
secrets: inherit

View file

@ -0,0 +1,14 @@
name: Test
on:
push:
branches: [main, dev]
pull_request:
branches: [main]
jobs:
test:
uses: core/go-devops/.forgejo/workflows/go-test.yml@main
with:
race: true
coverage: true

View file

@ -1,376 +0,0 @@
# Code Complexity and Maintainability Audit
This document outlines the findings of a code complexity and maintainability audit of the Enchantrix project.
## Methodology
The audit was conducted by analyzing the Go source code for the following:
* **Cyclomatic Complexity:** Functions with high complexity.
* **Cognitive Complexity:** Code that is difficult to understand.
* **Code Duplication:** Violations of the DRY (Don't Repeat Yourself) principle.
* **Maintainability Issues:** Long methods, large classes, deep nesting, long parameter lists, dead code, and commented-out code.
* **Code Smells:** Common indicators of deeper design problems.
## Findings
The findings are prioritized by their potential impact on the maintenance burden.
---
## 1. Code Duplication in `cmd/trix/main.go`
**Finding:** The functions `handleEncode`, `handleDecode`, `handleHash`, and `handleSigil` contain duplicated code for reading input from either a file or stdin. This violates the Don't Repeat Yourself (DRY) principle and makes the code harder to maintain.
**Example of Duplicated Code:**
```go
// From handleEncode
var data []byte
var err error
if inputFile == "" || inputFile == "-" {
data, err = ioutil.ReadAll(cmd.InOrStdin())
} else {
data, err = ioutil.ReadFile(inputFile)
}
if err != nil {
return err
}
// From handleDecode
var data []byte
var err error
if inputFile == "" || inputFile == "-" {
data, err = ioutil.ReadAll(cmd.InOrStdin())
} else {
data, err = ioutil.ReadFile(inputFile)
}
if err != nil {
return err
}
```
**Recommendation:** Abstract the input reading logic into a single helper function.
**Refactoring Approach:** Create a new function, `readInput`, that centralizes the logic for reading from a file or stdin.
**Proposed `readInput` function:**
```go
func readInput(cmd *cobra.Command, inputFile string) ([]byte, error) {
if inputFile == "" || inputFile == "-" {
return ioutil.ReadAll(cmd.InOrStdin())
}
return ioutil.ReadFile(inputFile)
}
```
**Refactored `handleEncode` function:**
```go
func handleEncode(cmd *cobra.Command, inputFile, outputFile, magicNumber string, sigils []string) error {
if len(magicNumber) != 4 {
return fmt.Errorf("magic number must be 4 bytes long")
}
data, err := readInput(cmd, inputFile)
if err != nil {
return err
}
t := &trix.Trix{
Header: make(map[string]interface{}),
Payload: data,
InSigils: sigils,
}
if err := t.Pack(); err != nil {
return err
}
encoded, err := trix.Encode(t, magicNumber, nil)
if err != nil {
return err
}
if outputFile == "" || outputFile == "-" {
_, err = cmd.OutOrStdout().Write(encoded)
return err
}
return ioutil.WriteFile(outputFile, encoded, 0644)
}
```
## 2. Long Methods in `pkg/trix/trix.go`
**Finding:** The `Encode` and `Decode` functions in `pkg/trix/trix.go` are both long methods that handle multiple responsibilities. This increases their cognitive complexity and makes them harder to test and maintain.
**`Encode` function responsibilities:**
* Validating the magic number.
* Calculating and adding a checksum.
* Serializing the header to JSON.
* Writing the magic number, version, header length, header, and payload to a writer.
**`Decode` function responsibilities:**
* Validating the magic number.
* Reading and verifying the magic number and version.
* Reading and validating the header length.
* Deserializing the header from JSON.
* Reading the payload.
* Verifying the checksum.
**Recommendation:** Decompose these methods into smaller, private helper functions, each with a single responsibility.
**Refactoring Approach (`Encode`):**
Create helper functions for handling the checksum and writing the components of the `.trix` file.
**Proposed Helper Functions for `Encode`:**
```go
func (t *Trix) addChecksum() {
if t.ChecksumAlgo != "" {
checksum := crypt.NewService().Hash(t.ChecksumAlgo, string(t.Payload))
t.Header["checksum"] = checksum
t.Header["checksum_algo"] = string(t.ChecksumAlgo)
}
}
func writeTrixComponents(w io.Writer, magicNumber string, headerBytes, payload []byte) error {
if _, err := io.WriteString(w, magicNumber); err != nil {
return err
}
if _, err := w.Write([]byte{byte(Version)}); err != nil {
return err
}
if err := binary.Write(w, binary.BigEndian, uint32(len(headerBytes))); err != nil {
return err
}
if _, err := w.Write(headerBytes); err != nil {
return err
}
if _, err := w.Write(payload); err != nil {
return err
}
return nil
}
```
**Refactored `Encode` function:**
```go
func Encode(trix *Trix, magicNumber string, w io.Writer) ([]byte, error) {
if len(magicNumber) != 4 {
return nil, ErrMagicNumberLength
}
trix.addChecksum()
headerBytes, err := json.Marshal(trix.Header)
if err != nil {
return nil, err
}
var buf *bytes.Buffer
writer := w
if writer == nil {
buf = new(bytes.Buffer)
writer = buf
}
if err := writeTrixComponents(writer, magicNumber, headerBytes, trix.Payload); err != nil {
return nil, err
}
if buf != nil {
return buf.Bytes(), nil
}
return nil, nil
}
```
## 3. Cognitive Complexity in `pkg/crypt/crypt.go`
**Finding:** The `Hash` function in `pkg/crypt/crypt.go` uses a `switch` statement to select the hashing algorithm. While this works for a small number of algorithms, it has a few drawbacks:
* **High Maintenance:** Adding a new hashing algorithm requires modifying this function.
* **Increased Complexity:** As more algorithms are added, the `switch` statement will grow, increasing the function's cognitive complexity.
* **Open/Closed Principle Violation:** The function is not closed for modification.
**`Hash` function `switch` statement:**
```go
func (s *Service) Hash(lib HashType, payload string) string {
switch lib {
case LTHN:
return lthn.Hash(payload)
case SHA512:
hash := sha512.Sum512([]byte(payload))
return hex.EncodeToString(hash[:])
case SHA1:
hash := sha1.Sum([]byte(payload))
return hex.EncodeToString(hash[:])
case MD5:
hash := md5.Sum([]byte(payload))
return hex.EncodeToString(hash[:])
case SHA256:
fallthrough
default:
hash := sha256.Sum256([]byte(payload))
return hex.EncodeToString(hash[:])
}
}
```
**Recommendation:** Apply the Strategy design pattern by using a map to store the hashing functions. This will make the `Hash` function more extensible and easier to maintain.
**Refactoring Approach:**
1. Create a type for the hashing functions.
2. Create a map to store the hashing functions, keyed by the `HashType`.
3. In the `NewService` function, initialize the map with the available hashing algorithms.
4. In the `Hash` function, look up the hashing function in the map and execute it.
**Proposed Refactoring:**
```go
// In the Service struct
type hashFunc func(string) string
type Service struct {
rsa *rsa.Service
pgp *pgp.Service
hashAlgos map[HashType]hashFunc
}
// In the NewService function
func NewService() *Service {
s := &Service{
rsa: rsa.NewService(),
pgp: pgp.NewService(),
}
s.hashAlgos = map[HashType]hashFunc{
LTHN: lthn.Hash,
SHA512: func(p string) string { h := sha512.Sum512([]byte(p)); return hex.EncodeToString(h[:]) },
SHA256: func(p string) string { h := sha256.Sum256([]byte(p)); return hex.EncodeToString(h[:]) },
SHA1: func(p string) string { h := sha1.Sum([]byte(p)); return hex.EncodeToString(h[:]) },
MD5: func(p string) string { h := md5.Sum([]byte(p)); return hex.EncodeToString(h[:]) },
}
return s
}
// Refactored Hash function
func (s *Service) Hash(lib HashType, payload string) string {
if f, ok := s.hashAlgos[lib]; ok {
return f(payload)
}
// Default to SHA256 if the algorithm is not found
return s.hashAlgos[SHA256](payload)
}
```
## 4. Encapsulation Issues in `pkg/crypt/std/lthn/lthn.go`
**Finding:** The `lthn` package uses a global `keyMap` variable for character substitutions. This variable can be modified at runtime using the `SetKeyMap` function, creating a package-level state that is shared across all callers. This design has several drawbacks:
* **Concurrency Unsafe:** If multiple goroutines use the `lthn` package concurrently, a call to `SetKeyMap` in one goroutine will affect the hashing results in all others, leading to race conditions and unpredictable behavior.
* **Difficult to Test:** Tests that need to modify the `keyMap` must use mutexes and cleanup functions to avoid interfering with other tests running in parallel.
* **Poor Encapsulation:** The hashing logic is not self-contained. Its behavior depends on a hidden, global dependency (`keyMap`), which makes the code harder to reason about.
**Code Exhibiting the Issue:**
```go
var keyMap = map[rune]rune{
// ... default mappings
}
func SetKeyMap(newKeyMap map[rune]rune) {
keyMap = newKeyMap
}
func Hash(input string) string {
salt := createSalt(input) // Uses the global keyMap
hash := sha256.Sum256([]byte(input + salt))
return hex.EncodeToString(hash[:])
}
```
**Recommendation:** Refactor the package to be stateless by encapsulating the `keyMap` within a struct. This will make the package safe for concurrent use and easier to test.
**Refactoring Approach:**
1. Create a `Lethn` struct to hold the `keyMap`.
2. Create a `New` function to initialize the `Lethn` struct with a default or custom `keyMap`.
3. Change the `Hash`, `Verify`, and `createSalt` functions into methods on the `Lethn` struct.
4. Provide a package-level `Hash` function that uses a default `Lethn` instance for backward compatibility.
**Proposed Refactoring:**
```go
package lthn
import (
"crypto/sha256"
"encoding/hex"
)
// Lethn holds the configuration for the LTHN hashing algorithm.
type Lethn struct {
keyMap map[rune]rune
}
// New creates a new Lethn instance with the provided keyMap.
// If no keyMap is provided, the default keyMap is used.
func New(keyMap ...map[rune]rune) *Lethn {
l := &Lethn{
keyMap: defaultKeyMap,
}
if len(keyMap) > 0 {
l.keyMap = keyMap[0]
}
return l
}
var defaultKeyMap = map[rune]rune{
'o': '0', 'l': '1', 'e': '3', 'a': '4', 's': 'z', 't': '7',
'0': 'o', '1': 'l', '3': 'e', '4', 'a', '7': 't',
}
// Hash computes the LTHN hash of the input string.
func (l *Lethn) Hash(input string) string {
salt := l.createSalt(input)
hash := sha256.Sum256([]byte(input + salt))
return hex.EncodeToString(hash[:])
}
// createSalt derives a quasi-salt from the input string.
func (l *Lethn) createSalt(input string) string {
if input == "" {
return ""
}
runes := []rune(input)
salt := make([]rune, len(runes))
for i := 0; i < len(runes); i++ {
char := runes[len(runes)-1-i]
if replacement, ok := l.keyMap[char]; ok {
salt[i] = replacement
} else {
salt[i] = char
}
}
return string(salt)
}
// Verify checks if an input string produces the given hash.
func (l *Lethn) Verify(input string, hash string) bool {
return l.Hash(input) == hash
}
// Default instance for backward compatibility
var defaultLethn = New()
// Hash is a package-level function that uses the default Lethn instance.
func Hash(input string) string {
return defaultLethn.Hash(input)
}
// Verify is a package-level function that uses the default Lethn instance.
func Verify(input string, hash string) bool {
return defaultLethn.Verify(input, hash)
}
```

View file

@ -5,9 +5,9 @@ import (
"io/ioutil"
"os"
"github.com/Snider/Enchantrix/pkg/crypt"
"github.com/Snider/Enchantrix/pkg/enchantrix"
"github.com/Snider/Enchantrix/pkg/trix"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/enchantrix"
"forge.lthn.ai/Snider/Enchantrix/pkg/trix"
"github.com/spf13/cobra"
)

View file

@ -9,7 +9,7 @@ package main
import (
"fmt"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func main() {

View file

@ -9,7 +9,7 @@ package main
import (
"fmt"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func main() {

View file

@ -11,7 +11,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func main() {

View file

@ -11,7 +11,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func main() {

View file

@ -11,7 +11,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func main() {

View file

@ -11,7 +11,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func main() {

View file

@ -12,7 +12,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func main() {

View file

@ -11,7 +11,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/enchantrix"
"forge.lthn.ai/Snider/Enchantrix/pkg/enchantrix"
)
func main() {

View file

@ -12,8 +12,8 @@ import (
"log"
"time"
"github.com/Snider/Enchantrix/pkg/crypt"
"github.com/Snider/Enchantrix/pkg/trix"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/trix"
)
func main() {

19
go.mod
View file

@ -1,20 +1,23 @@
module github.com/Snider/Enchantrix
module forge.lthn.ai/Snider/Enchantrix
go 1.25
require (
github.com/ProtonMail/go-crypto v1.3.0
github.com/spf13/cobra v1.10.1
github.com/spf13/cobra v1.10.2
github.com/stretchr/testify v1.11.1
golang.org/x/crypto v0.43.0
golang.org/x/crypto v0.48.0
)
require (
github.com/cloudflare/circl v1.6.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/cloudflare/circl v1.6.3 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.9 // indirect
golang.org/x/sys v0.37.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rogpeppe/go-internal v1.14.1 // indirect
github.com/spf13/pflag v1.0.10 // indirect
golang.org/x/sys v0.41.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

25
go.sum
View file

@ -1,26 +1,23 @@
github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
github.com/ProtonMail/go-crypto v1.3.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk=
github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
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

@ -11,9 +11,9 @@ import (
"strconv"
"strings"
"github.com/Snider/Enchantrix/pkg/crypt/std/lthn"
"github.com/Snider/Enchantrix/pkg/crypt/std/pgp"
"github.com/Snider/Enchantrix/pkg/crypt/std/rsa"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt/std/lthn"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt/std/pgp"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt/std/rsa"
)
// Service is the main struct for the crypt service.

View file

@ -4,7 +4,7 @@ import (
"strings"
"testing"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
"github.com/stretchr/testify/assert"
)

View file

@ -4,7 +4,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
)
func ExampleService_Hash() {

View file

@ -4,7 +4,7 @@ import (
"errors"
"testing"
"github.com/Snider/Enchantrix/pkg/enchantrix"
"forge.lthn.ai/Snider/Enchantrix/pkg/enchantrix"
"github.com/stretchr/testify/assert"
)

View file

@ -4,7 +4,7 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/enchantrix"
"forge.lthn.ai/Snider/Enchantrix/pkg/enchantrix"
)
func ExampleTransmute() {

View file

@ -4,7 +4,7 @@ import (
"errors"
"time"
"github.com/Snider/Enchantrix/pkg/enchantrix"
"forge.lthn.ai/Snider/Enchantrix/pkg/enchantrix"
)
var (

View file

@ -4,7 +4,7 @@ import (
"bytes"
"testing"
"github.com/Snider/Enchantrix/pkg/trix"
"forge.lthn.ai/Snider/Enchantrix/pkg/trix"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

View file

@ -4,8 +4,8 @@ import (
"fmt"
"log"
"github.com/Snider/Enchantrix/pkg/crypt"
"github.com/Snider/Enchantrix/pkg/trix"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/trix"
)
func ExampleEncode() {

View file

@ -28,8 +28,8 @@ import (
"fmt"
"io"
"github.com/Snider/Enchantrix/pkg/crypt"
"github.com/Snider/Enchantrix/pkg/enchantrix"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/enchantrix"
)
const (

View file

@ -8,8 +8,8 @@ import (
"reflect"
"testing"
"github.com/Snider/Enchantrix/pkg/crypt"
"github.com/Snider/Enchantrix/pkg/trix"
"forge.lthn.ai/Snider/Enchantrix/pkg/crypt"
"forge.lthn.ai/Snider/Enchantrix/pkg/trix"
"github.com/stretchr/testify/assert"
)