Skip to content
This repository has been archived by the owner on Mar 3, 2023. It is now read-only.

Commit

Permalink
Merge pull request #3 from asunlabs/feature/watchOnlyExistingEnvs
Browse files Browse the repository at this point in the history
Feature/watch only existing envs
  • Loading branch information
developerasun authored Nov 7, 2022
2 parents c9ae168 + 985fde7 commit bb6c7b5
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 59 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Configs
# env file list
.env
.env.production
.env.development
.env.test
.env.dev
.env.prod

# Owlly binaries
owlly-for-mac
owlly-for-mac-m1
owlly.exe
Expand Down
43 changes: 27 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<div align="center">
<img src="https://user-images.githubusercontent.com/83855174/200222357-3e74436c-36be-41f9-8da6-519052db15bf.png" alt="owlly banner" width="100%" />
<img src="https://user-images.githubusercontent.com/83855174/200222357-3e74436c-36be-41f9-8da6-519052db15bf.png" alt="banner" width="100%" />
</div>

# 🦉 Owlly

<img src="https://img.shields.io/badge/version-v0.1.3-red" alt="version 0.1.3" />
<img src="https://img.shields.io/badge/version-v0.1.4-red" alt="version 0.1.4" />

A file-based .env change notifier for your slack team.

<img src="https://user-images.githubusercontent.com/83855174/198875029-f20bba16-66e6-48d2-9d06-9feaea8fe175.gif" height="400px" alt="owlly banner" width="100%" />
<img src="https://user-images.githubusercontent.com/83855174/200312951-eec9e105-1772-4afa-b0ae-233d5fbda28d.gif" alt="demo" width="100%" />

## Contents
## Table of Contents

- [Owlly](#owlly)
- [Features](#features)
Expand All @@ -23,7 +23,7 @@ A file-based .env change notifier for your slack team.
## Features

- Auto-sync .env file changes
- Watch multiple .env files: .env, .env.test, .env.development, .env.production
- Watch multiple .env files
- Auto-post the update to slack channel as attachment
- Basic metadata supported: timestamp, .env directory
- Cross platform supported: Windows, Mac OS(intel, m1 chip)
Expand All @@ -48,6 +48,23 @@ Or, simply download binaries from [release](https://github.com/asunlabs/owlly/re

## Prerequisite

### Assumption

Owlly will check if below files exist in your project root and sync if exist.

```go
envList = []string{
".env",
".env.test",
".env.development",
".env.production",
".env.dev",
".env.prod",
}
```

### Slack

In order to use Owlly, you have to

1. Create a slack bot
Expand All @@ -66,26 +83,20 @@ SLACK_CHANNEL_ID="channel-id-here"

## Usage

1. Make sure you have all .env files in project root

```
.env, .env.test, .env.production, .env.development
```

2. Update .env files as you wish.
1. Update .env files as you wish.

```sh
FOO="bar"
```

3. Once done, set OWLLY_DONE variable in your .env. This variable will be a key for Owlly to know if your update is done.
2. Once done, set OWLLY_DONE variable in your .env. This variable will be a key for Owlly to know if your update is done.

```sh
# length of OWLLY_DONE > 0 ? send a DM : do nothing
OWLLY_DONE="true"
```

4. Run Owlly to watch .env changes.
3. Run Owlly

```sh
# if you cloned a repo,
Expand All @@ -97,9 +108,9 @@ go run owlly.go
./owlly-for-mac-m1
```

Check your slack channel if the message is sent. Result will look like below.
Check your slack channel if the message is sent. Result will look like below.

<img src="hhttps://user-images.githubusercontent.com/83855174/198875580-ba52d111-907a-43bf-8937-23b5558378a4.png" height="400px" alt="owlly banner" width="100%" />
<img src="https://user-images.githubusercontent.com/83855174/200310048-48d918c4-2478-4d60-a68a-906202b1a8db.png" height="400px" alt="owlly banner" width="100%" />

**Note**

Expand Down
138 changes: 96 additions & 42 deletions owlly.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@ var (
watcher *fsnotify.Watcher
api *slack.Client
onlyOnce sync.Once
envList = []string{".env", ".env.test", ".env.development", ".env.production"}
envList = []string{
".env",
".env.test",
".env.development",
".env.production",
".env.dev",
".env.prod",
}
)

func nilChecker(err error) {
Expand All @@ -41,23 +48,50 @@ func getEnvList() []string {
return envList
}

func hasNamedEnvFiles(filePath string) bool {
var result bool

_, fErr := os.Stat(filePath)

if os.IsNotExist(fErr) {
result = false
}

if !os.IsNotExist(fErr) {
result = true
}

return result
}

// @dev start watching multiple envs
func registerEnvs() {
for _, v := range getEnvList() {
wd, _ := os.Getwd()
filePath := strings.Join([]string{wd, "/", v}, "")

wErr := watcher.Add(filePath)
nilChecker(wErr)
color.Blue(fmt.Sprintf("watching: %v", v))
// add only existing envs
ok := hasNamedEnvFiles(filePath)

if ok {
wErr := watcher.Add(filePath)
nilChecker(wErr)
color.Blue(fmt.Sprintf("watching: %v", v))
}
}
}

// @dev load multiple envs and init slack instance
func initSlack() {
for _, v := range envList {
lErr := godotenv.Load(v)
nilChecker(lErr)
wd, _ := os.Getwd()
filePath := strings.Join([]string{wd, "/", v}, "")
ok := hasNamedEnvFiles(filePath)

if ok {
lErr := godotenv.Load(v)
nilChecker(lErr)
}
}

_api := slack.New(os.Getenv("SLACK_BOT_USER_OAUTH_TOKEN"))
Expand All @@ -66,67 +100,83 @@ func initSlack() {

connectionMsg := fmt.Sprintf("slack API connected to: %s", res.Team)
color.Green(connectionMsg)

api = _api
}

func updateEnvs() {
wd, _ := os.Getwd()

for _, v := range getEnvList() {
data, rErr := os.ReadFile(v)
nilChecker(rErr)

wrapDirName := "config"
wrapDirPath := strings.Join([]string{wd, "/", wrapDirName, "/"}, "")
wrapEnvName := strings.Join([]string{v, ".", wrapDirName}, "")
wrapEnvFile := strings.Join([]string{wrapDirPath, wrapEnvName}, "")

// @dev owning user has a read and write permission: 0644
os.WriteFile(wrapEnvFile, data, fs.FileMode(config.OWNER_PERM))
wd, _ := os.Getwd()
filePath := strings.Join([]string{wd, "/", v}, "")

ok := hasNamedEnvFiles(filePath)

if ok {
data, rErr := os.ReadFile(v)
nilChecker(rErr)

wrapDirName := "config"
wrapDirPath := strings.Join([]string{wd, "/", wrapDirName, "/"}, "")
wrapEnvName := strings.Join([]string{v, ".", wrapDirName}, "")
wrapEnvFile := strings.Join([]string{wrapDirPath, wrapEnvName}, "")

// @dev owning user has a read and write permission: 0644
os.WriteFile(wrapEnvFile, data, fs.FileMode(config.OWNER_PERM))
}
}
}

func cleanupEnvs() {
userEnvList := []string{}
wd, _ := os.Getwd()
for _, v := range getEnvList() {
fullPathForWrapEnv := strings.Join([]string{wd, "/", "config", "/", v, ".config"}, "")
_, sErr := os.Stat(fullPathForWrapEnv)

if ok := os.IsExist(sErr); ok {
rErr := os.Remove(fullPathForWrapEnv)
nilChecker(rErr)
for _, v := range getEnvList() {
ok := hasNamedEnvFiles(strings.Join([]string{wd, "/", v}, ""))
if ok {
userEnvList = append(userEnvList, v)
}
}

for _, v := range userEnvList {
fullPathForWrapEnv := strings.Join([]string{wd, "/", "config", "/", v, ".config"}, "")

rErr := os.Remove(fullPathForWrapEnv)
nilChecker(rErr)

_, cErr := os.Create(fullPathForWrapEnv)
nilChecker(cErr)

_data, rErr := os.ReadFile(v)
nilChecker(rErr)

wErr := os.WriteFile(fullPathForWrapEnv, _data, fs.FileMode(config.OWNER_PERM))
nilChecker(wErr)
}

color.Red("envs config setup done")
}

func sendSlackDM() {
wd, _ := os.Getwd()

// has

envStringMapForWrapEnv := make(map[string]string)
envStringForWrapEnv := "DEFAULT_VALUE"

for _, v := range getEnvList() {
if isDone := isUpdateFinished(); isDone[v] {
fullPathForWrapEnv := strings.Join([]string{wd, "/", "config", "/", v, ".config"}, "")
wrapEnvName := strings.Join([]string{v, ".config"}, "")
filePath := strings.Join([]string{wd, "/", v}, "")

envStringForWrapEnv = convertEnvMapToString(fullPathForWrapEnv, wrapEnvName)
envStringMapForWrapEnv[wrapEnvName] = envStringForWrapEnv
ok := hasNamedEnvFiles(filePath)

notifyEnvChange(envStringMapForWrapEnv[wrapEnvName], v)
if ok {
if isDone := isUpdateFinished(); isDone[v] {

fullPathForWrapEnv := strings.Join([]string{wd, "/", "config", "/", v, ".config"}, "")
wrapEnvName := strings.Join([]string{v, ".config"}, "")

envStringForWrapEnv = convertEnvMapToString(fullPathForWrapEnv, wrapEnvName)
envStringMapForWrapEnv[wrapEnvName] = envStringForWrapEnv

notifyEnvChange(envStringMapForWrapEnv[wrapEnvName], v)
}
}
}
}
Expand All @@ -139,12 +189,16 @@ func isUpdateFinished() map[string]bool {
wd, _ := os.Getwd()
fullPath := strings.Join([]string{wd, "/", v}, "")

_data, _rErr := os.ReadFile(fullPath)
nilChecker(_rErr)
data := string(_data)
ok := hasNamedEnvFiles(fullPath)

hasOwllyTrigger := strings.Contains(data, config.RESERVED)
isDone[v] = hasOwllyTrigger
if ok {
_data, _rErr := os.ReadFile(fullPath)
nilChecker(_rErr)
data := string(_data)

hasOwllyTrigger := strings.Contains(data, config.RESERVED)
isDone[v] = hasOwllyTrigger
}
}

return isDone
Expand Down

0 comments on commit bb6c7b5

Please sign in to comment.