commit
b1d3486324
|
@ -6,4 +6,10 @@ go:
|
||||||
- tip
|
- tip
|
||||||
matrix:
|
matrix:
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- go: tip
|
- go: tip
|
||||||
|
|
||||||
|
install:
|
||||||
|
- go get ./...
|
||||||
|
|
||||||
|
script:
|
||||||
|
- go install .
|
328
README.md
328
README.md
|
@ -17,176 +17,206 @@ A Go build system with file watchers, output streams and live reload. Run, build
|
||||||
#### Features
|
#### Features
|
||||||
|
|
||||||
- Highly customizable
|
- Highly customizable
|
||||||
|
- Config your project Step by Step
|
||||||
- Build, Install, Test, Fmt, Generate and Run at the same time
|
- Build, Install, Test, Fmt, Generate and Run at the same time
|
||||||
- Live reload on file changes (re-build, re-install...)
|
- Live reload on file changes (re-build, re-install...)
|
||||||
- Watch custom paths and specific file extensions
|
- Watch custom paths and specific file extensions
|
||||||
|
- Watch by FsNotify or by polling
|
||||||
- Support for multiple projects
|
- Support for multiple projects
|
||||||
- Output streams and error logs (Watch them in console or save them on a file)
|
- Output streams and error logs (support for save on a file)
|
||||||
- Web Panel (Watch all projects, edit the config settings, download each type of log)
|
- Web Panel (projects list, config settings, logs)
|
||||||
|
|
||||||
#### Installation and usage
|
#### Wiki
|
||||||
|
|
||||||
- Run this to get/install:
|
- [Getting Started](#installation-and-usage)
|
||||||
|
- [Run cmd](#run) - Run a project
|
||||||
|
- [Add cmd](#add) - Add a new project
|
||||||
|
- [Init cmd](#init) - Make a custom config step by step
|
||||||
|
- [Remove cmd](#remove) - Remove a project
|
||||||
|
- [List cmd](#list) - List the projects
|
||||||
|
- [Config sample](#config-sample)
|
||||||
|
- [Support](#support)
|
||||||
|
|
||||||
```
|
|
||||||
$ go get github.com/tockins/realize
|
|
||||||
```
|
|
||||||
|
|
||||||
- From project/projects root execute:
|
- ##### Installation
|
||||||
|
Run this to get/install:
|
||||||
```
|
```
|
||||||
$ realize add
|
$ go get github.com/tockins/realize
|
||||||
```
|
```
|
||||||
|
#### Commands
|
||||||
It will create a realize.yaml file if it doesn't exist already and adds the working directory as project.
|
|
||||||
|
|
||||||
Otherwise if a config file already exists it adds the working project to the existing config file.
|
|
||||||
|
|
||||||
The Add command supports the following custom parameters:
|
|
||||||
|
|
||||||
```
|
|
||||||
--name="Project Name" -> Name, if not specified takes the working directory name
|
|
||||||
--path="server" -> Custom Path, if not specified takes the working directory name
|
|
||||||
--build -> Enables the build
|
|
||||||
--test -> Enables the tests
|
|
||||||
--no-bin -> Disables the installation
|
|
||||||
--no-run -> Disables the run
|
|
||||||
--no-fmt -> Disables the fmt (go fmt)
|
|
||||||
--no-server -> Disables the web panel (default port 5001)
|
|
||||||
--open -> Open the web panel in a new browser window
|
|
||||||
```
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ realize add
|
|
||||||
|
|
||||||
$ realize add --path="mypath"
|
|
||||||
|
|
||||||
$ realize add --name="My Project" --build
|
|
||||||
|
|
||||||
$ realize add --name="My Project" --path="/projects/package" --build
|
|
||||||
|
|
||||||
$ realize add --name="My Project" --path="projects/package" --build --no-run
|
|
||||||
|
|
||||||
$ realize add --path="/Users/alessio/go/src/github.com/tockins/realize-examples/coin/"
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want, you can specify additional arguments for your project.
|
|
||||||
|
|
||||||
**The additional arguments must go after the options of "Realize"**
|
|
||||||
|
|
||||||
```
|
|
||||||
$ realize add --path="/print/printer" --no-run yourParams --yourFlags // correct
|
|
||||||
|
|
||||||
$ realize add yourParams --yourFlags --path="/print/printer" --no-run // wrong
|
|
||||||
```
|
|
||||||
|
|
||||||
- Remove a project by its name
|
|
||||||
|
|
||||||
```
|
|
||||||
$ realize remove --name="Project Name"
|
|
||||||
```
|
|
||||||
- Lists all projects
|
|
||||||
|
|
||||||
```
|
|
||||||
$ realize list
|
|
||||||
```
|
|
||||||
- Build, Run and watch file changes. Realize will re-build and re-run your projects on each change.
|
|
||||||
|
|
||||||
|
- ##### Run
|
||||||
|
From project/projects root execute:
|
||||||
```
|
```
|
||||||
$ realize run
|
$ realize run
|
||||||
```
|
```
|
||||||
|
|
||||||
Run can also launch a project from its working directory with or without make a config file (--no-config option).
|
It will create a realize.yaml file if it doesn't exist already, adds the working directory as project and run the pipeline.
|
||||||
It supports the following custom parameters:
|
|
||||||
|
The Run command supports the following custom parameters:
|
||||||
|
|
||||||
```
|
```
|
||||||
--path="server" -> Custom Path, if not specified takes the working directory name
|
--path="realize/server" -> Custom Path, if not specified takes the working directory name
|
||||||
--build -> Enables the build
|
--build -> Enable go build
|
||||||
--test -> Enables the tests
|
--no-run -> Disable go run
|
||||||
--config -> Take the defined settings if exist a config file
|
--no-install -> Disable go install
|
||||||
--no-bin -> Disables the installation
|
--no-config -> Ignore an existing config / skip the creation of a new one
|
||||||
--no-run -> Disables the run
|
--server -> Enable the web server
|
||||||
--no-fmt -> Disables the fmt (go fmt)
|
--legacy -> Enable legacy watch instead of Fsnotify watch
|
||||||
--no-server -> Disables the web panel (port :5000)
|
--generate -> Enable go generate
|
||||||
--no-config -> Doesn't create any configuration files
|
--test -> Enable go test
|
||||||
--open -> Open the web panel in a new browser window
|
```
|
||||||
```
|
Examples:
|
||||||
And additional arguments as the "add" command.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
$ realize run --no-run yourParams --yourFlags // correct
|
$ realize run
|
||||||
|
$ realize run --path="mypath"
|
||||||
$ realize run yourParams --yourFlags --no-run // wrong
|
$ realize run --name="My Project" --build
|
||||||
|
$ realize run --path="realize" --no-run --no-config
|
||||||
$ realize run --path="/Users/alessio/go/src/github.com/tockins/realize-examples/coin/"
|
$ realize run --path="/Users/alessio/go/src/github.com/tockins/realize-examples/coin/"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you want, you can specify additional arguments for your project.
|
||||||
|
|
||||||
|
**The additional arguments must go after the params**
|
||||||
|
|
||||||
|
**Run can run a project from its working directory without make a config file (--no-config).**
|
||||||
|
|
||||||
|
```
|
||||||
|
$ realize run --path="/print/printer" --no-run yourParams --yourFlags // right
|
||||||
|
$ realize run yourParams --yourFlags --path="/print/printer" --no-run // wrong
|
||||||
|
```
|
||||||
|
- ##### Add
|
||||||
|
Add a project to an existing config file or create a new one without run the pipeline.
|
||||||
|
|
||||||
|
"Add" supports the same parameters of the "Run" command.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ realize add
|
||||||
|
```
|
||||||
|
|
||||||
#### Color reference
|
- ##### Init
|
||||||
|
Like add, but with this command you can create a configuration step by step and customize each option.
|
||||||
|
|
||||||
|
**Init is the only command that supports a complete customization of all the options supported**
|
||||||
|
|
||||||
|
```
|
||||||
|
$ realize init
|
||||||
|
```
|
||||||
|
|
||||||
- Blue: outputs of the project
|
- ##### Remove
|
||||||
- Red: errors
|
Remove a project by its name
|
||||||
- Magenta: times or changed files
|
```
|
||||||
- Green: successfully completed action
|
$ realize remove --name="myname"
|
||||||
|
```
|
||||||
|
|
||||||
|
- ##### List
|
||||||
|
Projects list in cli
|
||||||
|
```
|
||||||
|
$ realize list
|
||||||
|
```
|
||||||
|
|
||||||
|
- #### Color reference
|
||||||
|
- Blue: outputs of the project
|
||||||
|
- Red: errors
|
||||||
|
- Magenta: times or changed files
|
||||||
|
- Green: successfully completed action
|
||||||
|
|
||||||
|
|
||||||
#### Config file example
|
- #### Config sample
|
||||||
|
|
||||||
- For more examples check [Realize Examples](https://github.com/tockins/realize-examples)
|
For more examples check [Realize Examples](https://github.com/tockins/realize-examples)
|
||||||
|
|
||||||
```
|
```
|
||||||
settings:
|
settings:
|
||||||
resources:
|
legacy:
|
||||||
output: outputs.log // name of the output file
|
status: true // legacy watch status
|
||||||
log: logs.log // name of the log file (errors included)
|
interval: 10s // polling interval
|
||||||
server:
|
resources: // files names related to streams
|
||||||
enable: true // enables the web server
|
outputs: outputs.log
|
||||||
open: false // opens the web server in a new tab
|
logs: logs.log
|
||||||
host: localhost // web server host
|
errors: errors.log
|
||||||
port: 5000 // wev server port
|
server:
|
||||||
config:
|
status: true // server status
|
||||||
flimit: 0 // increases the maximum number of open files - supported only on linux or os x, sudo required
|
open: false // auto open in browser on start
|
||||||
projects:
|
host: localhost // server host
|
||||||
- name: printer // project name
|
port: 5001 // server port
|
||||||
path: / // project path
|
projects:
|
||||||
run: true // enables go run (require bin)
|
- name: realize
|
||||||
bin: true // enables go install
|
path: . // project path
|
||||||
generate: false // enables go generate
|
fmt: true
|
||||||
build: false // enables go build
|
generate: false
|
||||||
fmt: true // enables go fmt
|
test: false
|
||||||
test: false // enables go test
|
bin: true
|
||||||
params: [] // array of additionals params. the project will be launched with these parameters
|
build: false
|
||||||
watcher:
|
run: false
|
||||||
before: [] // custom commands launched before the execution of the project
|
params: // additional params
|
||||||
after: [] // custom commands launched after the execution of the project
|
- --myarg
|
||||||
paths: // paths to observe for live reload
|
watcher:
|
||||||
- /
|
preview: false // wached files preview
|
||||||
ignore_paths: // paths to ignore
|
paths: // paths to watch
|
||||||
- vendor
|
- /
|
||||||
exts: // file extensions to observe for live reload
|
ignore_paths: // paths to ignore
|
||||||
- .go
|
- vendor
|
||||||
preview: true // prints the observed files on startup
|
exts: // exts to watch
|
||||||
cli:
|
- .go
|
||||||
streams: true // prints the output streams of the project in the cli
|
scripts: // custom commands after/before
|
||||||
file:
|
- type: after // type after/before
|
||||||
streams: false // saves the output stream of the project in a file
|
command: go run mycmd after // command
|
||||||
logs: false // saves the logs of the project in a file
|
path: "" // run from a custom path or from the working dir
|
||||||
errors: false // saves the errors of the project in a file
|
streams: // enable/disable streams
|
||||||
```
|
cli_out: true
|
||||||
|
file_out: false
|
||||||
#### Next features, in progress...
|
file_log: false
|
||||||
|
file_err: false
|
||||||
- [ ] Web panel - edit settings (full support)
|
|
||||||
- [ ] Web panel - logs download
|
```
|
||||||
- [ ] Schedule - reload a project after a specific time
|
This is the configuration used for develop realize
|
||||||
- [ ] Easy dependencies - automatically resolve the project dependencies
|
|
||||||
- [ ] Import license - retrieve the license for each imported library
|
```
|
||||||
- [ ] Tests
|
settings:
|
||||||
|
resources:
|
||||||
|
outputs: outputs.log
|
||||||
|
logs: logs.log
|
||||||
|
errors: errors.log
|
||||||
|
server:
|
||||||
|
status: false
|
||||||
|
open: false
|
||||||
|
host: localhost
|
||||||
|
port: 5001
|
||||||
|
projects:
|
||||||
|
- name: realize
|
||||||
|
path: /Users/alessio/go/src/github.com/tockins/realize
|
||||||
|
fmt: true
|
||||||
|
generate: false
|
||||||
|
test: false
|
||||||
|
bin: true
|
||||||
|
build: false
|
||||||
|
run: false
|
||||||
|
watcher:
|
||||||
|
preview: false
|
||||||
|
paths:
|
||||||
|
- /
|
||||||
|
ignore_paths:
|
||||||
|
- server/assets
|
||||||
|
exts:
|
||||||
|
- .go
|
||||||
|
scripts:
|
||||||
|
- type: before
|
||||||
|
command: go-bindata -pkg="server" assets/...
|
||||||
|
path: server
|
||||||
|
- type: after
|
||||||
|
command: go-bindata -pkg="server" assets/...
|
||||||
|
path: server
|
||||||
|
streams:
|
||||||
|
cli_out: true
|
||||||
|
file_out: false
|
||||||
|
file_log: false
|
||||||
|
file_err: false
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
#### Contacts
|
###### Support us and suggest an improvement
|
||||||
|
- Start the project
|
||||||
- Chat with us [Gitter](https://gitter.im/tockins/realize)
|
- Chat with us [Gitter](https://gitter.im/tockins/realize)
|
||||||
|
- Suggest a new [Feature](https://github.com/tockins/realize/issues/new)
|
||||||
- [Alessio Pracchia](https://www.linkedin.com/in/alessio-pracchia-38a70673)
|
|
||||||
- [Daniele Conventi](https://www.linkedin.com/in/conventi)
|
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
{
|
||||||
|
"memo": "0dae7877c338a668c3b0b2c64112895cd2076b90c0792ca2a0edf22fb10d14d2",
|
||||||
|
"projects": [
|
||||||
|
{
|
||||||
|
"name": "github.com/dgrijalva/jwt-go",
|
||||||
|
"version": "v3.0.0",
|
||||||
|
"revision": "d2709f9f1f31ebcda9651b03077758c1f3a0018c",
|
||||||
|
"packages": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "github.com/fatih/color",
|
||||||
|
"version": "v1.4.1",
|
||||||
|
"revision": "9131ab34cf20d2f6d83fdc67168a5430d1c7dc23",
|
||||||
|
"packages": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "github.com/fsnotify/fsnotify",
|
||||||
|
"branch": "master",
|
||||||
|
"revision": "4da3e2cfbabc9f751898f250b49f2439785783a1",
|
||||||
|
"packages": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "github.com/labstack/echo",
|
||||||
|
"version": "v3.0.3",
|
||||||
|
"revision": "8d504c1b699c757b267255c53b3e5219f9974abc",
|
||||||
|
"packages": [
|
||||||
|
".",
|
||||||
|
"middleware"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "github.com/labstack/gommon",
|
||||||
|
"version": "v0.2.0",
|
||||||
|
"revision": "9cedb429ffbe71a32a3ae7c65fd109cb7ae07804",
|
||||||
|
"packages": [
|
||||||
|
"bytes",
|
||||||
|
"color",
|
||||||
|
"log",
|
||||||
|
"random"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "github.com/mattn/go-colorable",
|
||||||
|
"version": "v0.0.7",
|
||||||
|
"revision": "d228849504861217f796da67fae4f6e347643f15",
|
||||||
|
"packages": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "github.com/mattn/go-isatty",
|
||||||
|
"version": "v0.0.2",
|
||||||
|
"revision": "fc9e8d8ef48496124e79ae0df75490096eccf6fe",
|
||||||
|
"packages": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "github.com/tockins/interact",
|
||||||
|
"branch": "master",
|
||||||
|
"revision": "7dfb115b4849a7d87b2b8368a076959c2bf56e35",
|
||||||
|
"packages": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "github.com/tylerb/graceful",
|
||||||
|
"version": "v1.2.15",
|
||||||
|
"revision": "4654dfbb6ad53cb5e27f37d99b02e16c1872fbbb",
|
||||||
|
"packages": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "github.com/valyala/bytebufferpool",
|
||||||
|
"branch": "master",
|
||||||
|
"revision": "e746df99fe4a3986f4d4f79e13c1e0117ce9c2f7",
|
||||||
|
"packages": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "github.com/valyala/fasttemplate",
|
||||||
|
"branch": "master",
|
||||||
|
"revision": "dcecefd839c4193db0d35b88ec65b4c12d360ab0",
|
||||||
|
"packages": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "golang.org/x/crypto",
|
||||||
|
"branch": "master",
|
||||||
|
"revision": "3cb07270c9455e8ad27956a70891c962d121a228",
|
||||||
|
"packages": [
|
||||||
|
"acme",
|
||||||
|
"acme/autocert"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "golang.org/x/net",
|
||||||
|
"branch": "master",
|
||||||
|
"revision": "ffcf1bedda3b04ebb15a168a59800a73d6dc0f4d",
|
||||||
|
"packages": [
|
||||||
|
"context",
|
||||||
|
"context/ctxhttp",
|
||||||
|
"websocket"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "golang.org/x/sys",
|
||||||
|
"branch": "master",
|
||||||
|
"revision": "9a7256cb28ed514b4e1e5f68959914c4c28a92e0",
|
||||||
|
"packages": [
|
||||||
|
"unix"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "gopkg.in/urfave/cli.v2",
|
||||||
|
"branch": "v2",
|
||||||
|
"revision": "04b2f4ff79cf1fd71e138bafc67df8bbdb5b81c2",
|
||||||
|
"packages": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "gopkg.in/yaml.v2",
|
||||||
|
"branch": "v2",
|
||||||
|
"revision": "a3f3340b5840cee44f372bddb5880fcbc419b46a",
|
||||||
|
"packages": [
|
||||||
|
"."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"github.com/fatih/color": {
|
||||||
|
"branch": "master"
|
||||||
|
},
|
||||||
|
"github.com/fsnotify/fsnotify": {
|
||||||
|
"branch": "master"
|
||||||
|
},
|
||||||
|
"github.com/labstack/echo": {
|
||||||
|
"version": "^3.0.3"
|
||||||
|
},
|
||||||
|
"github.com/tockins/interact": {
|
||||||
|
"branch": "master"
|
||||||
|
},
|
||||||
|
"golang.org/x/net": {
|
||||||
|
"branch": "master"
|
||||||
|
},
|
||||||
|
"gopkg.in/urfave/cli.v2": {
|
||||||
|
"branch": "v2"
|
||||||
|
},
|
||||||
|
"gopkg.in/yaml.v2": {
|
||||||
|
"branch": "v2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
825
realize.go
825
realize.go
|
@ -3,25 +3,27 @@ package main
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/fatih/color"
|
||||||
|
i "github.com/tockins/interact"
|
||||||
s "github.com/tockins/realize/server"
|
s "github.com/tockins/realize/server"
|
||||||
c "github.com/tockins/realize/settings"
|
c "github.com/tockins/realize/settings"
|
||||||
w "github.com/tockins/realize/watcher"
|
w "github.com/tockins/realize/watcher"
|
||||||
"gopkg.in/urfave/cli.v2"
|
"gopkg.in/urfave/cli.v2"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
name = "Realize"
|
name = "Realize"
|
||||||
version = "1.2.1"
|
version = "1.3"
|
||||||
description = "A Go build system with file watchers, output streams and live reload. Run, build and watch file changes with custom paths"
|
description = "A Go build system with file watchers, output streams and live reload. Run, build and watch file changes with custom paths"
|
||||||
config = "realize.yaml"
|
config = "realize.yaml"
|
||||||
streams = "streams.log"
|
outputs = "outputs.log"
|
||||||
errs = "errors.log"
|
errs = "errors.log"
|
||||||
logs = "logs.log"
|
logs = "logs.log"
|
||||||
host = "localhost"
|
host = "localhost"
|
||||||
port = 5001
|
port = 5001
|
||||||
server = true
|
interval = 200
|
||||||
open = false
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var r realize
|
var r realize
|
||||||
|
@ -45,19 +47,19 @@ func init() {
|
||||||
Sync: make(chan string),
|
Sync: make(chan string),
|
||||||
Settings: c.Settings{
|
Settings: c.Settings{
|
||||||
Config: c.Config{
|
Config: c.Config{
|
||||||
Flimit: 0,
|
Create: true,
|
||||||
},
|
},
|
||||||
Resources: c.Resources{
|
Resources: c.Resources{
|
||||||
Config: config,
|
Config: config,
|
||||||
Streams: streams,
|
Outputs: outputs,
|
||||||
Logs: logs,
|
Logs: logs,
|
||||||
Errors: errs,
|
Errors: errs,
|
||||||
},
|
},
|
||||||
Server: c.Server{
|
Server: c.Server{
|
||||||
Enabled: server,
|
Status: false,
|
||||||
Open: open,
|
Open: false,
|
||||||
Host: host,
|
Host: host,
|
||||||
Port: port,
|
Port: port,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -83,8 +85,6 @@ func init() {
|
||||||
|
|
||||||
// Before of every exec of a cli method
|
// Before of every exec of a cli method
|
||||||
func before() error {
|
func before() error {
|
||||||
fmt.Println(r.Blue.Bold(name) + " - " + r.Blue.Bold(version))
|
|
||||||
fmt.Println(r.Blue.Regular(description) + "\n")
|
|
||||||
gopath := os.Getenv("GOPATH")
|
gopath := os.Getenv("GOPATH")
|
||||||
if gopath == "" {
|
if gopath == "" {
|
||||||
return handle(errors.New("$GOPATH isn't set up properly"))
|
return handle(errors.New("$GOPATH isn't set up properly"))
|
||||||
|
@ -103,59 +103,49 @@ func handle(err error) error {
|
||||||
|
|
||||||
// Cli commands
|
// Cli commands
|
||||||
func main() {
|
func main() {
|
||||||
c := &cli.App{
|
app := &cli.App{
|
||||||
Name: r.Name,
|
Name: r.Name,
|
||||||
Version: r.Version,
|
Version: r.Version,
|
||||||
Authors: []*cli.Author{
|
Authors: []*cli.Author{
|
||||||
{
|
{
|
||||||
Name: "Alessio Pracchia",
|
Name: "Alessio Pracchia",
|
||||||
Email: "pracchia@hastegit",
|
Email: "pracchia@hastega.it",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Daniele Conventi",
|
Name: "Daniele Conventi",
|
||||||
Email: "conventi@hastegit",
|
Email: "conventi@hastega.it",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Usage: r.Description,
|
Usage: r.Description,
|
||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
{
|
{
|
||||||
Name: "run",
|
Name: "run",
|
||||||
Usage: "Build and watch file changes. Can be used even with a single project or without the config file",
|
Aliases: []string{"r"},
|
||||||
|
Usage: "Run a toolchain on a project or a list of projects. If not exist a config file it creates a new one.",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{Name: "path", Aliases: []string{"b"}, Value: "", Usage: "Project base path"},
|
&cli.StringFlag{Name: "path", Aliases: []string{"p"}, Value: "", Usage: "Project base path."},
|
||||||
&cli.BoolFlag{Name: "build", Value: false, Usage: "Enables the build"},
|
&cli.BoolFlag{Name: "test", Aliases: []string{"t"}, Value: false, Usage: "Enable go test."},
|
||||||
&cli.BoolFlag{Name: "no-run", Usage: "Disables the run"},
|
&cli.BoolFlag{Name: "generate", Aliases: []string{"g"}, Value: false, Usage: "Enable go generate."},
|
||||||
&cli.BoolFlag{Name: "no-bin", Usage: "Disables the installation"},
|
&cli.BoolFlag{Name: "build", Aliases: []string{"b"}, Value: false, Usage: "Enable go build."},
|
||||||
&cli.BoolFlag{Name: "no-fmt", Usage: "Disables the fmt (go fmt)"},
|
&cli.BoolFlag{Name: "legacy", Aliases: []string{"l"}, Value: false, Usage: "Watch by polling instead of Watch by fsnotify."},
|
||||||
&cli.BoolFlag{Name: "no-server", Usage: "Disables the web panel"},
|
&cli.BoolFlag{Name: "server", Aliases: []string{"s"}, Value: false, Usage: "Enable server and open into the default browser."},
|
||||||
&cli.BoolFlag{Name: "no-config", Value: false, Usage: "Uses the config settings"},
|
&cli.BoolFlag{Name: "no-run", Aliases: []string{"nr"}, Value: false, Usage: "Disable go run"},
|
||||||
&cli.BoolFlag{Name: "open", Usage: "Automatically opens the web panel"},
|
&cli.BoolFlag{Name: "no-install", Aliases: []string{"ni"}, Value: false, Usage: "Disable go install"},
|
||||||
&cli.IntFlag{Name: "port", Usage: "Sets the web panel port"},
|
&cli.BoolFlag{Name: "no-config", Aliases: []string{"nc"}, Value: false, Usage: "Ignore existing configurations."},
|
||||||
&cli.BoolFlag{Name: "test", Value: false, Usage: "Enables the tests"},
|
|
||||||
},
|
},
|
||||||
Action: func(p *cli.Context) error {
|
Action: func(p *cli.Context) error {
|
||||||
if p.Bool("no-config") {
|
if p.Bool("legacy") {
|
||||||
r.Settings = c.Settings{
|
r.Config.Legacy = c.Legacy{
|
||||||
Config: c.Config{
|
Status: p.Bool("legacy"),
|
||||||
Flimit: 0,
|
Interval: interval,
|
||||||
},
|
|
||||||
Resources: c.Resources{
|
|
||||||
Config: config,
|
|
||||||
Streams: streams,
|
|
||||||
Logs: logs,
|
|
||||||
Errors: errs,
|
|
||||||
},
|
|
||||||
Server: c.Server{
|
|
||||||
Enabled: server,
|
|
||||||
Open: open,
|
|
||||||
Host: host,
|
|
||||||
Port: port,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
r.Blueprint.Projects = r.Blueprint.Projects[:0]
|
}
|
||||||
r.Blueprint.Add(p)
|
if p.Bool("no-config") || len(r.Blueprint.Projects) <= 0 {
|
||||||
} else if len(r.Blueprint.Projects) <= 0 {
|
if p.Bool("no-config") {
|
||||||
r.Blueprint.Add(p)
|
r.Config.Create = false
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects = []w.Project{}
|
||||||
|
handle(r.Blueprint.Add(p))
|
||||||
}
|
}
|
||||||
handle(r.Server.Start(p))
|
handle(r.Server.Start(p))
|
||||||
handle(r.Blueprint.Run())
|
handle(r.Blueprint.Run())
|
||||||
|
@ -170,20 +160,717 @@ func main() {
|
||||||
Name: "add",
|
Name: "add",
|
||||||
Category: "Configuration",
|
Category: "Configuration",
|
||||||
Aliases: []string{"a"},
|
Aliases: []string{"a"},
|
||||||
Usage: "Add another project",
|
Usage: "Add a project to an existing config file or create a new one.",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: r.Wdir(), Usage: "Project name"},
|
&cli.StringFlag{Name: "path", Aliases: []string{"p"}, Value: "", Usage: "Project base path."},
|
||||||
&cli.StringFlag{Name: "path", Aliases: []string{"b"}, Value: "/", Usage: "Project base path"},
|
&cli.BoolFlag{Name: "test", Aliases: []string{"t"}, Value: false, Usage: "Enable go test."},
|
||||||
&cli.BoolFlag{Name: "build", Value: false, Usage: "Enable the build"},
|
&cli.BoolFlag{Name: "generate", Aliases: []string{"g"}, Value: false, Usage: "Enable go generate."},
|
||||||
&cli.BoolFlag{Name: "no-run", Usage: "Disables the run"},
|
&cli.BoolFlag{Name: "build", Aliases: []string{"b"}, Value: false, Usage: "Enable go build."},
|
||||||
&cli.BoolFlag{Name: "no-bin", Usage: "Disables the installation"},
|
&cli.BoolFlag{Name: "legacy", Aliases: []string{"l"}, Value: false, Usage: "Watch by polling instead of Watch by fsnotify."},
|
||||||
&cli.BoolFlag{Name: "no-fmt", Usage: "Disables the fmt (go fmt)"},
|
&cli.BoolFlag{Name: "server", Aliases: []string{"s"}, Value: false, Usage: "Enable server and open into the default browser."},
|
||||||
&cli.BoolFlag{Name: "test", Value: false, Usage: "Enables the tests"},
|
&cli.BoolFlag{Name: "no-run", Aliases: []string{"nr"}, Value: false, Usage: "Disable go run"},
|
||||||
|
&cli.BoolFlag{Name: "no-fmt", Aliases: []string{"nf"}, Value: false, Usage: "Disable go fmt."},
|
||||||
|
&cli.BoolFlag{Name: "no-install", Aliases: []string{"ni"}, Value: false, Usage: "Disable go install"},
|
||||||
|
&cli.BoolFlag{Name: "no-config", Aliases: []string{"nc"}, Value: false, Usage: "Ignore existing configurations."},
|
||||||
},
|
},
|
||||||
Action: func(p *cli.Context) (err error) {
|
Action: func(p *cli.Context) (err error) {
|
||||||
handle(r.Blueprint.Insert(p))
|
fmt.Println(p.String("path"))
|
||||||
|
handle(r.Blueprint.Add(p))
|
||||||
handle(r.Record(r))
|
handle(r.Record(r))
|
||||||
fmt.Println(r.Green.Bold("Your project was successfully added"))
|
fmt.Println(r.Yellow.Bold("[")+"REALIZE"+r.Yellow.Bold("]"), r.Green.Bold("Your project was successfully added."))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Before: func(c *cli.Context) error {
|
||||||
|
return before()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "init",
|
||||||
|
Category: "Configuration",
|
||||||
|
Aliases: []string{"a"},
|
||||||
|
Usage: "Define a new config file with all options step by step",
|
||||||
|
Action: func(p *cli.Context) (err error) {
|
||||||
|
i.Run(&i.Interact{
|
||||||
|
Before: func(context i.Context) error {
|
||||||
|
context.SetErr(r.Red.Bold("INVALID INPUT"))
|
||||||
|
context.SetPrfx(color.Output, r.Yellow.Bold("[")+"REALIZE"+r.Yellow.Bold("]"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Questions: []*i.Question{
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
if _, err := os.Stat(".realize/" + config); err != nil {
|
||||||
|
d.Skip()
|
||||||
|
}
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Would you want to overwrite the existing " + r.Colors.Magenta.Bold("Realize") + " config?",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
} else if val {
|
||||||
|
r.Settings = c.Settings{
|
||||||
|
Config: c.Config{
|
||||||
|
Create: true,
|
||||||
|
},
|
||||||
|
Resources: c.Resources{
|
||||||
|
Config: config,
|
||||||
|
Outputs: outputs,
|
||||||
|
Logs: logs,
|
||||||
|
Errors: errs,
|
||||||
|
},
|
||||||
|
Server: c.Server{
|
||||||
|
Status: false,
|
||||||
|
Open: false,
|
||||||
|
Host: host,
|
||||||
|
Port: port,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects = r.Blueprint.Projects[len(r.Blueprint.Projects):]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Would you want to customize the " + r.Colors.Magenta.Bold("settings") + "?",
|
||||||
|
Resolve: func(d i.Context) bool {
|
||||||
|
val, _ := d.Ans().Bool()
|
||||||
|
return val
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Subs: []*i.Question{
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(0, r.Green.Regular("(os default)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[int]"),
|
||||||
|
Msg: "Max number of open files (root required)",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Int()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Config.Flimit = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Enable legacy watch by polling",
|
||||||
|
Resolve: func(d i.Context) bool {
|
||||||
|
val, _ := d.Ans().Bool()
|
||||||
|
return val
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Subs: []*i.Question{
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(1, r.Green.Regular("(1s)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[seconds]"),
|
||||||
|
Msg: "Set polling interval in seconds",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Int()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Config.Legacy.Interval = time.Duration(val * 1000000000)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Config.Legacy.Status = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Enable web server",
|
||||||
|
Resolve: func(d i.Context) bool {
|
||||||
|
val, _ := d.Ans().Bool()
|
||||||
|
return val
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Subs: []*i.Question{
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(5001, r.Green.Regular("(5001)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[int]"),
|
||||||
|
Msg: "Server port",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Int()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Server.Port = int(val)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef("localhost", r.Green.Regular("(localhost)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[string]"),
|
||||||
|
Msg: "Server host",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().String()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Server.Host = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Open in the current browser",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Server.Open = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Server.Status = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
_, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(true, r.Green.Regular("(y)"))
|
||||||
|
d.SetEnd("!")
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Would you want to " + r.Colors.Magenta.Regular("add a new project") + "? (insert '!' to stop)",
|
||||||
|
Resolve: func(d i.Context) bool {
|
||||||
|
val, _ := d.Ans().Bool()
|
||||||
|
if val {
|
||||||
|
r.Blueprint.Add(p)
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Subs: []*i.Question{
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(r.Settings.Wdir(), r.Green.Regular("("+r.Settings.Wdir()+")"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[string]"),
|
||||||
|
Msg: "Project name",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().String()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Name = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
dir, _ := os.Getwd()
|
||||||
|
d.SetDef(dir, r.Green.Regular("("+dir+")"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[string]"),
|
||||||
|
Msg: "Project path",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().String()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Path = r.Settings.Path(val)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(true, r.Green.Regular("(y)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Enable go fmt",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Fmt = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Enable go test",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Test = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Enable go generate",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Generate = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(true, r.Green.Regular("(y)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Enable go install",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Bin = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Enable go build",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Build = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(true, r.Green.Regular("(y)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Enable go run",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Run = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Customize the watched paths",
|
||||||
|
Resolve: func(d i.Context) bool {
|
||||||
|
val, _ := d.Ans().Bool()
|
||||||
|
if val {
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Watcher.Paths = r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Watcher.Paths[:len(r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Watcher.Paths)-1]
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Subs: []*i.Question{
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetEnd("!")
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[string]"),
|
||||||
|
Msg: "Insert a path to watch (insert '!' to stop)",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().String()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Watcher.Paths = append(r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Watcher.Paths, val)
|
||||||
|
d.Reload()
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
_, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Customize the ignored paths",
|
||||||
|
Resolve: func(d i.Context) bool {
|
||||||
|
val, _ := d.Ans().Bool()
|
||||||
|
if val {
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Watcher.Ignore = r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Watcher.Ignore[:len(r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Watcher.Ignore)-1]
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Subs: []*i.Question{
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetEnd("!")
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[string]"),
|
||||||
|
Msg: "Insert a path to ignore (insert '!' to stop)",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().String()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Watcher.Ignore = append(r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Watcher.Ignore, val)
|
||||||
|
d.Reload()
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
_, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Add additionals arguments",
|
||||||
|
Resolve: func(d i.Context) bool {
|
||||||
|
val, _ := d.Ans().Bool()
|
||||||
|
return val
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Subs: []*i.Question{
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetEnd("!")
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[string]"),
|
||||||
|
Msg: "Insert an argument (insert '!' to stop)",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().String()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Params = append(r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Params, val)
|
||||||
|
d.Reload()
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
_, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Add 'before' custom commands",
|
||||||
|
Resolve: func(d i.Context) bool {
|
||||||
|
val, _ := d.Ans().Bool()
|
||||||
|
return val
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Subs: []*i.Question{
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetEnd("!")
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[string]"),
|
||||||
|
Msg: "Insert a command (insert '!' to stop)",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().String()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Watcher.Scripts = append(r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Watcher.Scripts, w.Command{Type: "before", Command: val})
|
||||||
|
d.Reload()
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
_, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Add 'after' custom commands",
|
||||||
|
Resolve: func(d i.Context) bool {
|
||||||
|
val, _ := d.Ans().Bool()
|
||||||
|
return val
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Subs: []*i.Question{
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetEnd("!")
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[string]"),
|
||||||
|
Msg: "Insert a command (insert '!' to stop)",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().String()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Watcher.Scripts = append(r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Watcher.Scripts, w.Command{Type: "after", Command: val})
|
||||||
|
d.Reload()
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
_, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Enable watcher files preview",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Watcher.Preview = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Enable file output history",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Streams.FileOut = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Enable file logs history",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Streams.FileLog = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Before: func(d i.Context) error {
|
||||||
|
d.SetDef(false, r.Green.Regular("(n)"))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Quest: i.Quest{
|
||||||
|
Options: r.Yellow.Regular("[y/n]"),
|
||||||
|
Msg: "Enable file errors history",
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
val, err := d.Ans().Bool()
|
||||||
|
if err != nil {
|
||||||
|
return d.Err()
|
||||||
|
}
|
||||||
|
r.Blueprint.Projects[len(r.Blueprint.Projects)-1].Streams.FileErr = val
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(d i.Context) interface{} {
|
||||||
|
if val, err := d.Ans().Bool(); err != nil {
|
||||||
|
return d.Err()
|
||||||
|
} else if val {
|
||||||
|
d.Reload()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
After: func(d i.Context) error {
|
||||||
|
if val, _ := d.Qns().Get(0).Ans().Bool(); val {
|
||||||
|
err = r.Settings.Remove()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
handle(r.Record(r))
|
||||||
|
fmt.Println(r.Yellow.Bold("[")+"REALIZE"+r.Yellow.Bold("]"), r.Green.Bold("Your configuration was successful."))
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Before: func(c *cli.Context) error {
|
Before: func(c *cli.Context) error {
|
||||||
|
@ -194,14 +881,14 @@ func main() {
|
||||||
Name: "remove",
|
Name: "remove",
|
||||||
Category: "Configuration",
|
Category: "Configuration",
|
||||||
Aliases: []string{"r"},
|
Aliases: []string{"r"},
|
||||||
Usage: "Remove a project",
|
Usage: "Remove a project from a realize configuration.",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: ""},
|
&cli.StringFlag{Name: "name", Aliases: []string{"n"}, Value: ""},
|
||||||
},
|
},
|
||||||
Action: func(p *cli.Context) error {
|
Action: func(p *cli.Context) error {
|
||||||
handle(r.Blueprint.Remove(p))
|
handle(r.Blueprint.Remove(p))
|
||||||
handle(r.Record(r))
|
handle(r.Record(r))
|
||||||
fmt.Println(r.Green.Bold("Your project was successfully removed."))
|
fmt.Println(r.Yellow.Bold("[")+"REALIZE"+r.Yellow.Bold("]"), r.Green.Bold("Your project was successfully removed."))
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Before: func(c *cli.Context) error {
|
Before: func(c *cli.Context) error {
|
||||||
|
@ -212,7 +899,7 @@ func main() {
|
||||||
Name: "list",
|
Name: "list",
|
||||||
Category: "Configuration",
|
Category: "Configuration",
|
||||||
Aliases: []string{"l"},
|
Aliases: []string{"l"},
|
||||||
Usage: "Projects list",
|
Usage: "Print projects list.",
|
||||||
Action: func(p *cli.Context) error {
|
Action: func(p *cli.Context) error {
|
||||||
return handle(r.Blueprint.List())
|
return handle(r.Blueprint.List())
|
||||||
},
|
},
|
||||||
|
@ -220,7 +907,21 @@ func main() {
|
||||||
return before()
|
return before()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "clean",
|
||||||
|
Category: "Configuration",
|
||||||
|
Aliases: []string{"c"},
|
||||||
|
Usage: "Remove realize folder.",
|
||||||
|
Action: func(p *cli.Context) error {
|
||||||
|
handle(r.Settings.Remove())
|
||||||
|
fmt.Println(r.Yellow.Bold("[")+"REALIZE"+r.Yellow.Bold("]"), r.Green.Bold("Realize folder successfully removed."))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Before: func(c *cli.Context) error {
|
||||||
|
return before()
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
c.Run(os.Args)
|
app.Run(os.Args)
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -48,12 +48,11 @@ func render(c echo.Context, path string, mime int) error {
|
||||||
|
|
||||||
// Start the web server
|
// Start the web server
|
||||||
func (s *Server) Start(p *cli.Context) (err error) {
|
func (s *Server) Start(p *cli.Context) (err error) {
|
||||||
if p.Int("port") != 0 {
|
if s.Server.Status || p.Bool("server") {
|
||||||
s.Settings.Server.Port = p.Int("port")
|
|
||||||
}
|
|
||||||
if !p.Bool("no-server") && s.Enabled {
|
|
||||||
e := echo.New()
|
e := echo.New()
|
||||||
e.Use(middleware.Gzip())
|
e.Use(middleware.GzipWithConfig(middleware.GzipConfig{
|
||||||
|
Level: 2,
|
||||||
|
}))
|
||||||
e.Use(middleware.Recover())
|
e.Use(middleware.Recover())
|
||||||
|
|
||||||
// web panel
|
// web panel
|
||||||
|
@ -95,8 +94,6 @@ func (s *Server) Start(p *cli.Context) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
s.Server.Enabled = false
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@ import "syscall"
|
||||||
// Flimit defines the max number of watched files
|
// Flimit defines the max number of watched files
|
||||||
func (s *Settings) Flimit() {
|
func (s *Settings) Flimit() {
|
||||||
var rLimit syscall.Rlimit
|
var rLimit syscall.Rlimit
|
||||||
rLimit.Max = s.Config.Flimit
|
rLimit.Max = uint64(s.Config.Flimit)
|
||||||
rLimit.Cur = s.Config.Flimit
|
rLimit.Cur = uint64(s.Config.Flimit)
|
||||||
err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit)
|
err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Fatal(err, "Error setting rlimit")
|
s.Fatal(err, "Error setting rlimit")
|
||||||
|
|
|
@ -3,33 +3,42 @@ package settings
|
||||||
import (
|
import (
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Settings defines a group of general settings
|
// Settings defines a group of general settings
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
Colors `yaml:"-"`
|
Colors `yaml:"-"`
|
||||||
|
Config `yaml:",inline" json:"config"`
|
||||||
Resources `yaml:"resources" json:"resources"`
|
Resources `yaml:"resources" json:"resources"`
|
||||||
Server `yaml:"server" json:"server"`
|
Server `yaml:"server,omitempty" json:"server,omitempty"`
|
||||||
Config `yaml:"config" json:"config"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config defines structural options
|
// Config defines structural options
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Flimit uint64 `yaml:"flimit" json:"flimit"`
|
Create bool `yaml:"-" json:"-"`
|
||||||
|
Flimit int64 `yaml:"flimit,omitempty" json:"flimit,omitempty"`
|
||||||
|
Legacy `yaml:"legacy,omitempty" json:"legacy,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Legacy configuration
|
||||||
|
type Legacy struct {
|
||||||
|
Status bool `yaml:"status" json:"status"`
|
||||||
|
Interval time.Duration `yaml:"interval" json:"interval"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server settings, used for the web panel
|
// Server settings, used for the web panel
|
||||||
type Server struct {
|
type Server struct {
|
||||||
Enabled bool `yaml:"enable" json:"enable"`
|
Status bool `yaml:"status" json:"status"`
|
||||||
Open bool `yaml:"open" json:"open"`
|
Open bool `yaml:"open" json:"open"`
|
||||||
Host string `yaml:"host" json:"host"`
|
Host string `yaml:"host" json:"host"`
|
||||||
Port int `yaml:"port" json:"port"`
|
Port int `yaml:"port" json:"port"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resources defines the files generated by realize
|
// Resources defines the files generated by realize
|
||||||
type Resources struct {
|
type Resources struct {
|
||||||
Config string `yaml:"-" json:"-"`
|
Config string `yaml:"-" json:"-"`
|
||||||
Streams string `yaml:"streams" json:"output"`
|
Outputs string `yaml:"outputs" json:"outputs"`
|
||||||
Logs string `yaml:"logs" json:"log"`
|
Logs string `yaml:"logs" json:"log"`
|
||||||
Errors string `yaml:"errors" json:"error"`
|
Errors string `yaml:"errors" json:"error"`
|
||||||
}
|
}
|
||||||
|
@ -50,14 +59,25 @@ func (s *Settings) Read(out interface{}) error {
|
||||||
|
|
||||||
// Record create and unmarshal the yaml config file
|
// Record create and unmarshal the yaml config file
|
||||||
func (s *Settings) Record(out interface{}) error {
|
func (s *Settings) Record(out interface{}) error {
|
||||||
y, err := yaml.Marshal(out)
|
if s.Config.Create {
|
||||||
if err != nil {
|
y, err := yaml.Marshal(out)
|
||||||
return err
|
if err != nil {
|
||||||
}
|
return err
|
||||||
if _, err := os.Stat(".realize/"); os.IsNotExist(err) {
|
|
||||||
if err = os.Mkdir(".realize/", 0770); err != nil {
|
|
||||||
return s.Write(s.Resources.Config, y)
|
|
||||||
}
|
}
|
||||||
|
if _, err := os.Stat(".realize/"); os.IsNotExist(err) {
|
||||||
|
if err = os.Mkdir(".realize/", 0770); err != nil {
|
||||||
|
return s.Write(s.Resources.Config, y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s.Write(".realize/"+s.Resources.Config, y)
|
||||||
}
|
}
|
||||||
return s.Write(".realize/"+s.Resources.Config, y)
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove realize folder
|
||||||
|
func (s *Settings) Remove() error {
|
||||||
|
if _, err := os.Stat(".realize/"); !os.IsNotExist(err) {
|
||||||
|
return os.RemoveAll(".realize/")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Wdir return the current working directory
|
// Wdir return the current working directory
|
||||||
|
@ -23,8 +24,24 @@ func (s Settings) Validate(err error) error {
|
||||||
|
|
||||||
// Fatal prints a fatal error with its additional messages
|
// Fatal prints a fatal error with its additional messages
|
||||||
func (s Settings) Fatal(err error, msg ...interface{}) {
|
func (s Settings) Fatal(err error, msg ...interface{}) {
|
||||||
if len(msg) > 0 {
|
if len(msg) > 0 && err != nil {
|
||||||
log.Fatalln(s.Red.Regular(msg...), err.Error())
|
log.Fatalln(s.Red.Regular(msg...), err.Error())
|
||||||
|
} else if err != nil {
|
||||||
|
log.Fatalln(err.Error())
|
||||||
}
|
}
|
||||||
log.Fatalln(err.Error())
|
}
|
||||||
|
|
||||||
|
// Name return the project name or the path of the working dir
|
||||||
|
func (s Settings) Name(name string, path string) string {
|
||||||
|
if name == "" && path == "" {
|
||||||
|
return s.Wdir()
|
||||||
|
} else if path != "/" {
|
||||||
|
return filepath.Base(path)
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path cleaner
|
||||||
|
func (s Settings) Path(path string) string {
|
||||||
|
return strings.Replace(filepath.Clean(path), "\\", "/", -1)
|
||||||
}
|
}
|
||||||
|
|
119
watcher/cmd.go
119
watcher/cmd.go
|
@ -4,7 +4,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"gopkg.in/urfave/cli.v2"
|
"gopkg.in/urfave/cli.v2"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,7 +15,12 @@ func (h *Blueprint) Run() error {
|
||||||
wg.Add(len(h.Projects))
|
wg.Add(len(h.Projects))
|
||||||
for k := range h.Projects {
|
for k := range h.Projects {
|
||||||
h.Projects[k].parent = h
|
h.Projects[k].parent = h
|
||||||
go h.Projects[k].watching()
|
h.Projects[k].path = h.Projects[k].Path
|
||||||
|
if h.Legacy.Status {
|
||||||
|
go h.Projects[k].watchByPolling()
|
||||||
|
} else {
|
||||||
|
go h.Projects[k].watchByNotify()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
return nil
|
return nil
|
||||||
|
@ -27,27 +31,27 @@ func (h *Blueprint) Run() error {
|
||||||
// Add a new project
|
// Add a new project
|
||||||
func (h *Blueprint) Add(p *cli.Context) error {
|
func (h *Blueprint) Add(p *cli.Context) error {
|
||||||
project := Project{
|
project := Project{
|
||||||
Name: h.name(p),
|
Name: h.Name(p.String("name"), p.String("path")),
|
||||||
Path: filepath.Clean(p.String("path")),
|
Path: h.Path(p.String("path")),
|
||||||
Build: p.Bool("build"),
|
Fmt: !p.Bool("no-fmt"),
|
||||||
Bin: !p.Bool("no-bin"),
|
Generate: p.Bool("generate"),
|
||||||
Run: !p.Bool("no-run"),
|
Test: p.Bool("test"),
|
||||||
Fmt: !p.Bool("no-fmt"),
|
Build: p.Bool("build"),
|
||||||
Test: p.Bool("test"),
|
Bin: !p.Bool("no-bin"),
|
||||||
Params: argsParam(p),
|
Run: !p.Bool("no-run"),
|
||||||
|
Params: argsParam(p),
|
||||||
Watcher: Watcher{
|
Watcher: Watcher{
|
||||||
Paths: []string{"/"},
|
Paths: []string{"/"},
|
||||||
Ignore: []string{"vendor"},
|
Ignore: []string{"vendor"},
|
||||||
Exts: []string{".go"},
|
Exts: []string{".go"},
|
||||||
Preview: false,
|
Preview: p.Bool("preview"),
|
||||||
|
Scripts: []Command{},
|
||||||
},
|
},
|
||||||
Cli: Cli{
|
Streams: Streams{
|
||||||
Streams: true,
|
CliOut: true,
|
||||||
},
|
FileOut: false,
|
||||||
File: File{
|
FileLog: false,
|
||||||
Streams: false,
|
FileErr: false,
|
||||||
Logs: false,
|
|
||||||
Errors: false,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if _, err := duplicates(project, h.Projects); err != nil {
|
if _, err := duplicates(project, h.Projects); err != nil {
|
||||||
|
@ -68,12 +72,6 @@ func (h *Blueprint) Clean() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert a new project in projects list
|
|
||||||
func (h *Blueprint) Insert(p *cli.Context) error {
|
|
||||||
err := h.Add(p)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove a project
|
// Remove a project
|
||||||
func (h *Blueprint) Remove(p *cli.Context) error {
|
func (h *Blueprint) Remove(p *cli.Context) error {
|
||||||
for key, val := range h.Projects {
|
for key, val := range h.Projects {
|
||||||
|
@ -90,39 +88,49 @@ func (h *Blueprint) List() error {
|
||||||
err := h.check()
|
err := h.check()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for _, val := range h.Projects {
|
for _, val := range h.Projects {
|
||||||
fmt.Println(h.Blue.Bold("|"), h.Blue.Bold(strings.ToUpper(val.Name)))
|
fmt.Println(h.Blue.Bold("[") + strings.ToUpper(val.Name) + h.Blue.Bold("]"))
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Base Path"), ":", h.Magenta.Regular(val.Path))
|
name := h.Magenta.Bold("[") + strings.ToUpper(val.Name) + h.Magenta.Bold("]")
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Run"), ":", h.Magenta.Regular(val.Run))
|
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Build"), ":", h.Magenta.Regular(val.Build))
|
fmt.Println(name, h.Yellow.Regular("Base Path"), ":", h.Magenta.Regular(val.Path))
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Install"), ":", h.Magenta.Regular(val.Bin))
|
fmt.Println(name, h.Yellow.Regular("Fmt"), ":", h.Magenta.Regular(val.Fmt))
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Fmt"), ":", h.Magenta.Regular(val.Fmt))
|
fmt.Println(name, h.Yellow.Regular("Generate"), ":", h.Magenta.Regular(val.Generate))
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Test"), ":", h.Magenta.Regular(val.Test))
|
fmt.Println(name, h.Yellow.Regular("Test"), ":", h.Magenta.Regular(val.Test))
|
||||||
|
fmt.Println(name, h.Yellow.Regular("Install"), ":", h.Magenta.Regular(val.Bin))
|
||||||
|
fmt.Println(name, h.Yellow.Regular("Build"), ":", h.Magenta.Regular(val.Build))
|
||||||
|
fmt.Println(name, h.Yellow.Regular("Run"), ":", h.Magenta.Regular(val.Run))
|
||||||
if len(val.Params) > 0 {
|
if len(val.Params) > 0 {
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Params"), ":", h.Magenta.Regular(val.Params))
|
fmt.Println(name, h.Yellow.Regular("Params"), ":", h.Magenta.Regular(val.Params))
|
||||||
}
|
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Watcher"), ":")
|
|
||||||
if len(val.Watcher.After) > 0 {
|
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("After"), ":", h.Magenta.Regular(val.Watcher.After))
|
|
||||||
}
|
|
||||||
if len(val.Watcher.Before) > 0 {
|
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Before"), ":", h.Magenta.Regular(val.Watcher.Before))
|
|
||||||
}
|
}
|
||||||
|
fmt.Println(name, h.Yellow.Regular("Watcher"), ":")
|
||||||
|
fmt.Println(name, "\t", h.Yellow.Regular("Preview"), ":", h.Magenta.Regular(val.Watcher.Preview))
|
||||||
if len(val.Watcher.Exts) > 0 {
|
if len(val.Watcher.Exts) > 0 {
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Extensions"), ":", h.Magenta.Regular(val.Watcher.Exts))
|
fmt.Println(name, "\t", h.Yellow.Regular("Extensions"), ":", h.Magenta.Regular(val.Watcher.Exts))
|
||||||
}
|
}
|
||||||
if len(val.Watcher.Paths) > 0 {
|
if len(val.Watcher.Paths) > 0 {
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Paths"), ":", h.Magenta.Regular(val.Watcher.Paths))
|
fmt.Println(name, "\t", h.Yellow.Regular("Paths"), ":", h.Magenta.Regular(val.Watcher.Paths))
|
||||||
}
|
}
|
||||||
if len(val.Watcher.Ignore) > 0 {
|
if len(val.Watcher.Ignore) > 0 {
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Ignored paths"), ":", h.Magenta.Regular(val.Watcher.Ignore))
|
fmt.Println(name, "\t", h.Yellow.Regular("Ignored paths"), ":", h.Magenta.Regular(val.Watcher.Ignore))
|
||||||
}
|
}
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Files preview"), ":", h.Magenta.Regular(val.Watcher.Preview))
|
if len(val.Watcher.Scripts) > 0 {
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("Cli"), ":")
|
fmt.Println(name, "\t", h.Yellow.Regular("Scripts"), ":")
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Streams"), ":", h.Magenta.Regular(val.Cli.Streams))
|
for _, v := range val.Watcher.Scripts {
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t", h.Yellow.Regular("File"), ":")
|
if v.Command != "" {
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Streams"), ":", h.Magenta.Regular(val.File.Streams))
|
fmt.Println(name, "\t\t", h.Magenta.Regular("-"), h.Yellow.Regular("Command"), ":", h.Magenta.Regular(v.Command))
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Logs"), ":", h.Magenta.Regular(val.File.Logs))
|
if v.Path != "" {
|
||||||
fmt.Println(h.Magenta.Regular("|"), "\t\t", h.Yellow.Regular("Errors"), ":", h.Magenta.Regular(val.File.Errors))
|
fmt.Println(name, "\t\t", h.Yellow.Regular("Path"), ":", h.Magenta.Regular(v.Path))
|
||||||
|
}
|
||||||
|
if v.Type != "" {
|
||||||
|
fmt.Println(name, "\t\t", h.Yellow.Regular("Type"), ":", h.Magenta.Regular(v.Type))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println(name, h.Yellow.Regular("Streams"), ":")
|
||||||
|
fmt.Println(name, "\t", h.Yellow.Regular("Cli Out"), ":", h.Magenta.Regular(val.Streams.CliOut))
|
||||||
|
fmt.Println(name, "\t", h.Yellow.Regular("File Out"), ":", h.Magenta.Regular(val.Streams.FileOut))
|
||||||
|
fmt.Println(name, "\t", h.Yellow.Regular("File Log"), ":", h.Magenta.Regular(val.Streams.FileLog))
|
||||||
|
fmt.Println(name, "\t", h.Yellow.Regular("File Err"), ":", h.Magenta.Regular(val.Streams.FileErr))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -137,16 +145,3 @@ func (h *Blueprint) check() error {
|
||||||
}
|
}
|
||||||
return errors.New("There are no projects. The config file is empty.")
|
return errors.New("There are no projects. The config file is empty.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// NameParam check the project name presence. If empty takes the working directory name
|
|
||||||
func (h *Blueprint) name(p *cli.Context) string {
|
|
||||||
var name string
|
|
||||||
if p.String("name") == "" && p.String("path") == "" {
|
|
||||||
return h.Wdir()
|
|
||||||
} else if p.String("path") != "/" {
|
|
||||||
name = filepath.Base(p.String("path"))
|
|
||||||
} else {
|
|
||||||
name = p.String("name")
|
|
||||||
}
|
|
||||||
return name
|
|
||||||
}
|
|
||||||
|
|
|
@ -34,6 +34,8 @@ func (p *Project) goRun(channel chan bool, runner chan bool, wr *sync.WaitGroup)
|
||||||
} else {
|
} else {
|
||||||
if _, err := os.Stat(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.path))); err == nil {
|
if _, err := os.Stat(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.path))); err == nil {
|
||||||
build = exec.Command(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.path)), params...)
|
build = exec.Command(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.path)), params...)
|
||||||
|
} else if _, err := os.Stat(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.path)) + ".exe"); err == nil {
|
||||||
|
build = exec.Command(filepath.Join(os.Getenv("GOBIN"), filepath.Base(p.path))+".exe", params...)
|
||||||
} else {
|
} else {
|
||||||
p.Buffer.StdLog = append(p.Buffer.StdLog, BufferOut{Time: time.Now(), Text: "Can't run a not compiled project"})
|
p.Buffer.StdLog = append(p.Buffer.StdLog, BufferOut{Time: time.Now(), Text: "Can't run a not compiled project"})
|
||||||
p.Fatal(err, "Can't run a not compiled project", ":")
|
p.Fatal(err, "Can't run a not compiled project", ":")
|
||||||
|
@ -139,14 +141,21 @@ func (p *Project) goTools(dir string, name string, cmd ...string) (string, error
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cmds exec a list of defined commands
|
// Exec an additional command from a defined path if specified
|
||||||
func (p *Project) afterBefore(command string) (errors string, logs string) {
|
func (p *Project) command(cmd Command) (errors string, logs string) {
|
||||||
var stdout bytes.Buffer
|
var stdout bytes.Buffer
|
||||||
var stderr bytes.Buffer
|
var stderr bytes.Buffer
|
||||||
command = strings.Replace(strings.Replace(command, "'", "", -1), "\"", "", -1)
|
command := strings.Replace(strings.Replace(cmd.Command, "'", "", -1), "\"", "", -1)
|
||||||
c := strings.Split(command, " ")
|
c := strings.Split(command, " ")
|
||||||
build := exec.Command(c[0], c[1:]...)
|
build := exec.Command(c[0], c[1:]...)
|
||||||
build.Dir = p.base
|
build.Dir = p.base
|
||||||
|
if cmd.Path != "" {
|
||||||
|
if strings.Contains(cmd.Path, p.base) {
|
||||||
|
build.Dir = cmd.Path
|
||||||
|
} else {
|
||||||
|
build.Dir = filepath.Join(p.base, cmd.Path)
|
||||||
|
}
|
||||||
|
}
|
||||||
build.Stdout = &stdout
|
build.Stdout = &stdout
|
||||||
build.Stderr = &stderr
|
build.Stderr = &stderr
|
||||||
err := build.Run()
|
err := build.Run()
|
||||||
|
|
|
@ -9,6 +9,16 @@ import (
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
// Watcher interface used by polling/fsnotify watching
|
||||||
|
type watcher interface {
|
||||||
|
Add(path string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Polling watcher
|
||||||
|
type pollWatcher struct {
|
||||||
|
paths map[string]bool
|
||||||
|
}
|
||||||
|
|
||||||
// Log struct
|
// Log struct
|
||||||
type logWriter struct {
|
type logWriter struct {
|
||||||
c.Colors
|
c.Colors
|
||||||
|
@ -29,15 +39,14 @@ type Project struct {
|
||||||
Name string `yaml:"name" json:"name"`
|
Name string `yaml:"name" json:"name"`
|
||||||
Path string `yaml:"path" json:"path"`
|
Path string `yaml:"path" json:"path"`
|
||||||
Fmt bool `yaml:"fmt" json:"fmt"`
|
Fmt bool `yaml:"fmt" json:"fmt"`
|
||||||
Test bool `yaml:"test" json:"test"`
|
|
||||||
Generate bool `yaml:"generate" json:"generate"`
|
Generate bool `yaml:"generate" json:"generate"`
|
||||||
|
Test bool `yaml:"test" json:"test"`
|
||||||
Bin bool `yaml:"bin" json:"bin"`
|
Bin bool `yaml:"bin" json:"bin"`
|
||||||
Build bool `yaml:"build" json:"build"`
|
Build bool `yaml:"build" json:"build"`
|
||||||
Run bool `yaml:"run" json:"run"`
|
Run bool `yaml:"run" json:"run"`
|
||||||
Params []string `yaml:"params" json:"params"`
|
Params []string `yaml:"params,omitempty" json:"params,omitempty"`
|
||||||
Watcher Watcher `yaml:"watcher" json:"watcher"`
|
Watcher Watcher `yaml:"watcher" json:"watcher"`
|
||||||
Cli Cli `yaml:"cli" json:"cli"`
|
Streams Streams `yaml:"streams" json:"streams"`
|
||||||
File File `yaml:"file" json:"file"`
|
|
||||||
Buffer Buffer `yaml:"-" json:"buffer"`
|
Buffer Buffer `yaml:"-" json:"buffer"`
|
||||||
parent *Blueprint
|
parent *Blueprint
|
||||||
path string
|
path string
|
||||||
|
@ -45,25 +54,26 @@ type Project struct {
|
||||||
|
|
||||||
// Watcher struct defines the livereload's logic
|
// Watcher struct defines the livereload's logic
|
||||||
type Watcher struct {
|
type Watcher struct {
|
||||||
// different before and after on re-run?
|
Preview bool `yaml:"preview" json:"preview"`
|
||||||
Before []string `yaml:"before" json:"before"`
|
Paths []string `yaml:"paths" json:"paths"`
|
||||||
After []string `yaml:"after" json:"after"`
|
Ignore []string `yaml:"ignore_paths" json:"ignore"`
|
||||||
Paths []string `yaml:"paths" json:"paths"`
|
Exts []string `yaml:"exts" json:"exts"`
|
||||||
Ignore []string `yaml:"ignore_paths" json:"ignore"`
|
Scripts []Command `yaml:"scripts,omitempty" json:"scripts,omitempty"`
|
||||||
Exts []string `yaml:"exts" json:"exts"`
|
|
||||||
Preview bool `yaml:"preview" json:"preview"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cli output status, enables or disables
|
// Command options
|
||||||
type Cli struct {
|
type Command struct {
|
||||||
Streams bool `yaml:"streams" json:"streams"`
|
Type string `yaml:"type" json:"type"`
|
||||||
|
Command string `yaml:"command" json:"command"`
|
||||||
|
Path string `yaml:"path" json:"path"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// File determinates the status of each log files (streams, logs, errors)
|
// Streams is a collection of names and values for the logs functionality
|
||||||
type File struct {
|
type Streams struct {
|
||||||
Streams bool `yaml:"streams" json:"streams"`
|
CliOut bool `yaml:"cli_out" json:"cli_out"`
|
||||||
Logs bool `yaml:"logs" json:"logs"`
|
FileOut bool `yaml:"file_out" json:"file_out"`
|
||||||
Errors bool `yaml:"errors" json:"errors"`
|
FileLog bool `yaml:"file_log" json:"file_log"`
|
||||||
|
FileErr bool `yaml:"file_err" json:"file_err"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffer define an array buffer for each log files
|
// Buffer define an array buffer for each log files
|
||||||
|
|
|
@ -23,8 +23,8 @@ func argsParam(params *cli.Context) []string {
|
||||||
// Duplicates check projects with same name or same combinations of main/path
|
// Duplicates check projects with same name or same combinations of main/path
|
||||||
func duplicates(value Project, arr []Project) (Project, error) {
|
func duplicates(value Project, arr []Project) (Project, error) {
|
||||||
for _, val := range arr {
|
for _, val := range arr {
|
||||||
if value.Path == val.Path || value.Name == val.Name {
|
if value.Path == val.Path {
|
||||||
return val, errors.New("There is a duplicate of '" + val.Name + "'. Check your config file!")
|
return val, errors.New("There is already a project for '" + val.Path + "'. Check your config file!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Project{}, nil
|
return Project{}, nil
|
||||||
|
|
|
@ -16,28 +16,113 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Watching method is the main core. It manages the livereload and the watching
|
var msg string
|
||||||
func (p *Project) watching() {
|
var out BufferOut
|
||||||
|
|
||||||
|
func (w *pollWatcher) Add(path string) error {
|
||||||
|
if w.paths == nil {
|
||||||
|
w.paths = map[string]bool{}
|
||||||
|
}
|
||||||
|
w.paths[path] = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *pollWatcher) isWatching(path string) bool {
|
||||||
|
a, b := w.paths[path]
|
||||||
|
return a && b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch the project by polling
|
||||||
|
func (p *Project) watchByPolling() {
|
||||||
var wr sync.WaitGroup
|
var wr sync.WaitGroup
|
||||||
var watcher *fsnotify.Watcher
|
var watcher = new(pollWatcher)
|
||||||
channel, exit := make(chan bool, 1), make(chan bool, 1)
|
channel, exit := make(chan bool, 1), make(chan os.Signal, 2)
|
||||||
p.path = p.Path
|
signal.Notify(exit, os.Interrupt, syscall.SIGTERM)
|
||||||
watcher, err := fsnotify.NewWatcher()
|
|
||||||
defer func() {
|
defer func() {
|
||||||
|
p.cmd("after")
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
if err != nil {
|
|
||||||
log.Fatalln(p.pname(p.Name, 2), ":", p.Red.Bold(err.Error()))
|
p.cmd("before")
|
||||||
return
|
p.Fatal(p.watch(watcher))
|
||||||
}
|
go p.routines(channel, &wr)
|
||||||
p.cmd(exit)
|
p.LastChangedOn = time.Now().Truncate(time.Second)
|
||||||
if p.walks(watcher) != nil {
|
walk := func(changed string, info os.FileInfo, err error) error {
|
||||||
log.Fatalln(p.pname(p.Name, 2), ":", p.Red.Bold(err.Error()))
|
var ext string
|
||||||
return
|
if err != nil {
|
||||||
}
|
return err
|
||||||
|
} else if !watcher.isWatching(changed) {
|
||||||
|
return nil
|
||||||
|
} else if !info.ModTime().Truncate(time.Second).After(p.LastChangedOn) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if index := strings.Index(filepath.Ext(changed), "_"); index == -1 {
|
||||||
|
ext = filepath.Ext(changed)
|
||||||
|
} else {
|
||||||
|
ext = filepath.Ext(changed)[0:index]
|
||||||
|
}
|
||||||
|
i := strings.Index(changed, filepath.Ext(changed))
|
||||||
|
file := changed[:i] + ext
|
||||||
|
path := filepath.Dir(changed[:i])
|
||||||
|
if changed[:i] != "" && inArray(ext, p.Watcher.Exts) {
|
||||||
|
if p.Run {
|
||||||
|
close(channel)
|
||||||
|
channel = make(chan bool)
|
||||||
|
}
|
||||||
|
p.LastChangedOn = time.Now().Truncate(time.Second)
|
||||||
|
// repeat the initial cycle
|
||||||
|
msg = fmt.Sprintln(p.pname(p.Name, 4), ":", p.Magenta.Bold(strings.ToUpper(ext[1:])+" changed"), p.Magenta.Bold(file))
|
||||||
|
out = BufferOut{Time: time.Now(), Text: strings.ToUpper(ext[1:]) + " changed " + file}
|
||||||
|
p.print("log", out, msg, "")
|
||||||
|
|
||||||
|
p.cmd("change")
|
||||||
|
p.fmt(file)
|
||||||
|
p.test(path)
|
||||||
|
p.generate(path)
|
||||||
|
go p.routines(channel, &wr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for {
|
||||||
|
for _, dir := range p.Watcher.Paths {
|
||||||
|
base := filepath.Join(p.base, dir)
|
||||||
|
if _, err := os.Stat(base); err == nil {
|
||||||
|
if err := filepath.Walk(base, walk); err != nil {
|
||||||
|
msg = fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Regular(err.Error()))
|
||||||
|
out = BufferOut{Time: time.Now(), Text: err.Error()}
|
||||||
|
p.print("error", out, msg, "")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
msg = fmt.Sprintln(p.pname(p.Name, 2), ":", base, "path doesn't exist")
|
||||||
|
out = BufferOut{Time: time.Now(), Text: base + " path doesn't exist"}
|
||||||
|
p.print("error", out, msg, "")
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case <-exit:
|
||||||
|
return
|
||||||
|
case <-time.After(p.parent.Legacy.Interval / time.Duration(len(p.Watcher.Paths))):
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch the project by fsnotify
|
||||||
|
func (p *Project) watchByNotify() {
|
||||||
|
var wr sync.WaitGroup
|
||||||
|
var watcher *fsnotify.Watcher
|
||||||
|
channel, exit := make(chan bool, 1), make(chan os.Signal, 2)
|
||||||
|
signal.Notify(exit, os.Interrupt, syscall.SIGTERM)
|
||||||
|
watcher, err := fsnotify.NewWatcher()
|
||||||
|
p.Fatal(err)
|
||||||
|
defer func() {
|
||||||
|
p.cmd("after")
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
p.cmd("before")
|
||||||
|
p.Fatal(p.watch(watcher))
|
||||||
go p.routines(channel, &wr)
|
go p.routines(channel, &wr)
|
||||||
p.LastChangedOn = time.Now().Truncate(time.Second)
|
p.LastChangedOn = time.Now().Truncate(time.Second)
|
||||||
// waiting for an event
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case event := <-watcher.Events:
|
case event := <-watcher.Events:
|
||||||
|
@ -56,176 +141,36 @@ func (p *Project) watching() {
|
||||||
file := event.Name[:i] + ext
|
file := event.Name[:i] + ext
|
||||||
path := filepath.Dir(event.Name[:i])
|
path := filepath.Dir(event.Name[:i])
|
||||||
if event.Name[:i] != "" && inArray(ext, p.Watcher.Exts) {
|
if event.Name[:i] != "" && inArray(ext, p.Watcher.Exts) {
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 4), ":", p.Magenta.Bold(strings.ToUpper(ext[1:])+" changed"), p.Magenta.Bold(file))
|
|
||||||
out := BufferOut{Time: time.Now(), Text: strings.ToUpper(ext[1:]) + " changed " + file}
|
|
||||||
p.print("log", out, msg, "")
|
|
||||||
// stop and run again
|
|
||||||
if p.Run {
|
if p.Run {
|
||||||
close(channel)
|
close(channel)
|
||||||
channel = make(chan bool)
|
channel = make(chan bool)
|
||||||
}
|
}
|
||||||
// handle multiple errors, need a better way
|
p.LastChangedOn = time.Now().Truncate(time.Second)
|
||||||
|
// repeat the initial cycle
|
||||||
|
msg = fmt.Sprintln(p.pname(p.Name, 4), ":", p.Magenta.Bold(strings.ToUpper(ext[1:])+" changed"), p.Magenta.Bold(file))
|
||||||
|
out = BufferOut{Time: time.Now(), Text: strings.ToUpper(ext[1:]) + " changed " + file}
|
||||||
|
p.print("log", out, msg, "")
|
||||||
|
|
||||||
|
p.cmd("change")
|
||||||
p.fmt(file)
|
p.fmt(file)
|
||||||
p.test(path)
|
p.test(path)
|
||||||
p.generate(path)
|
p.generate(path)
|
||||||
go p.routines(channel, &wr)
|
go p.routines(channel, &wr)
|
||||||
p.LastChangedOn = time.Now().Truncate(time.Second)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case err := <-watcher.Errors:
|
case err := <-watcher.Errors:
|
||||||
log.Println(p.Red.Bold(err.Error()))
|
msg = fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Regular(err.Error()))
|
||||||
|
out = BufferOut{Time: time.Now(), Text: err.Error()}
|
||||||
|
p.print("error", out, msg, "")
|
||||||
case <-exit:
|
case <-exit:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install calls an implementation of "go install"
|
// Watch the files tree of a project
|
||||||
func (p *Project) install() error {
|
func (p *Project) watch(watcher watcher) error {
|
||||||
if p.Bin {
|
|
||||||
start := time.Now()
|
|
||||||
log.Println(p.pname(p.Name, 1), ":", "Installing..")
|
|
||||||
stream, err := p.goInstall()
|
|
||||||
if err != nil {
|
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Install"), p.Red.Regular(err.Error()))
|
|
||||||
out := BufferOut{Time: time.Now(), Text: err.Error(), Type: "Go Install", Stream: stream}
|
|
||||||
p.print("error", out, msg, stream)
|
|
||||||
} else {
|
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Regular("Installed")+" after", p.Magenta.Regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s"))
|
|
||||||
out := BufferOut{Time: time.Now(), Text: "Installed after " + big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3) + " s"}
|
|
||||||
p.print("log", out, msg, stream)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Install calls an implementation of "go run"
|
|
||||||
func (p *Project) run(channel chan bool, wr *sync.WaitGroup) {
|
|
||||||
if p.Run {
|
|
||||||
start := time.Now()
|
|
||||||
runner := make(chan bool, 1)
|
|
||||||
log.Println(p.pname(p.Name, 1), ":", "Running..")
|
|
||||||
go p.goRun(channel, runner, wr)
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-runner:
|
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Regular("Has been run")+" after", p.Magenta.Regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s"))
|
|
||||||
out := BufferOut{Time: time.Now(), Text: "Has been run after " + big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3) + " s"}
|
|
||||||
p.print("log", out, msg, "")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build calls an implementation of the "go build"
|
|
||||||
func (p *Project) build() error {
|
|
||||||
if p.Build {
|
|
||||||
start := time.Now()
|
|
||||||
log.Println(p.pname(p.Name, 1), ":", "Building..")
|
|
||||||
stream, err := p.goBuild()
|
|
||||||
if err != nil {
|
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Build"), p.Red.Regular(err.Error()))
|
|
||||||
out := BufferOut{Time: time.Now(), Text: err.Error(), Type: "Go Build", Stream: stream}
|
|
||||||
p.print("error", out, msg, stream)
|
|
||||||
} else {
|
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Regular("Builded")+" after", p.Magenta.Regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s"))
|
|
||||||
out := BufferOut{Time: time.Now(), Text: "Builded after " + big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3) + " s"}
|
|
||||||
p.print("log", out, msg, stream)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fmt calls an implementation of the "go fmt"
|
|
||||||
func (p *Project) fmt(path string) error {
|
|
||||||
if p.Fmt && strings.HasSuffix(path, ".go") {
|
|
||||||
if stream, err := p.goTools(p.base, "gofmt", "-s", "-w", "-e", path); err != nil {
|
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Fmt"), p.Red.Regular("there are some errors in"), ":", p.Magenta.Bold(path))
|
|
||||||
out := BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: "Go Fmt", Stream: stream}
|
|
||||||
p.print("error", out, msg, stream)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate calls an implementation of the "go generate"
|
|
||||||
func (p *Project) generate(path string) error {
|
|
||||||
if p.Generate {
|
|
||||||
if stream, err := p.goTools(path, "go", "generate"); err != nil {
|
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Generate"), p.Red.Regular("there are some errors in"), ":", p.Magenta.Bold(path))
|
|
||||||
out := BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: "Go Generate", Stream: stream}
|
|
||||||
p.print("error", out, msg, stream)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test calls an implementation of the "go test"
|
|
||||||
func (p *Project) test(path string) error {
|
|
||||||
if p.Test {
|
|
||||||
if stream, err := p.goTools(path, "go", "test"); err != nil {
|
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Test"), p.Red.Regular("there are some errors in "), ":", p.Magenta.Bold(path))
|
|
||||||
out := BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: "Go Test", Stream: stream}
|
|
||||||
p.print("error", out, msg, stream)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cmd calls an wrapper for execute the commands after/before
|
|
||||||
func (p *Project) cmd(exit chan bool) {
|
|
||||||
c := make(chan os.Signal, 2)
|
|
||||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
|
||||||
cast := func(commands []string) {
|
|
||||||
for _, command := range commands {
|
|
||||||
errors, logs := p.afterBefore(command)
|
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Bold("Command"), p.Green.Bold("\"")+command+p.Green.Bold("\""))
|
|
||||||
out := BufferOut{Time: time.Now(), Text: command, Type: "After/Before"}
|
|
||||||
if logs != "" {
|
|
||||||
p.print("log", out, msg, "")
|
|
||||||
}
|
|
||||||
if errors != "" {
|
|
||||||
p.print("error", out, msg, "")
|
|
||||||
}
|
|
||||||
if logs != "" {
|
|
||||||
msg = fmt.Sprintln(logs)
|
|
||||||
out = BufferOut{Time: time.Now(), Text: logs, Type: "After/Before"}
|
|
||||||
p.print("log", out, "", msg)
|
|
||||||
}
|
|
||||||
if errors != "" {
|
|
||||||
msg = fmt.Sprintln(p.Red.Regular(errors))
|
|
||||||
out = BufferOut{Time: time.Now(), Text: errors, Type: "After/Before"}
|
|
||||||
p.print("error", out, "", msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(p.Watcher.Before) > 0 {
|
|
||||||
cast(p.Watcher.Before)
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-c:
|
|
||||||
if len(p.Watcher.After) > 0 {
|
|
||||||
cast(p.Watcher.After)
|
|
||||||
}
|
|
||||||
close(exit)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Walks the file tree of a project
|
|
||||||
func (p *Project) walks(watcher *fsnotify.Watcher) error {
|
|
||||||
var files, folders int64
|
var files, folders int64
|
||||||
wd, _ := os.Getwd()
|
wd, _ := os.Getwd()
|
||||||
walk := func(path string, info os.FileInfo, err error) error {
|
walk := func(path string, info os.FileInfo, err error) error {
|
||||||
|
@ -249,7 +194,6 @@ func (p *Project) walks(watcher *fsnotify.Watcher) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.path == "." || p.path == "/" {
|
if p.path == "." || p.path == "/" {
|
||||||
p.base = wd
|
p.base = wd
|
||||||
p.path = p.Wdir()
|
p.path = p.Wdir()
|
||||||
|
@ -268,12 +212,137 @@ func (p *Project) walks(watcher *fsnotify.Watcher) error {
|
||||||
return errors.New(base + " path doesn't exist")
|
return errors.New(base + " path doesn't exist")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
msg := fmt.Sprintln(p.pname(p.Name, 1), ":", p.Blue.Bold("Watching"), p.Magenta.Bold(files), "file/s", p.Magenta.Bold(folders), "folder/s")
|
msg = fmt.Sprintln(p.pname(p.Name, 1), ":", p.Blue.Bold("Watching"), p.Magenta.Bold(files), "file/s", p.Magenta.Bold(folders), "folder/s")
|
||||||
out := BufferOut{Time: time.Now(), Text: "Watching " + strconv.FormatInt(files, 10) + " files/s " + strconv.FormatInt(folders, 10) + " folder/s"}
|
out = BufferOut{Time: time.Now(), Text: "Watching " + strconv.FormatInt(files, 10) + " files/s " + strconv.FormatInt(folders, 10) + " folder/s"}
|
||||||
p.print("log", out, msg, "")
|
p.print("log", out, msg, "")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Install calls an implementation of "go install"
|
||||||
|
func (p *Project) install() error {
|
||||||
|
if p.Bin {
|
||||||
|
start := time.Now()
|
||||||
|
log.Println(p.pname(p.Name, 1), ":", "Installing..")
|
||||||
|
stream, err := p.goInstall()
|
||||||
|
if err != nil {
|
||||||
|
msg = fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Install"), p.Red.Regular(err.Error()))
|
||||||
|
out = BufferOut{Time: time.Now(), Text: err.Error(), Type: "Go Install", Stream: stream}
|
||||||
|
p.print("error", out, msg, stream)
|
||||||
|
} else {
|
||||||
|
msg = fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Regular("Installed")+" after", p.Magenta.Regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s"))
|
||||||
|
out = BufferOut{Time: time.Now(), Text: "Installed after " + big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3) + " s"}
|
||||||
|
p.print("log", out, msg, stream)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install calls an implementation of "go run"
|
||||||
|
func (p *Project) run(channel chan bool, wr *sync.WaitGroup) {
|
||||||
|
if p.Run {
|
||||||
|
start := time.Now()
|
||||||
|
runner := make(chan bool, 1)
|
||||||
|
log.Println(p.pname(p.Name, 1), ":", "Running..")
|
||||||
|
go p.goRun(channel, runner, wr)
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-runner:
|
||||||
|
msg = fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Regular("Has been run")+" after", p.Magenta.Regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s"))
|
||||||
|
out = BufferOut{Time: time.Now(), Text: "Has been run after " + big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3) + " s"}
|
||||||
|
p.print("log", out, msg, "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build calls an implementation of the "go build"
|
||||||
|
func (p *Project) build() error {
|
||||||
|
if p.Build {
|
||||||
|
start := time.Now()
|
||||||
|
log.Println(p.pname(p.Name, 1), ":", "Building..")
|
||||||
|
stream, err := p.goBuild()
|
||||||
|
if err != nil {
|
||||||
|
msg = fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Build"), p.Red.Regular(err.Error()))
|
||||||
|
out = BufferOut{Time: time.Now(), Text: err.Error(), Type: "Go Build", Stream: stream}
|
||||||
|
p.print("error", out, msg, stream)
|
||||||
|
} else {
|
||||||
|
msg = fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Regular("Builded")+" after", p.Magenta.Regular(big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3), " s"))
|
||||||
|
out = BufferOut{Time: time.Now(), Text: "Builded after " + big.NewFloat(float64(time.Since(start).Seconds())).Text('f', 3) + " s"}
|
||||||
|
p.print("log", out, msg, stream)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fmt calls an implementation of the "go fmt"
|
||||||
|
func (p *Project) fmt(path string) error {
|
||||||
|
if p.Fmt && strings.HasSuffix(path, ".go") {
|
||||||
|
if stream, err := p.goTools(p.base, "gofmt", "-s", "-w", "-e", path); err != nil {
|
||||||
|
msg = fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Fmt"), p.Red.Regular("there are some errors in"), ":", p.Magenta.Bold(path))
|
||||||
|
out = BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: "Go Fmt", Stream: stream}
|
||||||
|
p.print("error", out, msg, stream)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate calls an implementation of the "go generate"
|
||||||
|
func (p *Project) generate(path string) error {
|
||||||
|
if p.Generate {
|
||||||
|
if stream, err := p.goTools(path, "go", "generate"); err != nil {
|
||||||
|
msg = fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Generate"), p.Red.Regular("there are some errors in"), ":", p.Magenta.Bold(path))
|
||||||
|
out = BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: "Go Generate", Stream: stream}
|
||||||
|
p.print("error", out, msg, stream)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test calls an implementation of the "go test"
|
||||||
|
func (p *Project) test(path string) error {
|
||||||
|
if p.Test {
|
||||||
|
if stream, err := p.goTools(path, "go", "test"); err != nil {
|
||||||
|
msg = fmt.Sprintln(p.pname(p.Name, 2), ":", p.Red.Bold("Go Test"), p.Red.Regular("there are some errors in "), ":", p.Magenta.Bold(path))
|
||||||
|
out = BufferOut{Time: time.Now(), Text: "there are some errors in", Path: path, Type: "Go Test", Stream: stream}
|
||||||
|
p.print("error", out, msg, stream)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cmd calls an wrapper for execute the commands after/before
|
||||||
|
func (p *Project) cmd(flag string) {
|
||||||
|
for _, cmd := range p.Watcher.Scripts {
|
||||||
|
if strings.ToLower(cmd.Type) == flag {
|
||||||
|
errors, logs := p.command(cmd)
|
||||||
|
msg = fmt.Sprintln(p.pname(p.Name, 5), ":", p.Green.Bold("Command"), p.Green.Bold("\"")+cmd.Command+p.Green.Bold("\""))
|
||||||
|
out = BufferOut{Time: time.Now(), Text: cmd.Command, Type: flag}
|
||||||
|
if logs != "" {
|
||||||
|
p.print("log", out, msg, "")
|
||||||
|
}
|
||||||
|
if errors != "" {
|
||||||
|
p.print("error", out, msg, "")
|
||||||
|
}
|
||||||
|
if logs != "" {
|
||||||
|
msg = fmt.Sprintln(logs)
|
||||||
|
out = BufferOut{Time: time.Now(), Text: logs, Type: flag}
|
||||||
|
p.print("log", out, "", msg)
|
||||||
|
}
|
||||||
|
if errors != "" {
|
||||||
|
msg = fmt.Sprintln(p.Red.Regular(errors))
|
||||||
|
out = BufferOut{Time: time.Now(), Text: errors, Type: flag}
|
||||||
|
p.print("error", out, "", msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Ignore and validate a path
|
// Ignore and validate a path
|
||||||
func (p *Project) ignore(str string) bool {
|
func (p *Project) ignore(str string) bool {
|
||||||
for _, v := range p.Watcher.Ignore {
|
for _, v := range p.Watcher.Ignore {
|
||||||
|
@ -322,20 +391,20 @@ func (p *Project) print(t string, o BufferOut, msg string, stream string) {
|
||||||
switch t {
|
switch t {
|
||||||
case "out":
|
case "out":
|
||||||
p.Buffer.StdOut = append(p.Buffer.StdOut, o)
|
p.Buffer.StdOut = append(p.Buffer.StdOut, o)
|
||||||
if p.File.Streams {
|
if p.Streams.FileOut {
|
||||||
f := p.Create(p.base, p.parent.Resources.Streams)
|
f := p.Create(p.base, p.parent.Resources.Outputs)
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
s := []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Text, "\r\n"}
|
s := []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Text, "\r\n"}
|
||||||
if _, err := f.WriteString(strings.Join(s, " ")); err != nil {
|
if _, err := f.WriteString(strings.Join(s, " ")); err != nil {
|
||||||
p.Fatal(err, "")
|
p.Fatal(err, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if msg != "" && p.Cli.Streams {
|
if msg != "" && p.Streams.CliOut {
|
||||||
log.Print(msg)
|
log.Print(msg)
|
||||||
}
|
}
|
||||||
case "log":
|
case "log":
|
||||||
p.Buffer.StdLog = append(p.Buffer.StdLog, o)
|
p.Buffer.StdLog = append(p.Buffer.StdLog, o)
|
||||||
if p.File.Logs {
|
if p.Streams.FileLog {
|
||||||
f := p.Create(p.base, p.parent.Resources.Logs)
|
f := p.Create(p.base, p.parent.Resources.Logs)
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
s := []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Text, "\r\n"}
|
s := []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Text, "\r\n"}
|
||||||
|
@ -351,7 +420,7 @@ func (p *Project) print(t string, o BufferOut, msg string, stream string) {
|
||||||
}
|
}
|
||||||
case "error":
|
case "error":
|
||||||
p.Buffer.StdErr = append(p.Buffer.StdErr, o)
|
p.Buffer.StdErr = append(p.Buffer.StdErr, o)
|
||||||
if p.File.Errors {
|
if p.Streams.FileErr {
|
||||||
f := p.Create(p.base, p.parent.Resources.Errors)
|
f := p.Create(p.base, p.parent.Resources.Errors)
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
s := []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Type, o.Text, o.Path, "\r\n"}
|
s := []string{t.Format("2006-01-02 15:04:05"), strings.ToUpper(p.Name), ":", o.Type, o.Text, o.Path, "\r\n"}
|
||||||
|
|
Loading…
Reference in New Issue