Compare commits
4 commits
renovate/g
...
main
Author | SHA1 | Date | |
---|---|---|---|
29e31c5b21 | |||
7ae4c4869e | |||
a16af482de | |||
fd263d8280 |
51 changed files with 390 additions and 202 deletions
|
@ -1,31 +0,0 @@
|
||||||
name: build bin
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
pull_request:
|
|
||||||
branches: [main]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: Make sure build does not fail
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: https://code.forgejo.org/actions/checkout@v4
|
|
||||||
name: checkout
|
|
||||||
- name: install alsa devel
|
|
||||||
run: apt update && apt install libasound2-dev -y
|
|
||||||
- uses: https://code.forgejo.org/actions/setup-go@v5
|
|
||||||
name: install go
|
|
||||||
with:
|
|
||||||
go-version-file: './go.mod'
|
|
||||||
- run: go version
|
|
||||||
name: Go version
|
|
||||||
- run: make dep
|
|
||||||
name: install dependencies
|
|
||||||
- run: make build
|
|
||||||
name: build app
|
|
||||||
|
|
93
.forgejo/workflows/ci.yml
Normal file
93
.forgejo/workflows/ci.yml
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
codespell:
|
||||||
|
name: check for spelling errors
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Annotate locations with typos
|
||||||
|
uses: "https://github.com/codespell-project/codespell-problem-matcher@v1"
|
||||||
|
- name: Codespell
|
||||||
|
uses: "https://github.com/codespell-project/actions-codespell@v2"
|
||||||
|
with:
|
||||||
|
check_filenames: true
|
||||||
|
check_hidden: true
|
||||||
|
skip: ./.git
|
||||||
|
|
||||||
|
codequality:
|
||||||
|
name: code quality (lint/tests)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- codespell
|
||||||
|
if: ${{ success() }}
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- uses: https://code.forgejo.org/actions/setup-go@v5
|
||||||
|
name: install go
|
||||||
|
with:
|
||||||
|
go-version-file: './go.mod'
|
||||||
|
- name: install dependencies
|
||||||
|
run: make dep
|
||||||
|
- name: download golangci-lint
|
||||||
|
run: wget https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh
|
||||||
|
- name: install golangci-lint
|
||||||
|
run: sh ./install.sh v1.62.2
|
||||||
|
- name: lint
|
||||||
|
run: ./bin/golangci-lint run
|
||||||
|
|
||||||
|
compile:
|
||||||
|
name: make sure build does not fail
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- codespell
|
||||||
|
- codequality
|
||||||
|
if: ${{ success() }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
name: checkout
|
||||||
|
- name: install alsa devel
|
||||||
|
run: apt update && apt install libasound2-dev -y
|
||||||
|
- uses: https://code.forgejo.org/actions/setup-go@v5
|
||||||
|
name: install go
|
||||||
|
with:
|
||||||
|
go-version-file: './go.mod'
|
||||||
|
- run: go version
|
||||||
|
name: Go version
|
||||||
|
- run: make dep
|
||||||
|
name: install dependencies
|
||||||
|
- run: make build
|
||||||
|
name: build app
|
||||||
|
|
||||||
|
notify-fail:
|
||||||
|
name: notify-fail
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs:
|
||||||
|
- codespell
|
||||||
|
- codequality
|
||||||
|
- compile
|
||||||
|
if: ${{ failure() }}
|
||||||
|
env:
|
||||||
|
SERVER_URL: ${{ secrets.GOTIFY_SERVER_URL }}
|
||||||
|
TOKEN: ${{ secrets.GOTIFY_TOKEN }}
|
||||||
|
steps:
|
||||||
|
- name: gotify
|
||||||
|
run: |-
|
||||||
|
curl "${SERVER_URL}?token=${TOKEN}" \
|
||||||
|
-F "title='CI failed'" \
|
||||||
|
-F "message='Something failed at ${GITHUB_REPOSITORY}/${GITHUB_REF} for user ${GITHUB_ACTOR}'" \
|
||||||
|
-F "priority=7" &> /dev/null
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
name: Codespell
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
pull_request:
|
|
||||||
branches: [main]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
codespell:
|
|
||||||
name: Check for spelling errors
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Annotate locations with typos
|
|
||||||
uses: "https://github.com/codespell-project/codespell-problem-matcher@v1"
|
|
||||||
- name: Codespell
|
|
||||||
uses: "https://github.com/codespell-project/actions-codespell@v2"
|
|
||||||
with:
|
|
||||||
check_filenames: true
|
|
||||||
check_hidden: true
|
|
||||||
skip: ./.git
|
|
12
.golangci.yml
Normal file
12
.golangci.yml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
linters:
|
||||||
|
enable-all: true
|
||||||
|
disable:
|
||||||
|
- wrapcheck
|
||||||
|
- exhaustruct
|
||||||
|
- varnamelen
|
||||||
|
- gochecknoglobals
|
||||||
|
- depguard
|
||||||
|
- gochecknoinits
|
||||||
|
- forbidigo
|
||||||
|
- revive
|
||||||
|
- gosec
|
2
Makefile
2
Makefile
|
@ -8,7 +8,7 @@ GO_BUILD_LD_FLAGS=-ldflags="-s -w -X 'git.dayanhub.com/sagi/envoid/internal/vari
|
||||||
build:
|
build:
|
||||||
GOARCH=amd64 GOOS=linux go build ${GO_BUILD_LD_FLAGS} -o ${BUILD_FOLDER}/${BINARY_NAME}-linux main.go
|
GOARCH=amd64 GOOS=linux go build ${GO_BUILD_LD_FLAGS} -o ${BUILD_FOLDER}/${BINARY_NAME}-linux main.go
|
||||||
GOARCH=amd64 GOOS=darwin go build ${GO_BUILD_LD_FLAGS} -o ${BUILD_FOLDER}/${BINARY_NAME}-darwin main.go
|
GOARCH=amd64 GOOS=darwin go build ${GO_BUILD_LD_FLAGS} -o ${BUILD_FOLDER}/${BINARY_NAME}-darwin main.go
|
||||||
GOARCH=amd64 GOOS=windows go build ${GO_BUILD_LD_FLAGS} -o ${BUILD_FOLDER}/${BINARY_NAME}-windows main.go
|
#GOARCH=amd64 GOOS=windows go build ${GO_BUILD_LD_FLAGS} -o ${BUILD_FOLDER}/${BINARY_NAME}-windows main.go
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
|
|
14
cmd/env.go
14
cmd/env.go
|
@ -37,12 +37,15 @@ var rmEnvCmd = &cobra.Command{
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer ds.Close()
|
defer ds.Close()
|
||||||
|
|
||||||
err = ds.RemoveEnv(*envFlags.rmEnvName)
|
err = ds.RemoveEnv(*envFlags.rmEnvName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
project.RemoveEnv(*envFlags.rmEnvName)
|
project.RemoveEnv(*envFlags.rmEnvName)
|
||||||
configuration.Save()
|
configuration.Save()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -91,6 +94,7 @@ var addEnvCmd = &cobra.Command{
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
configuration.Save()
|
configuration.Save()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -119,21 +123,27 @@ var lsEnvCmd = &cobra.Command{
|
||||||
func init() {
|
func init() {
|
||||||
// add
|
// add
|
||||||
envFlags.addEnvName = addEnvCmd.Flags().StringP("environment", "e", "", "environment name")
|
envFlags.addEnvName = addEnvCmd.Flags().StringP("environment", "e", "", "environment name")
|
||||||
|
|
||||||
err := addEnvCmd.MarkFlagRequired("environment")
|
err := addEnvCmd.MarkFlagRequired("environment")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
envFlags.baseEnvName = addEnvCmd.Flags().StringP("base-environment", "b", "", "base environment name (copy data from base)")
|
|
||||||
|
envFlags.baseEnvName = addEnvCmd.Flags().StringP("base-environment",
|
||||||
|
"b", "", "base environment name (copy data from base)")
|
||||||
|
|
||||||
err = addEnvCmd.RegisterFlagCompletionFunc("base-environment", validEnvironmentNamesComplete)
|
err = addEnvCmd.RegisterFlagCompletionFunc("base-environment", validEnvironmentNamesComplete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
//rm
|
// rm
|
||||||
envFlags.rmEnvName = rmEnvCmd.Flags().StringP("environment", "e", "", "environment name")
|
envFlags.rmEnvName = rmEnvCmd.Flags().StringP("environment", "e", "", "environment name")
|
||||||
|
|
||||||
err = rmEnvCmd.MarkFlagRequired("environment")
|
err = rmEnvCmd.MarkFlagRequired("environment")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = rmEnvCmd.RegisterFlagCompletionFunc("environment", validEnvironmentNamesComplete)
|
err = rmEnvCmd.RegisterFlagCompletionFunc("environment", validEnvironmentNamesComplete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"errors"
|
|
||||||
"git.dayanhub.com/sagi/envoid/internal/datastore"
|
"git.dayanhub.com/sagi/envoid/internal/datastore"
|
||||||
intErrors "git.dayanhub.com/sagi/envoid/internal/errors"
|
intErrors "git.dayanhub.com/sagi/envoid/internal/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -68,12 +68,14 @@ var getCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Println(envVar.Value)
|
fmt.Println(envVar.Value)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
getFlags.envName = getCmd.Flags().StringP("environment", "e", "", "environment name")
|
getFlags.envName = getCmd.Flags().StringP("environment", "e", "", "environment name")
|
||||||
|
|
||||||
err := getCmd.RegisterFlagCompletionFunc("environment", validEnvironmentNamesComplete)
|
err := getCmd.RegisterFlagCompletionFunc("environment", validEnvironmentNamesComplete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
@ -39,8 +39,9 @@ var importCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
envs = []*types.Environment{e}
|
envs = []*types.Environment{e}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return fmt.Errorf("Needs a file to parse")
|
return errors.NewInvalidCommandError("Missing a file to parse")
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.Open(args[0])
|
file, err := os.Open(args[0])
|
||||||
|
@ -70,6 +71,7 @@ var importCmd = &cobra.Command{
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
importFlags.envName = importCmd.Flags().StringP("environment", "e", "", "environments name")
|
importFlags.envName = importCmd.Flags().StringP("environment", "e", "", "environments name")
|
||||||
|
|
||||||
err := importCmd.RegisterFlagCompletionFunc("environment", validEnvironmentNamesComplete)
|
err := importCmd.RegisterFlagCompletionFunc("environment", validEnvironmentNamesComplete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
@ -18,6 +18,7 @@ var initCmd = &cobra.Command{
|
||||||
_, err := configuration.GetProject(workingDir)
|
_, err := configuration.GetProject(workingDir)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fmt.Printf("Project already exists. please remove if you wish to override\n")
|
fmt.Printf("Project already exists. please remove if you wish to override\n")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
ds, err := datastore.NewDataStore()
|
ds, err := datastore.NewDataStore()
|
||||||
|
@ -30,7 +31,7 @@ var initCmd = &cobra.Command{
|
||||||
var pass string
|
var pass string
|
||||||
var envNames []string
|
var envNames []string
|
||||||
|
|
||||||
//check if we are importing an existing file
|
// check if we are importing an existing file
|
||||||
if ds.DoesFileExists() {
|
if ds.DoesFileExists() {
|
||||||
fmt.Printf("Project was not found locally. But found %s file in path.\n", variables.DBFileName)
|
fmt.Printf("Project was not found locally. But found %s file in path.\n", variables.DBFileName)
|
||||||
fmt.Printf("Importing Project for %s\n", workingDir)
|
fmt.Printf("Importing Project for %s\n", workingDir)
|
||||||
|
@ -71,6 +72,7 @@ var initCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
configuration.Save()
|
configuration.Save()
|
||||||
fmt.Println("✅ Done")
|
fmt.Println("✅ Done")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,13 +44,13 @@ var printenvCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
env = e
|
env = e
|
||||||
}
|
}
|
||||||
datastore, err := datastore.NewDataStore()
|
ds, err := datastore.NewDataStore()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error: %e", err)
|
fmt.Printf("Error: %e", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer datastore.Close()
|
defer ds.Close()
|
||||||
vars, err := datastore.GetAll(env.Name)
|
vars, err := ds.GetAll(env.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -68,12 +68,14 @@ var printenvCmd = &cobra.Command{
|
||||||
fmt.Println("###")
|
fmt.Println("###")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
printenvFlags.envName = printenvCmd.Flags().StringP("environment", "e", "", "environments name")
|
printenvFlags.envName = printenvCmd.Flags().StringP("environment", "e", "", "environments name")
|
||||||
|
|
||||||
err := printenvCmd.RegisterFlagCompletionFunc("environment", validEnvironmentNamesComplete)
|
err := printenvCmd.RegisterFlagCompletionFunc("environment", validEnvironmentNamesComplete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
@ -25,9 +25,11 @@ var lsProjectCmd = &cobra.Command{
|
||||||
for _, proj := range configuration.Projects {
|
for _, proj := range configuration.Projects {
|
||||||
fmt.Printf("%s\t%s\n", proj.Name, proj.Path)
|
fmt.Printf("%s\t%s\n", proj.Name, proj.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var rmProjectCmd = &cobra.Command{
|
var rmProjectCmd = &cobra.Command{
|
||||||
Use: "rm",
|
Use: "rm",
|
||||||
Short: "remove a project definition. the `.envoid` file will not be removed",
|
Short: "remove a project definition. the `.envoid` file will not be removed",
|
||||||
|
@ -36,22 +38,27 @@ var rmProjectCmd = &cobra.Command{
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
configuration.RemoveProject(project)
|
configuration.RemoveProject(project)
|
||||||
configuration.Save()
|
configuration.Save()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
projectFlags.projectPath = rmProjectCmd.Flags().StringP("project-path", "p", "", "project path to remove")
|
projectFlags.projectPath = rmProjectCmd.Flags().StringP("project-path", "p", "", "project path to remove")
|
||||||
|
|
||||||
err := rmProjectCmd.MarkFlagRequired("project-path")
|
err := rmProjectCmd.MarkFlagRequired("project-path")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = rmProjectCmd.RegisterFlagCompletionFunc("project-path", validProjectPathComplete)
|
err = rmProjectCmd.RegisterFlagCompletionFunc("project-path", validProjectPathComplete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
projectCmd.AddCommand(lsProjectCmd)
|
projectCmd.AddCommand(lsProjectCmd)
|
||||||
projectCmd.AddCommand(rmProjectCmd)
|
projectCmd.AddCommand(rmProjectCmd)
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ var rmCmd = &cobra.Command{
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rmFlags.envName = rmCmd.Flags().StringP("environment", "e", "", "environments name")
|
rmFlags.envName = rmCmd.Flags().StringP("environment", "e", "", "environments name")
|
||||||
|
|
||||||
err := rmCmd.RegisterFlagCompletionFunc("environment", validEnvironmentNamesComplete)
|
err := rmCmd.RegisterFlagCompletionFunc("environment", validEnvironmentNamesComplete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
31
cmd/root.go
31
cmd/root.go
|
@ -5,22 +5,26 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.dayanhub.com/sagi/envoid/internal/config"
|
"git.dayanhub.com/sagi/envoid/internal/config"
|
||||||
|
"git.dayanhub.com/sagi/envoid/internal/errors"
|
||||||
"git.dayanhub.com/sagi/envoid/internal/types"
|
"git.dayanhub.com/sagi/envoid/internal/types"
|
||||||
"git.dayanhub.com/sagi/envoid/internal/variables"
|
"git.dayanhub.com/sagi/envoid/internal/variables"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/cobra/doc"
|
"github.com/spf13/cobra/doc"
|
||||||
)
|
)
|
||||||
|
|
||||||
var configuration *config.Config = nil
|
var (
|
||||||
var workingDir string
|
configuration *config.Config = nil
|
||||||
var project *types.Project = nil
|
workingDir string
|
||||||
|
project *types.Project = nil
|
||||||
|
)
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Use: "envoid [command]",
|
Use: "envoid [command]",
|
||||||
Short: "envoid is an easy to use .env manager for personal (non production) use",
|
Short: "envoid is an easy to use .env manager for personal (non production) use",
|
||||||
Long: `envoid is an easy to use .env manager for personal (non production) use.
|
Long: `envoid is an easy to use .env manager for personal (non production) use.
|
||||||
|
|
||||||
envoid works offline and creates different encrypted environments for each project. It's mainly used to store,encrypt (with a passphrase) and share
|
envoid works offline and creates different encrypted environments for each project.
|
||||||
|
It's mainly used to store,encrypt (with a passphrase) and share
|
||||||
.env variables`,
|
.env variables`,
|
||||||
Version: fmt.Sprintf("%s commit %s", variables.Version, variables.Commit),
|
Version: fmt.Sprintf("%s commit %s", variables.Version, variables.Commit),
|
||||||
}
|
}
|
||||||
|
@ -33,6 +37,7 @@ var docCmd = &cobra.Command{
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -46,8 +51,9 @@ func Execute() {
|
||||||
|
|
||||||
func checkAmbiguousEnv(envName string) error {
|
func checkAmbiguousEnv(envName string) error {
|
||||||
if len(envName) == 0 && len(project.Environments) > 1 {
|
if len(envName) == 0 && len(project.Environments) > 1 {
|
||||||
return fmt.Errorf("You have more than 1 environment. please provide environment name")
|
return errors.NewNoEnvProvidedError()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,25 +62,34 @@ func initProject() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
project = p
|
project = p
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func validEnvironmentNamesComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
func validEnvironmentNamesComplete(cmd *cobra.Command, args []string,
|
||||||
|
toComplete string,
|
||||||
|
) ([]string, cobra.ShellCompDirective) {
|
||||||
envs := []string{}
|
envs := []string{}
|
||||||
|
|
||||||
if err := initProject(); err == nil {
|
if err := initProject(); err == nil {
|
||||||
for _, e := range project.Environments {
|
for _, e := range project.Environments {
|
||||||
envs = append(envs, e.Name)
|
envs = append(envs, e.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return envs, cobra.ShellCompDirectiveDefault
|
return envs, cobra.ShellCompDirectiveDefault
|
||||||
}
|
}
|
||||||
|
|
||||||
func validProjectPathComplete(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
func validProjectPathComplete(cmd *cobra.Command, args []string,
|
||||||
|
toComplete string,
|
||||||
|
) ([]string, cobra.ShellCompDirective) {
|
||||||
paths := []string{}
|
paths := []string{}
|
||||||
for _, p := range configuration.Projects {
|
for _, p := range configuration.Projects {
|
||||||
paths = append(paths, fmt.Sprintf("%s\t%s", p.Path, p.Name))
|
paths = append(paths, fmt.Sprintf("%s\t%s", p.Path, p.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
return paths, cobra.ShellCompDirectiveDefault
|
return paths, cobra.ShellCompDirectiveDefault
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,10 +105,12 @@ func init() {
|
||||||
rootCmd.AddCommand(projectCmd)
|
rootCmd.AddCommand(projectCmd)
|
||||||
|
|
||||||
configuration = config.GetConfig()
|
configuration = config.GetConfig()
|
||||||
|
|
||||||
pwd, err := os.Getwd()
|
pwd, err := os.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("[error] %s. please run 'ssecret init'\n", err.Error())
|
fmt.Printf("[error] %s. please run 'ssecret init'\n", err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
workingDir = pwd
|
workingDir = pwd
|
||||||
}
|
}
|
||||||
|
|
19
cmd/set.go
19
cmd/set.go
|
@ -21,13 +21,15 @@ var setCmd = &cobra.Command{
|
||||||
Use: "set [flags] <key> <value>",
|
Use: "set [flags] <key> <value>",
|
||||||
Short: "sets a variable in environment(s)",
|
Short: "sets a variable in environment(s)",
|
||||||
Long: "",
|
Long: "",
|
||||||
Args: func(cmd *cobra.Command, args []string) error {
|
Args: func(_ *cobra.Command, args []string) error {
|
||||||
if len(args) != 2 {
|
expectedArgs := 2
|
||||||
|
if len(args) != expectedArgs {
|
||||||
return errors.NewInvalidCommandError("expected 2 args. <key> <value>")
|
return errors.NewInvalidCommandError("expected 2 args. <key> <value>")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(_ *cobra.Command, args []string) error {
|
||||||
err := initProject()
|
err := initProject()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -57,6 +59,7 @@ var setCmd = &cobra.Command{
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error: %s\n", err.Error())
|
fmt.Printf("Error: %s\n", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -65,13 +68,15 @@ var setEncryptCmd = &cobra.Command{
|
||||||
Use: "encrypt <key>",
|
Use: "encrypt <key>",
|
||||||
Short: "encrypts an existing variable in environment(s)",
|
Short: "encrypts an existing variable in environment(s)",
|
||||||
Long: "",
|
Long: "",
|
||||||
Args: func(cmd *cobra.Command, args []string) error {
|
Args: func(_ *cobra.Command, args []string) error {
|
||||||
if len(args) != 1 {
|
expectedArgs := 1
|
||||||
|
if len(args) != expectedArgs {
|
||||||
return errors.NewInvalidCommandError("expected 1 args. <key>")
|
return errors.NewInvalidCommandError("expected 1 args. <key>")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(_ *cobra.Command, args []string) error {
|
||||||
err := initProject()
|
err := initProject()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -117,9 +122,11 @@ var setEncryptCmd = &cobra.Command{
|
||||||
func init() {
|
func init() {
|
||||||
setFlags.envName = setCmd.PersistentFlags().StringP("environment", "e", "", "environments name")
|
setFlags.envName = setCmd.PersistentFlags().StringP("environment", "e", "", "environments name")
|
||||||
setFlags.encrypt = setCmd.Flags().BoolP("secret", "s", false, "value is a secret. encrypt this value")
|
setFlags.encrypt = setCmd.Flags().BoolP("secret", "s", false, "value is a secret. encrypt this value")
|
||||||
|
|
||||||
err := setCmd.RegisterFlagCompletionFunc("environment", validEnvironmentNamesComplete)
|
err := setCmd.RegisterFlagCompletionFunc("environment", validEnvironmentNamesComplete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
setCmd.AddCommand(setEncryptCmd)
|
setCmd.AddCommand(setEncryptCmd)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,8 @@ envoid is an easy to use .env manager for personal (non production) use
|
||||||
|
|
||||||
envoid is an easy to use .env manager for personal (non production) use.
|
envoid is an easy to use .env manager for personal (non production) use.
|
||||||
|
|
||||||
envoid works offline and creates different encrypted environments for each project. It's mainly used to store,encrypt (with a passphrase) and share
|
envoid works offline and creates different encrypted environments for each project.
|
||||||
|
It's mainly used to store,encrypt (with a passphrase) and share
|
||||||
.env variables
|
.env variables
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
@ -27,4 +28,4 @@ envoid works offline and creates different encrypted environments for each proje
|
||||||
* [envoid rm](envoid_rm.md) - removes a variable from environment(s)
|
* [envoid rm](envoid_rm.md) - removes a variable from environment(s)
|
||||||
* [envoid set](envoid_set.md) - sets a variable in environment(s)
|
* [envoid set](envoid_set.md) - sets a variable in environment(s)
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -22,4 +22,4 @@ See each sub-command's help for details on how to use the generated script.
|
||||||
* [envoid completion powershell](envoid_completion_powershell.md) - Generate the autocompletion script for powershell
|
* [envoid completion powershell](envoid_completion_powershell.md) - Generate the autocompletion script for powershell
|
||||||
* [envoid completion zsh](envoid_completion_zsh.md) - Generate the autocompletion script for zsh
|
* [envoid completion zsh](envoid_completion_zsh.md) - Generate the autocompletion script for zsh
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -41,4 +41,4 @@ envoid completion bash
|
||||||
|
|
||||||
* [envoid completion](envoid_completion.md) - Generate the autocompletion script for the specified shell
|
* [envoid completion](envoid_completion.md) - Generate the autocompletion script for the specified shell
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -32,4 +32,4 @@ envoid completion fish [flags]
|
||||||
|
|
||||||
* [envoid completion](envoid_completion.md) - Generate the autocompletion script for the specified shell
|
* [envoid completion](envoid_completion.md) - Generate the autocompletion script for the specified shell
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -29,4 +29,4 @@ envoid completion powershell [flags]
|
||||||
|
|
||||||
* [envoid completion](envoid_completion.md) - Generate the autocompletion script for the specified shell
|
* [envoid completion](envoid_completion.md) - Generate the autocompletion script for the specified shell
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -43,4 +43,4 @@ envoid completion zsh [flags]
|
||||||
|
|
||||||
* [envoid completion](envoid_completion.md) - Generate the autocompletion script for the specified shell
|
* [envoid completion](envoid_completion.md) - Generate the autocompletion script for the specified shell
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -15,4 +15,4 @@ manage environments
|
||||||
* [envoid env ls](envoid_env_ls.md) - list all environments in this project
|
* [envoid env ls](envoid_env_ls.md) - list all environments in this project
|
||||||
* [envoid env rm](envoid_env_rm.md) - removes an environment
|
* [envoid env rm](envoid_env_rm.md) - removes an environment
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -18,4 +18,4 @@ envoid env add [flags]
|
||||||
|
|
||||||
* [envoid env](envoid_env.md) - manage environments
|
* [envoid env](envoid_env.md) - manage environments
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -16,4 +16,4 @@ envoid env ls [flags]
|
||||||
|
|
||||||
* [envoid env](envoid_env.md) - manage environments
|
* [envoid env](envoid_env.md) - manage environments
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -17,4 +17,4 @@ envoid env rm [flags]
|
||||||
|
|
||||||
* [envoid env](envoid_env.md) - manage environments
|
* [envoid env](envoid_env.md) - manage environments
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -17,4 +17,4 @@ envoid get <key> [flags]
|
||||||
|
|
||||||
* [envoid](envoid.md) - envoid is an easy to use .env manager for personal (non production) use
|
* [envoid](envoid.md) - envoid is an easy to use .env manager for personal (non production) use
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -21,4 +21,4 @@ envoid import <file> [flags]
|
||||||
|
|
||||||
* [envoid](envoid.md) - envoid is an easy to use .env manager for personal (non production) use
|
* [envoid](envoid.md) - envoid is an easy to use .env manager for personal (non production) use
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -16,4 +16,4 @@ envoid init [flags]
|
||||||
|
|
||||||
* [envoid](envoid.md) - envoid is an easy to use .env manager for personal (non production) use
|
* [envoid](envoid.md) - envoid is an easy to use .env manager for personal (non production) use
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -17,4 +17,4 @@ envoid printenv [flags]
|
||||||
|
|
||||||
* [envoid](envoid.md) - envoid is an easy to use .env manager for personal (non production) use
|
* [envoid](envoid.md) - envoid is an easy to use .env manager for personal (non production) use
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -14,4 +14,4 @@ manage project
|
||||||
* [envoid project ls](envoid_project_ls.md) - list all projects for this user
|
* [envoid project ls](envoid_project_ls.md) - list all projects for this user
|
||||||
* [envoid project rm](envoid_project_rm.md) - remove a project definition. the `.envoid` file will not be removed
|
* [envoid project rm](envoid_project_rm.md) - remove a project definition. the `.envoid` file will not be removed
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -16,4 +16,4 @@ envoid project ls [flags]
|
||||||
|
|
||||||
* [envoid project](envoid_project.md) - manage project
|
* [envoid project](envoid_project.md) - manage project
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -17,4 +17,4 @@ envoid project rm [flags]
|
||||||
|
|
||||||
* [envoid project](envoid_project.md) - manage project
|
* [envoid project](envoid_project.md) - manage project
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -17,4 +17,4 @@ envoid rm <key> [flags]
|
||||||
|
|
||||||
* [envoid](envoid.md) - envoid is an easy to use .env manager for personal (non production) use
|
* [envoid](envoid.md) - envoid is an easy to use .env manager for personal (non production) use
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -19,4 +19,4 @@ envoid set [flags] <key> <value>
|
||||||
* [envoid](envoid.md) - envoid is an easy to use .env manager for personal (non production) use
|
* [envoid](envoid.md) - envoid is an easy to use .env manager for personal (non production) use
|
||||||
* [envoid set encrypt](envoid_set_encrypt.md) - encrypts an existing variable in environment(s)
|
* [envoid set encrypt](envoid_set_encrypt.md) - encrypts an existing variable in environment(s)
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
|
@ -22,4 +22,4 @@ envoid set encrypt <key> [flags]
|
||||||
|
|
||||||
* [envoid set](envoid_set.md) - sets a variable in environment(s)
|
* [envoid set](envoid_set.md) - sets a variable in environment(s)
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 12-Dec-2024
|
###### Auto generated by spf13/cobra on 16-Dec-2024
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -7,8 +7,8 @@ require (
|
||||||
github.com/glebarez/go-sqlite v1.22.0
|
github.com/glebarez/go-sqlite v1.22.0
|
||||||
github.com/joho/godotenv v1.5.1
|
github.com/joho/godotenv v1.5.1
|
||||||
github.com/spf13/cobra v1.8.1
|
github.com/spf13/cobra v1.8.1
|
||||||
golang.org/x/crypto v0.29.0
|
golang.org/x/crypto v0.31.0
|
||||||
golang.org/x/sync v0.9.0
|
golang.org/x/sync v0.10.0
|
||||||
golang.org/x/term v0.27.0
|
golang.org/x/term v0.27.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
12
go.sum
12
go.sum
|
@ -24,17 +24,13 @@ github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||||
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||||
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
|
||||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
|
|
||||||
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
|
|
||||||
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
|
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
|
||||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
|
|
@ -6,5 +6,6 @@ func StrToSnakeCase(s string) string {
|
||||||
snake := strings.ToLower(s)
|
snake := strings.ToLower(s)
|
||||||
snake = strings.ReplaceAll(snake, " ", "_")
|
snake = strings.ReplaceAll(snake, " ", "_")
|
||||||
snake = strings.ReplaceAll(snake, "\t", "_")
|
snake = strings.ReplaceAll(snake, "\t", "_")
|
||||||
|
|
||||||
return snake
|
return snake
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
|
@ -14,33 +15,40 @@ import (
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
PWD string `json:"-"`
|
PWD string `json:"-"`
|
||||||
Projects []*types.Project `json:"projects" default:"[]"`
|
Projects []*types.Project `default:"[]" json:"projects"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var configPath string
|
var configPath string
|
||||||
|
|
||||||
var configStruct *Config
|
var configStruct *Config
|
||||||
|
|
||||||
func (c *Config) GetProject(projectPath string) (*types.Project, error) {
|
func (c *Config) GetProject(projectPath string) (*types.Project, error) {
|
||||||
var p *types.Project
|
var p *types.Project
|
||||||
|
|
||||||
for _, project := range configStruct.Projects {
|
for _, project := range configStruct.Projects {
|
||||||
if project.Path == projectPath {
|
if project.Path == projectPath {
|
||||||
p = project
|
p = project
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if p == nil {
|
if p == nil {
|
||||||
return nil, errors.NewProjectNotFoundError(projectPath)
|
return nil, errors.NewProjectNotFoundError(projectPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) RemoveProject(project *types.Project) {
|
func (c *Config) RemoveProject(project *types.Project) {
|
||||||
projects := []*types.Project{}
|
projects := []*types.Project{}
|
||||||
|
|
||||||
for _, p := range c.Projects {
|
for _, p := range c.Projects {
|
||||||
if p.Name != project.Name && p.Path != project.Path {
|
if p.Name != project.Name && p.Path != project.Path {
|
||||||
projects = append(projects, p)
|
projects = append(projects, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Projects = projects
|
c.Projects = projects
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +62,9 @@ func (c *Config) NewProject(name string, path string, password string) (*types.P
|
||||||
Environments: []*types.Environment{},
|
Environments: []*types.Environment{},
|
||||||
}
|
}
|
||||||
configStruct.Projects = append(configStruct.Projects, p)
|
configStruct.Projects = append(configStruct.Projects, p)
|
||||||
|
|
||||||
SaveConfig()
|
SaveConfig()
|
||||||
|
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,46 +89,53 @@ func init() {
|
||||||
fmt.Printf("[ERROR] Failed to fetch user config directory. %e\n", err)
|
fmt.Printf("[ERROR] Failed to fetch user config directory. %e\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := os.Stat(configDir); os.IsNotExist(err) {
|
if _, err := os.Stat(configDir); os.IsNotExist(err) {
|
||||||
err := os.MkdirAll(configDir, 0700)
|
var folderPermissions fs.FileMode = 0o700
|
||||||
|
|
||||||
|
err := os.MkdirAll(configDir, folderPermissions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var configFile *os.File
|
var configFile *os.File
|
||||||
|
|
||||||
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||||
configFile, err = os.Create(configPath)
|
configFile, err = os.Create(configPath)
|
||||||
defer func() {
|
|
||||||
err = configFile.Close()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("[ERROR] Failed to create config file @ %s. %e\n", configPath, err)
|
fmt.Printf("[ERROR] Failed to create config file @ %s. %e\n", configPath, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer configFile.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
configStruct, err = loadConfig()
|
configStruct, err = loadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("[ERROR] Failed to load config file @ %s. %e\n", configPath, err)
|
fmt.Printf("[ERROR] Failed to load config file @ %s. %e\n", configPath, err)
|
||||||
os.Exit(1)
|
configFile.Close()
|
||||||
|
panic("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadConfig() (*Config, error) {
|
func loadConfig() (*Config, error) {
|
||||||
c := &Config{}
|
c := &Config{}
|
||||||
|
|
||||||
err := defaults.Set(c)
|
err := defaults.Set(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
file, err := os.ReadFile(configPath)
|
file, err := os.ReadFile(configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(file) == 0 {
|
if len(file) == 0 {
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = json.Unmarshal(file, c); err != nil {
|
if err = json.Unmarshal(file, c); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -127,7 +144,9 @@ func loadConfig() (*Config, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.PWD = pwd
|
c.PWD = pwd
|
||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +156,10 @@ func SaveConfig() {
|
||||||
fmt.Printf("[ERROR] Failed to convert config to json. %e\n", err)
|
fmt.Printf("[ERROR] Failed to convert config to json. %e\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
err = os.WriteFile(configPath, yml, 0600)
|
|
||||||
|
var filePermissions fs.FileMode = 0o600
|
||||||
|
|
||||||
|
err = os.WriteFile(configPath, yml, filePermissions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("[ERROR] Failed to save config file @ %s. %e\n", configPath, err)
|
fmt.Printf("[ERROR] Failed to save config file @ %s. %e\n", configPath, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|
|
@ -18,84 +18,98 @@ import (
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
type datastore struct {
|
type Datastore struct {
|
||||||
db *db
|
db *db
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDataStore() (*datastore, error) {
|
func NewDataStore() (*Datastore, error) {
|
||||||
db, err := newDB()
|
db, err := newDB()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &datastore{
|
return &Datastore{
|
||||||
db: db,
|
db: db,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *datastore) CreateEnv(name string) error {
|
func (d *Datastore) CreateEnv(name string) error {
|
||||||
table_name := envNameToTableName(name)
|
tableName := envNameToTableName(name)
|
||||||
return d.db.createTableIfNotExists(table_name)
|
|
||||||
|
return d.db.createTableIfNotExists(tableName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *datastore) DoesFileExists() bool {
|
func (d *Datastore) DoesFileExists() bool {
|
||||||
pwd := config.GetConfig().PWD
|
pwd := config.GetConfig().PWD
|
||||||
filePath := fmt.Sprintf("%s/%s", pwd, variables.DBFileName)
|
filePath := fmt.Sprintf("%s/%s", pwd, variables.DBFileName)
|
||||||
|
|
||||||
if _, err := os.Stat(filePath); errors.Is(err, os.ErrNotExist) {
|
if _, err := os.Stat(filePath); errors.Is(err, os.ErrNotExist) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *datastore) ListEnvironments() ([]string, error) {
|
func (d *Datastore) ListEnvironments() ([]string, error) {
|
||||||
return d.db.listTables()
|
return d.db.listTables()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *datastore) CreateEnvOffExsisting(new_env string, base_env string) error {
|
func (d *Datastore) CreateEnvOffExsisting(newEnv string, baseEnv string) error {
|
||||||
table_name_new := envNameToTableName(new_env)
|
tableNameName := envNameToTableName(newEnv)
|
||||||
table_name_base := envNameToTableName(base_env)
|
tableNameBase := envNameToTableName(baseEnv)
|
||||||
err := d.CreateEnv(new_env)
|
|
||||||
|
err := d.CreateEnv(newEnv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = d.db.copyContentFromTo(table_name_base, table_name_new)
|
|
||||||
|
err = d.db.copyContentFromTo(tableNameBase, tableNameName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *datastore) Close() error {
|
func (d *Datastore) Close() error {
|
||||||
return d.db.close()
|
return d.db.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *datastore) SetValue(key string, value string, encrypted *bool, envs []*types.Environment) error {
|
func (d *Datastore) SetValue(key string, value string, encrypted *bool, envs []*types.Environment) error {
|
||||||
if encrypted == nil {
|
if encrypted == nil {
|
||||||
encrypted = common.BoolP(false)
|
encrypted = common.BoolP(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if *encrypted {
|
if *encrypted {
|
||||||
v, err := enc(value)
|
v, err := enc(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
value = *v
|
value = *v
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, env := range envs {
|
for _, env := range envs {
|
||||||
table_name := envNameToTableName(env.Name)
|
tableName := envNameToTableName(env.Name)
|
||||||
if err := d.db.setVar(table_name, key, value, *encrypted); err != nil {
|
|
||||||
|
if err := d.db.setVar(tableName, key, value, *encrypted); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *datastore) GetAll(envName string) ([]*types.EnvVar, error) {
|
func (d *Datastore) GetAll(envName string) ([]*types.EnvVar, error) {
|
||||||
table_name := envNameToTableName(envName)
|
tableName := envNameToTableName(envName)
|
||||||
vars, err := d.db.getAll(table_name)
|
|
||||||
|
vars, err := d.db.getAll(tableName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return vars, err
|
return vars, err
|
||||||
}
|
}
|
||||||
|
|
||||||
g := new(errgroup.Group)
|
g := new(errgroup.Group)
|
||||||
|
|
||||||
for _, v := range vars {
|
for _, v := range vars {
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
if v.Encrypted {
|
if v.Encrypted {
|
||||||
|
@ -103,42 +117,50 @@ func (d *datastore) GetAll(envName string) ([]*types.EnvVar, error) {
|
||||||
return &intErrors.InvalidPasswordError{}
|
return &intErrors.InvalidPasswordError{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := g.Wait(); err != nil {
|
if err := g.Wait(); err != nil {
|
||||||
return vars, err
|
return vars, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.SliceStable(vars, func(i, j int) bool {
|
sort.SliceStable(vars, func(i, j int) bool {
|
||||||
return vars[i].Key < vars[j].Key
|
return vars[i].Key < vars[j].Key
|
||||||
})
|
})
|
||||||
|
|
||||||
return vars, nil
|
return vars, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *datastore) RemoveVar(key string, envs []*types.Environment) {
|
func (d *Datastore) RemoveVar(key string, envs []*types.Environment) {
|
||||||
for _, env := range envs {
|
for _, env := range envs {
|
||||||
table_name := envNameToTableName(env.Name)
|
tableName := envNameToTableName(env.Name)
|
||||||
d.db.rmVar(table_name, key)
|
d.db.rmVar(tableName, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *datastore) GetVar(envName string, key string) (*types.EnvVar, error) {
|
func (d *Datastore) GetVar(envName string, key string) (*types.EnvVar, error) {
|
||||||
table_name := envNameToTableName(envName)
|
tableName := envNameToTableName(envName)
|
||||||
v, err := d.db.getVar(table_name, key)
|
|
||||||
|
v, err := d.db.getVar(tableName, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return v, err
|
return v, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.Encrypted {
|
if v.Encrypted {
|
||||||
if v.Value, err = dec(v.Value); err != nil {
|
if v.Value, err = dec(v.Value); err != nil {
|
||||||
return v, &intErrors.InvalidPasswordError{}
|
return v, &intErrors.InvalidPasswordError{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return v, err
|
return v, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *datastore) RemoveEnv(envName string) error {
|
func (d *Datastore) RemoveEnv(envName string) error {
|
||||||
table_name := envNameToTableName(envName)
|
tableName := envNameToTableName(envName)
|
||||||
return d.db.deleteTable(table_name)
|
|
||||||
|
return d.db.deleteTable(tableName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func enc(s string) (*string, error) {
|
func enc(s string) (*string, error) {
|
||||||
|
@ -146,6 +168,7 @@ func enc(s string) (*string, error) {
|
||||||
proj, _ := conf.GetProject(conf.PWD)
|
proj, _ := conf.GetProject(conf.PWD)
|
||||||
key, salt, err := deriveKey([]byte(proj.Password), nil)
|
key, salt, err := deriveKey([]byte(proj.Password), nil)
|
||||||
data := []byte(s)
|
data := []byte(s)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -179,6 +202,7 @@ func dec(s string) (string, error) {
|
||||||
|
|
||||||
conf := config.GetConfig()
|
conf := config.GetConfig()
|
||||||
proj, _ := conf.GetProject(conf.PWD)
|
proj, _ := conf.GetProject(conf.PWD)
|
||||||
|
|
||||||
key, _, err := deriveKey([]byte(proj.Password), salt)
|
key, _, err := deriveKey([]byte(proj.Password), salt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -207,14 +231,19 @@ func dec(s string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func deriveKey(password, salt []byte) ([]byte, []byte, error) {
|
func deriveKey(password, salt []byte) ([]byte, []byte, error) {
|
||||||
|
saltSize := 32
|
||||||
if salt == nil {
|
if salt == nil {
|
||||||
salt = make([]byte, 32)
|
salt = make([]byte, saltSize)
|
||||||
if _, err := rand.Read(salt); err != nil {
|
if _, err := rand.Read(salt); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
key, err := scrypt.Key(password, salt, 1048576, 8, 1, 32)
|
N := 1048576
|
||||||
|
r := 8
|
||||||
|
p := 1
|
||||||
|
|
||||||
|
key, err := scrypt.Key(password, salt, N, r, p, saltSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package datastore
|
package datastore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"git.dayanhub.com/sagi/envoid/internal/common"
|
"git.dayanhub.com/sagi/envoid/internal/common"
|
||||||
"git.dayanhub.com/sagi/envoid/internal/errors"
|
"git.dayanhub.com/sagi/envoid/internal/errors"
|
||||||
|
@ -20,6 +19,7 @@ func newDB() (*db, error) {
|
||||||
con, err := sql.Open("sqlite", variables.DBFileName)
|
con, err := sql.Open("sqlite", variables.DBFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%v\n", err)
|
fmt.Printf("%v\n", err)
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,72 +32,91 @@ func (d *db) close() error {
|
||||||
return d.con.Close()
|
return d.con.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *db) createTableIfNotExists(table_name string) error {
|
func (d *db) createTableIfNotExists(tableName string) error {
|
||||||
_, err := d.con.Exec(fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s (key TEXT PRIMARY KEY NOT NULL, value BLOB NOT NULL, encrypted BOOL NOT NULL);", table_name))
|
q := "CREATE TABLE IF NOT EXISTS " + tableName +
|
||||||
|
" (key TEXT PRIMARY KEY NOT NULL,value BLOB NOT NULL,encrypted BOOL NOT NULL);"
|
||||||
|
|
||||||
|
_, err := d.con.Exec(q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *db) listTables() ([]string, error) {
|
func (d *db) listTables() ([]string, error) {
|
||||||
tables := []string{}
|
tables := []string{}
|
||||||
q := "SELECT name FROM sqlite_schema WHERE type ='table' AND name NOT LIKE 'sqlite_%' AND name LIKE ?"
|
q := "SELECT name FROM sqlite_schema WHERE type ='table' AND name NOT LIKE 'sqlite_%' AND name LIKE ?"
|
||||||
rows, err := d.con.Query(q, fmt.Sprintf("%s_%%", variables.DBTablePrefix))
|
|
||||||
if err != nil {
|
rows, err := d.con.Query(q, variables.DBTablePrefix+"_%%")
|
||||||
|
if err != nil || rows.Err() != nil {
|
||||||
return tables, err
|
return tables, err
|
||||||
}
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var table string
|
var table string
|
||||||
|
|
||||||
if err := rows.Scan(&table); err != nil {
|
if err := rows.Scan(&table); err != nil {
|
||||||
return tables, err
|
return tables, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tables = append(tables, tableNameToEnvName(table))
|
tables = append(tables, tableNameToEnvName(table))
|
||||||
}
|
}
|
||||||
|
|
||||||
return tables, nil
|
return tables, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *db) copyContentFromTo(table_name_target string, table_name_dest string) error {
|
func (d *db) copyContentFromTo(tableNameTarget string, tableNameDest string) error {
|
||||||
_, err := d.con.Exec(fmt.Sprintf("INSERT INTO %s (key, value, encrypted) SELECT * FROM %s", table_name_dest, table_name_target))
|
_, err := d.con.Exec(
|
||||||
|
fmt.Sprintf("INSERT INTO %s (key, value, encrypted) SELECT * FROM %s",
|
||||||
|
tableNameDest, tableNameTarget),
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *db) deleteTable(table_name string) error {
|
func (d *db) deleteTable(tableName string) error {
|
||||||
_, err := d.con.Exec(fmt.Sprintf("DROP TABLE IF EXISTS %s", table_name))
|
_, err := d.con.Exec("DROP TABLE IF EXISTS " + tableName)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *db) getVar(table_name string, key string) (*types.EnvVar, error) {
|
func (d *db) getVar(tableName string, key string) (*types.EnvVar, error) {
|
||||||
q := fmt.Sprintf("SELECT * FROM %s WHERE key=?", table_name)
|
q := "SELECT * FROM " + tableName + " WHERE key=?"
|
||||||
row := d.con.QueryRow(q, key)
|
row := d.con.QueryRow(q, key)
|
||||||
envVar := &types.EnvVar{}
|
envVar := &types.EnvVar{}
|
||||||
|
|
||||||
err := row.Scan(&envVar.Key, &envVar.Value, &envVar.Encrypted)
|
err := row.Scan(&envVar.Key, &envVar.Value, &envVar.Encrypted)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return envVar, errors.NewNoKeyFoundError(key)
|
return envVar, errors.NewNoKeyFoundError(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
return envVar, nil
|
return envVar, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *db) getAll(table_name string) ([]*types.EnvVar, error) {
|
func (d *db) getAll(tableName string) ([]*types.EnvVar, error) {
|
||||||
entries := []*types.EnvVar{}
|
entries := []*types.EnvVar{}
|
||||||
rows, err := d.con.Query(fmt.Sprintf("SELECT * FROM %s", table_name))
|
|
||||||
if err != nil {
|
rows, err := d.con.Query("SELECT * FROM " + tableName)
|
||||||
|
if err != nil || rows.Err() != nil {
|
||||||
return entries, err
|
return entries, err
|
||||||
}
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
key := ""
|
key := ""
|
||||||
value := ""
|
value := ""
|
||||||
enc := common.BoolP(false)
|
enc := common.BoolP(false)
|
||||||
|
|
||||||
err := rows.Scan(&key, &value, enc)
|
err := rows.Scan(&key, &value, enc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return entries, err
|
return entries, err
|
||||||
}
|
}
|
||||||
|
|
||||||
e := &types.EnvVar{
|
e := &types.EnvVar{
|
||||||
Key: key,
|
Key: key,
|
||||||
Value: value,
|
Value: value,
|
||||||
|
@ -105,27 +124,33 @@ func (d *db) getAll(table_name string) ([]*types.EnvVar, error) {
|
||||||
}
|
}
|
||||||
entries = append(entries, e)
|
entries = append(entries, e)
|
||||||
}
|
}
|
||||||
return entries, nil
|
|
||||||
|
|
||||||
|
return entries, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *db) setVar(table_name string, key string, value string, encrypted bool) error {
|
func (d *db) setVar(tableName string, key string, value string, encrypted bool) error {
|
||||||
q := fmt.Sprintf("INSERT INTO %s (key, value, encrypted) values ( ? , ? , ? ) ON CONFLICT (key) DO UPDATE SET value = ?, encrypted = ?", table_name)
|
q := "INSERT INTO " +
|
||||||
|
tableName +
|
||||||
|
" (key,value,encrypted) values (?,?,?) ON CONFLICT (key) DO UPDATE SET value=?, encrypted=?"
|
||||||
|
|
||||||
_, err := d.con.Exec(q, key, value, encrypted, value, encrypted)
|
_, err := d.con.Exec(q, key, value, encrypted, value, encrypted)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
|
||||||
return errors.NewSecretExsistsError(key)
|
return errors.NewSecretExsistsError(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *db) rmVar(table_name string, key string) {
|
func (d *db) rmVar(tableName string, key string) {
|
||||||
q := fmt.Sprintf("DELETE FROM %s WHERE key = ?", table_name)
|
q := "DELETE FROM " + tableName + " WHERE key = ?"
|
||||||
_, _ = d.con.Exec(q, key)
|
_, _ = d.con.Exec(q, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func envNameToTableName(envName string) string {
|
func envNameToTableName(envName string) string {
|
||||||
envSanke := common.StrToSnakeCase(envName)
|
envSanke := common.StrToSnakeCase(envName)
|
||||||
|
|
||||||
return fmt.Sprintf("%s_%s", variables.DBTablePrefix, envSanke)
|
return fmt.Sprintf("%s_%s", variables.DBTablePrefix, envSanke)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package errors
|
package errors
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
type EnvironmentExistsError struct {
|
type EnvironmentExistsError struct {
|
||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *EnvironmentExistsError) Error() string {
|
func (e *EnvironmentExistsError) Error() string {
|
||||||
return fmt.Sprintf("environment %s already exists", e.name)
|
return "environment " + e.name + " already exists"
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEnvironmentExistsError(name string) *EnvironmentExistsError {
|
func NewEnvironmentExistsError(name string) *EnvironmentExistsError {
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package errors
|
package errors
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
type InvalidCommandError struct {
|
type InvalidCommandError struct {
|
||||||
msg string
|
msg string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *InvalidCommandError) Error() string {
|
func (e *InvalidCommandError) Error() string {
|
||||||
return fmt.Sprintf("invalid command. %v", e.msg)
|
return "invalid command. " + e.msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInvalidCommandError(msg string) *InvalidCommandError {
|
func NewInvalidCommandError(msg string) *InvalidCommandError {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package errors
|
package errors
|
||||||
|
|
||||||
type InvalidPasswordError struct {
|
type InvalidPasswordError struct{}
|
||||||
}
|
|
||||||
|
|
||||||
func (e *InvalidPasswordError) Error() string {
|
func (e *InvalidPasswordError) Error() string {
|
||||||
return "invalid password. is your environment set correctly?"
|
return "invalid password. is your environment set correctly?"
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package errors
|
package errors
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
type NoKeyFoundError struct {
|
type NoKeyFoundError struct {
|
||||||
key string
|
key string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *NoKeyFoundError) Error() string {
|
func (e *NoKeyFoundError) Error() string {
|
||||||
return fmt.Sprintf("key %s not found", e.key)
|
return "key " + e.key + " not found"
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNoKeyFoundError(key string) *NoKeyFoundError {
|
func NewNoKeyFoundError(key string) *NoKeyFoundError {
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package errors
|
package errors
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
type NoConfigFoundError struct {
|
type NoConfigFoundError struct {
|
||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *NoConfigFoundError) Error() string {
|
func (e *NoConfigFoundError) Error() string {
|
||||||
return fmt.Sprintf("no config file found in %s", e.path)
|
return "no config file found in " + e.path
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNoConfigFoundError(path string) *NoConfigFoundError {
|
func NewNoConfigFoundError(path string) *NoConfigFoundError {
|
||||||
|
|
11
internal/errors/no_env_provided.go
Normal file
11
internal/errors/no_env_provided.go
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package errors
|
||||||
|
|
||||||
|
type NoEnvProvidedError struct{}
|
||||||
|
|
||||||
|
func (e *NoEnvProvidedError) Error() string {
|
||||||
|
return "You have more than 1 environment. please provide environment name"
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNoEnvProvidedError() *NoEnvProvidedError {
|
||||||
|
return &NoEnvProvidedError{}
|
||||||
|
}
|
|
@ -1,13 +1,11 @@
|
||||||
package errors
|
package errors
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
type ProjectEmptyError struct {
|
type ProjectEmptyError struct {
|
||||||
name string
|
name string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ProjectEmptyError) Error() string {
|
func (e *ProjectEmptyError) Error() string {
|
||||||
return fmt.Sprintf("Project %s does not have any environments.", e.name)
|
return "Project " + e.name + " does not have any environments."
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProjectEmptyError(name string) *ProjectEmptyError {
|
func NewProjectEmptyError(name string) *ProjectEmptyError {
|
||||||
|
|
|
@ -9,15 +9,20 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func PasswordPrompt(label string) string {
|
func PasswordPrompt(label string) string {
|
||||||
var s string
|
var str string
|
||||||
|
|
||||||
for {
|
for {
|
||||||
fmt.Fprint(os.Stderr, label+" ")
|
fmt.Fprint(os.Stderr, label+" ")
|
||||||
b, _ := term.ReadPassword(int(syscall.Stdin))
|
|
||||||
s = string(b)
|
b, _ := term.ReadPassword(syscall.Stdin)
|
||||||
if s != "" {
|
|
||||||
|
str = string(b)
|
||||||
|
if str != "" {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
return s
|
|
||||||
|
return str
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,18 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func StringPrompt(label string) string {
|
func StringPrompt(label string) string {
|
||||||
var s string
|
var str string
|
||||||
|
|
||||||
r := bufio.NewReader(os.Stdin)
|
r := bufio.NewReader(os.Stdin)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
fmt.Fprint(os.Stderr, label+" ")
|
fmt.Fprint(os.Stderr, label+" ")
|
||||||
s, _ = r.ReadString('\n')
|
|
||||||
if s != "" {
|
str, _ = r.ReadString('\n')
|
||||||
|
if str != "" {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return strings.TrimSpace(s)
|
|
||||||
|
return strings.TrimSpace(str)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,12 @@ type Project struct {
|
||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
Environments []*Environment `json:"envorinments" default:"[]"`
|
Environments []*Environment `default:"[]" json:"envorinments"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) GetEnv(name string) (*Environment, error) {
|
func (p *Project) GetEnv(name string) (*Environment, error) {
|
||||||
var e *Environment
|
var e *Environment
|
||||||
|
|
||||||
for _, env := range p.Environments {
|
for _, env := range p.Environments {
|
||||||
if env.Name == name {
|
if env.Name == name {
|
||||||
passByte, err := base64.RawStdEncoding.DecodeString(p.Password)
|
passByte, err := base64.RawStdEncoding.DecodeString(p.Password)
|
||||||
|
@ -24,32 +25,39 @@ func (p *Project) GetEnv(name string) (*Environment, error) {
|
||||||
fmt.Printf("[ERROR] Failed to decode project password @ %s. %e\n", p.Path, err)
|
fmt.Printf("[ERROR] Failed to decode project password @ %s. %e\n", p.Path, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
e = &Environment{
|
e = &Environment{
|
||||||
Name: env.Name,
|
Name: env.Name,
|
||||||
Password: string(passByte),
|
Password: string(passByte),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return nil, errors.NewEnvironmentNotFoundError(p.Path, name)
|
return nil, errors.NewEnvironmentNotFoundError(p.Path, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return e, nil
|
return e, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) NewEnv(name string) error {
|
func (p *Project) NewEnv(name string) error {
|
||||||
e := &Environment{
|
e := &Environment{
|
||||||
Name: name,
|
Name: name,
|
||||||
}
|
}
|
||||||
p.Environments = append(p.Environments, e)
|
p.Environments = append(p.Environments, e)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) RemoveEnv(name string) {
|
func (p *Project) RemoveEnv(name string) {
|
||||||
environments := []*Environment{}
|
environments := []*Environment{}
|
||||||
|
|
||||||
for _, env := range p.Environments {
|
for _, env := range p.Environments {
|
||||||
if env.Name != name {
|
if env.Name != name {
|
||||||
environments = append(environments, env)
|
environments = append(environments, env)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Environments = environments
|
p.Environments = environments
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package variables
|
package variables
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Commit string = "HEAD"
|
Commit = "HEAD"
|
||||||
Version string = "development"
|
Version = "development"
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue