Initial commit
Basic project layout, some initial code
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/bin
|
19
LICENSE
Normal file
19
LICENSE
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2025 omicron <omicron.me@protonmail.com>
|
||||||
|
|
||||||
|
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.
|
30
Makefile
Normal file
30
Makefile
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
BINARY_DIR = bin
|
||||||
|
BINARIES = $(patsubst cmd/%/,%,$(wildcard cmd/*/))
|
||||||
|
|
||||||
|
.PHONY: all build test validate clean run $(BINARIES)
|
||||||
|
|
||||||
|
all: build
|
||||||
|
|
||||||
|
|
||||||
|
build: $(BINARIES)
|
||||||
|
|
||||||
|
|
||||||
|
$(BINARY_DIR):
|
||||||
|
mkdir -p $(BINARY_DIR)
|
||||||
|
|
||||||
|
$(BINARIES): %: $(BINARY_DIR)
|
||||||
|
go build -o $(BINARY_DIR)/$@ ./cmd/$@/
|
||||||
|
|
||||||
|
test:
|
||||||
|
go test ./...
|
||||||
|
|
||||||
|
validate:
|
||||||
|
@test -z "$(shell gofmt -l .)" || (echo "Incorrect formatting in:"; gofmt -l .; exit 1)
|
||||||
|
go vet ./...
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BINARY_DIR)
|
||||||
|
go clean
|
||||||
|
|
||||||
|
run: $(LINKSERV)
|
||||||
|
$(LINKSERV)
|
15
cmd/linkctl/main.go
Normal file
15
cmd/linkctl/main.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
import "git.omicron.one/omicron/linkshare/internal/util"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
paths, err := util.FindDirectories("")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Paths:")
|
||||||
|
fmt.Println(" Schema:", paths.SchemaDir)
|
||||||
|
fmt.Println(" Database:", paths.DatabaseFile)
|
||||||
|
}
|
118
internal/util/directories.go
Normal file
118
internal/util/directories.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AppPaths struct {
|
||||||
|
SchemaDir string
|
||||||
|
DatabaseFile string
|
||||||
|
}
|
||||||
|
|
||||||
|
func executableDir() (string, error) {
|
||||||
|
myExecutable, err := os.Executable()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
myExecutable, err = filepath.EvalSymlinks(myExecutable)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return filepath.Dir(myExecutable), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSystemInstall(myDir string) (bool, error) {
|
||||||
|
if myDir != "/bin" && myDir != "/usr/bin" {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSystemLocalInstall(myDir string) (bool, error) {
|
||||||
|
if myDir != "/usr/local/bin" {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func isUserLocalInstall(myDir string) (bool, error) {
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if myDir != filepath.Join(home, ".local/bin") {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func findDefaultDirectories() (*AppPaths, error) {
|
||||||
|
myDir, err := executableDir()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if system, err := isSystemInstall(myDir); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if system {
|
||||||
|
return &AppPaths{
|
||||||
|
SchemaDir: "/usr/share/linkshare/schema",
|
||||||
|
DatabaseFile: "/var/lib/linkshare/linkshare.db",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if local, err := isSystemLocalInstall(myDir); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if local {
|
||||||
|
return &AppPaths{
|
||||||
|
SchemaDir: "/usr/local/share/linkshare/schema",
|
||||||
|
DatabaseFile: "/var/lib/linkshare/linkshare.db",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if user, err := isUserLocalInstall(myDir); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if user {
|
||||||
|
return &AppPaths{
|
||||||
|
SchemaDir: filepath.Join(myDir, "../share/linkshare/"),
|
||||||
|
DatabaseFile: filepath.Join(myDir, "../var/lib/linkshare/linkshare.db"),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &AppPaths{
|
||||||
|
SchemaDir: filepath.Join(myDir, "../schema"),
|
||||||
|
DatabaseFile: filepath.Join(myDir, "../linkshare.db"),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindDirectories will find all relevant directories.
|
||||||
|
// It checks where the binary is installed and based on that it will decide
|
||||||
|
// where to look for other static data.
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - dbPath: the explicit db path passed on the command line. If this contains
|
||||||
|
// a non-empty string the db returned database file will always be this one.
|
||||||
|
// If this contains an empty string a default database file will be picked
|
||||||
|
// based on where the binary is installed.
|
||||||
|
func FindDirectories(dbPath string) (*AppPaths, error) {
|
||||||
|
paths, err := findDefaultDirectories()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if dbPath != "" {
|
||||||
|
paths.DatabaseFile = dbPath
|
||||||
|
}
|
||||||
|
return paths, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateDirectories ensures all application managed directories are created
|
||||||
|
func CreateDirectories(paths *AppPaths) error {
|
||||||
|
err := os.MkdirAll(filepath.Dir(paths.DatabaseFile), 0750)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Reference in New Issue
Block a user