Compare commits

...

5 commits

Author SHA1 Message Date
3d06bb35ce 🔀🔖 Merge tag 'v0.0.1' into develop
🎉 First release
2025-03-10 17:06:07 -05:00
ee0b3beeb5 🔀 Merge branch 'release/0.0.1' into stable 2025-03-10 17:05:17 -05:00
899fbedd9a 🔖 Version 0.0.1 2025-03-10 17:03:52 -05:00
7126ef97a4 Add Make function
This is the important one
2025-03-10 14:53:59 -05:00
7bd5503613 ♻️ Export Config 2025-03-10 14:52:50 -05:00
11 changed files with 140 additions and 38 deletions

14
CHANGELOG.md Normal file
View file

@ -0,0 +1,14 @@
# Changelog
## [0.0.1] - 2025-03-10
Initial Release! Hope you like it!
### Added
- nomino.Make
- nomino.Config
- nomino.Generator
+ We needs more of these until I'm ready
- Lots of tests!

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2025, Dan Jones <danjones@goodevilgenius.org>.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

11
README.md Normal file
View file

@ -0,0 +1,11 @@
# nomino - A filename generator
The purpose of nomino is to generate (probably random) filenames, for example, if you want to save an uploaded file to storage under a new name.
It takes a lot of inspiration (although no actual code) from [Onym](https://github.com/Blaspsoft/onym).
## TODO
I'll fill this out more in depth later.
For now, add it to a new project, and run `go doc codeberg.org/danjones000/nomino`

20
config.go Normal file
View file

@ -0,0 +1,20 @@
package nomino
type Config struct {
original string
prefix string
suffix string
extension string
generator Generator
}
func NewConfig(options ...Option) Config {
conf := Config{
extension: ".txt",
generator: uuidGen,
}
for _, opt := range options {
opt(&conf)
}
return conf
}

22
config_test.go Normal file
View file

@ -0,0 +1,22 @@
package nomino
import (
"testing"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
)
func TestNewConf(t *testing.T) {
c := NewConfig()
assert.Equal(t, ".txt", c.extension)
st, _ := c.generator()
_, parseErr := uuid.Parse(st)
assert.NoError(t, parseErr)
}
func TestNewConfWithOpts(t *testing.T) {
c := NewConfig(WithoutExtension(), WithPrefix("foobar"))
assert.Equal(t, "", c.extension)
assert.Equal(t, "foobar_", c.prefix)
}

View file

@ -14,7 +14,7 @@ type Generator func() (string, error)
// WithGenerator sets the specified generator // WithGenerator sets the specified generator
func WithGenerator(g Generator) Option { func WithGenerator(g Generator) Option {
return func(c *config) { return func(c *Config) {
c.generator = g c.generator = g
} }
} }

View file

@ -11,7 +11,7 @@ import (
func TestWithGenerator(t *testing.T) { func TestWithGenerator(t *testing.T) {
g := func() (string, error) { return "abc", nil } g := func() (string, error) { return "abc", nil }
var c config var c Config
WithGenerator(g)(&c) WithGenerator(g)(&c)
st, err := c.generator() st, err := c.generator()
assert.NoError(t, err) assert.NoError(t, err)

15
make.go Normal file
View file

@ -0,0 +1,15 @@
package nomino
import "fmt"
// Make generates a random filename. The behavior can be controlled by specifying Options
// In general, the final filename will be [prefix]_[generated_string]_[original_filename]_[suffix].[extension].
// If the name generator returns an error (generally, it shouldn't), that will be returned instead.
func Make(conf Config) (string, error) {
name, err := conf.generator()
if err != nil {
return "", err
}
return fmt.Sprintf("%s%s%s%s%s", conf.prefix, name, conf.original, conf.suffix, conf.original), nil
}

23
make_test.go Normal file
View file

@ -0,0 +1,23 @@
package nomino
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
)
func TestMake(t *testing.T) {
conf := NewConfig(WithGenerator(func() (string, error) { return "abc", nil }))
st, err := Make(conf)
assert.NoError(t, err)
assert.Equal(t, "abc", st)
}
func TestMakeErr(t *testing.T) {
retErr := errors.New("oops")
conf := NewConfig(WithGenerator(func() (string, error) { return "foobar", retErr }))
st, err := Make(conf)
assert.Zero(t, st)
assert.ErrorIs(t, err, retErr)
}

View file

@ -2,56 +2,41 @@ package nomino
import "strings" import "strings"
type config struct { // Option sets configuration parameters for Config.
original string type Option func(c *Config)
prefix string
suffix string
extension string
generator Generator
}
func defaultConf() config {
return config{
extension: ".txt",
generator: uuidGen,
}
}
// Option is an option for nomino
type Option func(c *config)
// WithOriginal sets the original filename. // WithOriginal sets the original filename.
// This will be included in the generated name after the generated string and before the suffix. // This will be included in the generated name after the generated string and before the suffix.
func WithOriginal(o string) Option { func WithOriginal(o string) Option {
return func(c *config) { return func(c *Config) {
c.original = "_" + o c.original = "_" + o
} }
} }
// WithPrefix sets a prefix for the generated name. // WithPrefix sets a prefix for the generated name.
func WithPrefix(p string) Option { func WithPrefix(p string) Option {
return func(c *config) { return func(c *Config) {
c.prefix = p + "_" c.prefix = p + "_"
} }
} }
// WithSuffix sets a suffix for the generated name. It will be included in the base name before the suffix. // WithSuffix sets a suffix for the generated name. It will be included in the base name before the suffix.
func WithSuffix(s string) Option { func WithSuffix(s string) Option {
return func(c *config) { return func(c *Config) {
c.suffix = "_" + s c.suffix = "_" + s
} }
} }
// WithoutExtension sets no extension for the generated filename. By default, it will be txt // WithoutExtension sets no extension for the generated filename. By default, it will be txt
func WithoutExtension() Option { func WithoutExtension() Option {
return func(c *config) { return func(c *Config) {
c.extension = "" c.extension = ""
} }
} }
// WithExtension sets the extension for the generated filename. // WithExtension sets the extension for the generated filename.
func WithExtension(ext string) Option { func WithExtension(ext string) Option {
return func(c *config) { return func(c *Config) {
c.extension = "." + strings.TrimPrefix(ext, ".") c.extension = "." + strings.TrimPrefix(ext, ".")
} }
} }

View file

@ -3,47 +3,38 @@ package nomino
import ( import (
"testing" "testing"
"github.com/google/uuid"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestDefaultConf(t *testing.T) {
c := defaultConf()
assert.Equal(t, ".txt", c.extension)
st, _ := c.generator()
_, parseErr := uuid.Parse(st)
assert.NoError(t, parseErr)
}
func TestWithOriginal(t *testing.T) { func TestWithOriginal(t *testing.T) {
var c config var c Config
name := "foobar" name := "foobar"
WithOriginal(name)(&c) WithOriginal(name)(&c)
assert.Equal(t, "_"+name, c.original) assert.Equal(t, "_"+name, c.original)
} }
func TestWithPrefix(t *testing.T) { func TestWithPrefix(t *testing.T) {
var c config var c Config
pref := "draft" pref := "draft"
WithPrefix(pref)(&c) WithPrefix(pref)(&c)
assert.Equal(t, pref+"_", c.prefix) assert.Equal(t, pref+"_", c.prefix)
} }
func TestWithSuffix(t *testing.T) { func TestWithSuffix(t *testing.T) {
var c config var c Config
suff := "out" suff := "out"
WithSuffix(suff)(&c) WithSuffix(suff)(&c)
assert.Equal(t, "_"+suff, c.suffix) assert.Equal(t, "_"+suff, c.suffix)
} }
func TestWithoutExtension(t *testing.T) { func TestWithoutExtension(t *testing.T) {
c := config{extension: ".foobar"} c := Config{extension: ".foobar"}
WithoutExtension()(&c) WithoutExtension()(&c)
assert.Equal(t, "", c.extension) assert.Equal(t, "", c.extension)
} }
func TestWithExtension(t *testing.T) { func TestWithExtension(t *testing.T) {
var c config var c Config
ext := "yaml" ext := "yaml"
WithExtension(ext)(&c) WithExtension(ext)(&c)
assert.Equal(t, "."+ext, c.extension) assert.Equal(t, "."+ext, c.extension)