From c5392ede6a528a4697ca345612dec1fa1af150db Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Sun, 19 Apr 2020 16:47:15 +0300 Subject: [PATCH] remove the 'typescript' package entirely in favor of iris-cli and because the alm editor was deprecated by its author (consider using the designtsx.com instead) Former-commit-id: 52888ae3fd0da9e5b98e095c665a1a538381ddef --- .travis.yml | 5 - HISTORY.md | 3 +- _examples/README.md | 6 - _examples/README_ZH.md | 4 - typescript/README.md | 9 - typescript/_examples/editor/main.go | 33 --- typescript/_examples/editor/www/index.html | 8 - .../_examples/editor/www/scripts/app.js | 12 - .../_examples/editor/www/scripts/app.ts | 16 -- .../editor/www/scripts/tsconfig.json | 22 -- typescript/_examples/typescript/main.go | 40 --- .../_examples/typescript/www/index.html | 8 - .../_examples/typescript/www/scripts/app.ts | 16 -- typescript/config.go | 194 ------------- typescript/editor/config.go | 46 --- typescript/editor/editor.go | 209 -------------- typescript/npm/exec.go | 112 -------- typescript/npm/npm.go | 118 -------- typescript/typescript.go | 270 ------------------ 19 files changed, 2 insertions(+), 1129 deletions(-) delete mode 100644 typescript/README.md delete mode 100644 typescript/_examples/editor/main.go delete mode 100644 typescript/_examples/editor/www/index.html delete mode 100644 typescript/_examples/editor/www/scripts/app.js delete mode 100644 typescript/_examples/editor/www/scripts/app.ts delete mode 100644 typescript/_examples/editor/www/scripts/tsconfig.json delete mode 100644 typescript/_examples/typescript/main.go delete mode 100644 typescript/_examples/typescript/www/index.html delete mode 100644 typescript/_examples/typescript/www/scripts/app.ts delete mode 100644 typescript/config.go delete mode 100644 typescript/editor/config.go delete mode 100644 typescript/editor/editor.go delete mode 100644 typescript/npm/exec.go delete mode 100644 typescript/npm/npm.go delete mode 100644 typescript/typescript.go diff --git a/.travis.yml b/.travis.yml index 74f4cb20..3054d12b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,11 +18,6 @@ after_script: - go get ./... - go test -count=1 -v -cover ./... - cd ../ - # typescript examples - - cd ./typescript/_examples - - go get ./... - - go test -count=1 -v -cover ./... - - cd ../../ # make sure that the _benchmarks code is working - cd ./_benchmarks - go get ./... diff --git a/HISTORY.md b/HISTORY.md index a3559d7c..aa728107 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -204,7 +204,8 @@ Breaking Changes: - `var mvc.AutoBinding` removed as the default behavior now resolves such dependencies automatically (see [[FEATURE REQUEST] MVC serving gRPC-compatible controller](https://github.com/kataras/iris/issues/1449)) - `mvc#Application.SortByNumMethods()` removed as the default behavior now binds the "thinnest" empty `interface{}` automatically (see [MVC: service injecting fails](https://github.com/kataras/iris/issues/1343)) -- `mvc#BeforeActivation.Dependencies().Add` should be replaced with `mvc#BeforeActivation.Dependencies().Register` instead. +- `mvc#BeforeActivation.Dependencies().Add` should be replaced with `mvc#BeforeActivation.Dependencies().Register` instead +- **REMOVE** the `kataras/iris/v12/typescript` package in favor of the new [iris-cli](https://github.com/kataras/iris-cli). Also, the alm typescript online editor was removed as it is deprecated by its author, please consider using the [designtsx](https://designtsx.com/) instead. # Su, 16 February 2020 | v12.1.8 diff --git a/_examples/README.md b/_examples/README.md index abc39557..aa836c25 100644 --- a/_examples/README.md +++ b/_examples/README.md @@ -357,12 +357,6 @@ iris session manager lives on its own [package](https://github.com/kataras/iris/ - [Native Messages](websocket/native-messages/main.go) - [TLS Enabled](websocket/secure/README.md) -### Typescript Automation Tools - -typescript automation tools have their own repository: [https://github.com/kataras/iris/tree/master/typescript](https://github.com/kataras/iris/tree/master/typescript) **it contains examples** - -> I'd like to tell you that you can use your favourite but I don't think you will find such a thing anywhere else. - ### Hey, You Developers should read the [godocs](https://godoc.org/github.com/kataras/iris) and https://docs.iris-go.com for a better understanding. diff --git a/_examples/README_ZH.md b/_examples/README_ZH.md index 8afcea4e..00468a25 100644 --- a/_examples/README_ZH.md +++ b/_examples/README_ZH.md @@ -441,10 +441,6 @@ Iris session 管理独立包 [package](https://github.com/kataras/iris/tree/mast - [原生消息](websocket/native-messages/main.go) **更新** - [TLS支持](websocket/secure/README.md) -### Typescript 自动化工具 - -Typescript 自动化工具独立库: [https://github.com/kataras/iris/tree/master/typescript](https://github.com/kataras/iris/tree/master/typescript) **包含相关示例** - ### 大兄弟 进一步学习可通过 [godocs](https://godoc.org/github.com/kataras/iris) 和 https://docs.iris-go.com diff --git a/typescript/README.md b/typescript/README.md deleted file mode 100644 index 4e09edb3..00000000 --- a/typescript/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Typescript - -[Typescript](http://www.typescriptlang.org/) and [alm-tools cloud editor](http://alm.tools/) automation tools for the [iris](https://github.com/kataras/iris) web framework. - - -## Table of contents - -* [Typescript compiler](_examples/typescript/main.go) -* [Alm-tools cloud editor](_examples/editor/main.go) \ No newline at end of file diff --git a/typescript/_examples/editor/main.go b/typescript/_examples/editor/main.go deleted file mode 100644 index 03a7d723..00000000 --- a/typescript/_examples/editor/main.go +++ /dev/null @@ -1,33 +0,0 @@ -package main - -import ( - "github.com/kataras/iris/v12" - - "github.com/kataras/iris/v12/typescript/editor" -) - -func main() { - app := iris.New() - app.HandleDir("/scripts", "./www/scripts") // serve the scripts - // when you edit a typescript file from the alm-tools - // it compiles it to javascript, have fun! - - app.Get("/", func(ctx iris.Context) { - ctx.ServeFile("./www/index.html", false) - }) - - editorConfig := editor.Config{ - Hostname: "localhost", - Port: 4444, - WorkingDir: "./www/scripts/", // "/path/to/the/client/side/directory/", - Username: "myusername", - Password: "mypassword", - } - e := editor.New(editorConfig) - e.Run(app.Logger().Infof) // start the editor's server - - // http://localhost:8080 - // http://localhost:4444 - app.Listen(":8080") - e.Stop() -} diff --git a/typescript/_examples/editor/www/index.html b/typescript/_examples/editor/www/index.html deleted file mode 100644 index 5626962b..00000000 --- a/typescript/_examples/editor/www/index.html +++ /dev/null @@ -1,8 +0,0 @@ - - -Load my script - - - - - diff --git a/typescript/_examples/editor/www/scripts/app.js b/typescript/_examples/editor/www/scripts/app.js deleted file mode 100644 index 263cbaff..00000000 --- a/typescript/_examples/editor/www/scripts/app.js +++ /dev/null @@ -1,12 +0,0 @@ -var User = (function () { - function User(fullname) { - this.name = fullname; - } - User.prototype.Hi = function (msg) { - return msg + " " + this.name; - }; - return User; -}()); -var user = new User("iris web framework!"); -var hi = user.Hi("Hello"); -window.alert(hi); diff --git a/typescript/_examples/editor/www/scripts/app.ts b/typescript/_examples/editor/www/scripts/app.ts deleted file mode 100644 index d8dcf18a..00000000 --- a/typescript/_examples/editor/www/scripts/app.ts +++ /dev/null @@ -1,16 +0,0 @@ -class User{ - private name: string; - - constructor(fullname:string) { - this.name = fullname; - } - - Hi(msg: string): string { - return msg + " " + this.name; - } - -} - -var user = new User("iris web framework!"); -var hi = user.Hi("Hello"); -window.alert(hi); diff --git a/typescript/_examples/editor/www/scripts/tsconfig.json b/typescript/_examples/editor/www/scripts/tsconfig.json deleted file mode 100644 index 2125ded8..00000000 --- a/typescript/_examples/editor/www/scripts/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "noImplicitAny": false, - "removeComments": true, - "preserveConstEnums": true, - "sourceMap": false, - "target": "ES5", - "noEmit": false, - "watch":true, - "noEmitOnError": true, - "experimentalDecorators": false, - "outDir": "./", - "charset": "UTF-8", - "noLib": false, - "diagnostics": true, - "declaration": false - }, - "files": [ - "./app.ts" - ] -} diff --git a/typescript/_examples/typescript/main.go b/typescript/_examples/typescript/main.go deleted file mode 100644 index 4070ea37..00000000 --- a/typescript/_examples/typescript/main.go +++ /dev/null @@ -1,40 +0,0 @@ -package main - -import ( - "github.com/kataras/iris/v12" - - "github.com/kataras/iris/v12/typescript" -) - -// NOTE: Some machines don't allow to install typescript automatically, so if you don't have typescript installed -// and the typescript adaptor doesn't works for you then follow the below steps: -// 1. close the iris server -// 2. open your terminal and execute: npm install -g typescript -// 3. start your iris server, it should be work, as expected, now. -func main() { - app := iris.New() - - app.HandleDir("/scripts", "./www") // serve the scripts - - app.Get("/", func(ctx iris.Context) { - ctx.ServeFile("./www/index.html", false) - }) - - ts := typescript.New() - ts.Config.Dir = "./www/scripts" - ts.Run(app.Logger().Infof) - - // http://localhost:8080 - app.Listen(":8080") -} - -// open http://localhost:8080 -// go to ./www/scripts/app.ts -// make a change -// reload the http://localhost:8080 and you should see the changes -// -// what it does? -// - compiles the typescript files using default compiler options if not tsconfig found -// - watches for changes on typescript files, if a change then it recompiles the .ts to .js -// -// same as you used to do with gulp-like tools, but here I do my bests to help GO developers. diff --git a/typescript/_examples/typescript/www/index.html b/typescript/_examples/typescript/www/index.html deleted file mode 100644 index 5626962b..00000000 --- a/typescript/_examples/typescript/www/index.html +++ /dev/null @@ -1,8 +0,0 @@ - - -Load my script - - - - - diff --git a/typescript/_examples/typescript/www/scripts/app.ts b/typescript/_examples/typescript/www/scripts/app.ts deleted file mode 100644 index 37b9d588..00000000 --- a/typescript/_examples/typescript/www/scripts/app.ts +++ /dev/null @@ -1,16 +0,0 @@ -class User{ - private name: string; - - constructor(fullname:string) { - this.name = fullname; - } - - Hi(msg: string): string { - return msg + " "+ this.name; - } - -} - -var user = new User("iris web framework"); -var hi = user.Hi("Hello"); -window.alert(hi); diff --git a/typescript/config.go b/typescript/config.go deleted file mode 100644 index 092f6001..00000000 --- a/typescript/config.go +++ /dev/null @@ -1,194 +0,0 @@ -package typescript - -import ( - "encoding/json" - "io/ioutil" - "os" - "reflect" - "strconv" - - "github.com/kataras/iris/v12/typescript/npm" -) - -var ( - pathSeparator = string(os.PathSeparator) - nodeModules = pathSeparator + "node_modules" + pathSeparator -) - -type ( - // Tsconfig the struct for tsconfig.json - Tsconfig struct { - CompilerOptions CompilerOptions `json:"compilerOptions"` - Exclude []string `json:"exclude"` - } - - // CompilerOptions contains all the compiler options used by the tsc (typescript compiler) - CompilerOptions struct { - Declaration bool `json:"declaration"` - Module string `json:"module"` - Target string `json:"target"` - Watch bool `json:"watch"` - Charset string `json:"charset"` - Diagnostics bool `json:"diagnostics"` - EmitBOM bool `json:"emitBOM"` - EmitDecoratorMetadata bool `json:"emitDecoratorMetadata"` - ExperimentalDecorators bool `json:"experimentalDecorators"` - InlineSourceMap bool `json:"inlineSourceMap"` - InlineSources bool `json:"inlineSources"` - IsolatedModules bool `json:"isolatedModules"` - Jsx string `json:"jsx"` - ReactNamespace string `json:"reactNamespace"` - ListFiles bool `json:"listFiles"` - Locale string `json:"locale"` - MapRoot string `json:"mapRoot"` - ModuleResolution string `json:"moduleResolution"` - NewLine string `json:"newLine"` - NoEmit bool `json:"noEmit"` - NoEmitOnError bool `json:"noEmitOnError"` - NoEmitHelpers bool `json:"noEmitHelpers"` - NoImplicitAny bool `json:"noImplicitAny"` - NoLib bool `json:"noLib"` - NoResolve bool `json:"noResolve"` - SkipDefaultLibCheck bool `json:"skipDefaultLibCheck"` - OutDir string `json:"outDir"` - OutFile string `json:"outFile"` - PreserveConstEnums bool `json:"preserveConstEnums"` - Pretty bool `json:"pretty"` - RemoveComments bool `json:"removeComments"` - RootDir string `json:"rootDir"` - SourceMap bool `json:"sourceMap"` - SourceRoot string `json:"sourceRoot"` - StripInternal bool `json:"stripInternal"` - SuppressExcessPropertyErrors bool `json:"suppressExcessPropertyErrors"` - SuppressImplicitAnyIndexErrors bool `json:"suppressImplicitAnyIndexErrors"` - AllowUnusedLabels bool `json:"allowUnusedLabels"` - NoImplicitReturns bool `json:"noImplicitReturns"` - NoFallthroughCasesInSwitch bool `json:"noFallthroughCasesInSwitch"` - AllowUnreachableCode bool `json:"allowUnreachableCode"` - ForceConsistentCasingInFileNames bool `json:"forceConsistentCasingInFileNames"` - AllowSyntheticDefaultImports bool `json:"allowSyntheticDefaultImports"` - AllowJs bool `json:"allowJs"` - NoImplicitUseStrict bool `json:"noImplicitUseStrict"` - } - - // Config the configs for the Typescript plugin - // Has five (5) fields - // - // 1. Bin: string, the typescript installation directory/typescript/lib/tsc.js, if empty it will search inside global npm modules - // 2. Dir: string, Dir set the root, where to search for typescript files/project. Default "./" - // 3. Ignore: string, comma separated ignore typescript files/project from these directories. Default "" (node_modules are always ignored) - // 4. Tsconfig: &typescript.Tsconfig{}, here you can set all compilerOptions if no tsconfig.json exists inside the 'Dir' - // 5. Editor: typescript.Editor("username","password"), if set then alm-tools browser-based typescript IDE will be available. Defailt is nil - Config struct { - // Bin the path of the tsc binary file - // if empty then the plugin tries to find it - Bin string - // Dir the client side directory, which typescript (.ts) files are live - Dir string - // Ignore ignore folders, default is /node_modules/ - Ignore string - // Tsconfig the typescript build configs, including the compiler's options - Tsconfig *Tsconfig - } -) - -// CompilerArgs returns the CompilerOptions' contents of the Tsconfig -// it reads the json tags, add '--' at the start of each one and returns an array of strings -// this is from file -func (tsconfig *Tsconfig) CompilerArgs() []string { - val := reflect.ValueOf(tsconfig).Elem().FieldByName("CompilerOptions") // -> for tsconfig *Tsconfig - // val := reflect.ValueOf(tsconfig.CompilerOptions) - compilerOpts := make([]string, 0) // 0 because we don't know the real valid options yet. - for i := 0; i < val.NumField(); i++ { - typeField := val.Type().Field(i) - valueFieldG := val.Field(i) - var valueField string - // only if it's string or int we need to put that - if valueFieldG.Kind() == reflect.String { - // if valueFieldG.String() != "" { - // valueField = strconv.QuoteToASCII(valueFieldG.String()) - // } - valueField = valueFieldG.String() - } else if valueFieldG.Kind() == reflect.Int { - if valueFieldG.Int() > 0 { - valueField = strconv.Itoa(int(valueFieldG.Int())) - } - } else if valueFieldG.Kind() == reflect.Bool { - valueField = strconv.FormatBool(valueFieldG.Bool()) - } - - if valueField != "" && valueField != "false" { - // var opt string - - // key := typeField.Tag.Get("json") - // // it's bool value of true then just --key, for example --watch - // if valueField == "true" { - // opt = "--" + key - // } else { - // // it's a string now, for example -m commonjs - // opt = "-" + string(key[0]) + " " + valueField - // } - key := "--" + typeField.Tag.Get("json") - compilerOpts = append(compilerOpts, key) - // the form is not '--module ES6' but os.Exec should recognise them as arguments - // so we need to put the values on the next index - if valueField != "true" { - // it's a string now, for example -m commonjs - compilerOpts = append(compilerOpts, valueField) - } - - } - - } - - return compilerOpts -} - -// FromFile reads a file & returns the Tsconfig by its contents -func FromFile(tsConfigAbsPath string) (config Tsconfig, err error) { - file, err := ioutil.ReadFile(tsConfigAbsPath) - if err != nil { - return - } - config = Tsconfig{} - err = json.Unmarshal(file, &config) - - return -} - -// DefaultTsconfig returns the default Tsconfig, with CompilerOptions module: commonjs, target: es5 and ignore the node_modules -func DefaultTsconfig() Tsconfig { - return Tsconfig{ - CompilerOptions: CompilerOptions{ - Module: "commonjs", - Target: "ES6", - Jsx: "react", - ModuleResolution: "classic", - Locale: "en", - Watch: false, - NoImplicitAny: false, - SourceMap: false, - Diagnostics: true, - NoEmit: false, - OutDir: "", // taken from Config.Dir if it's not empty, otherwise ./ on Run() - }, - Exclude: []string{"node_modules"}, - } -} - -// DefaultConfig returns the default Options of the Typescript adaptor -// Bin and Editor are setting in runtime via the adaptor -func DefaultConfig() Config { - root, err := os.Getwd() - if err != nil { - panic("typescript: cannot get the cwd") - } - compilerTsConfig := DefaultTsconfig() - c := Config{ - Dir: root + pathSeparator, - Ignore: nodeModules, - Tsconfig: &compilerTsConfig, - } - c.Bin = npm.NodeModuleAbs("typescript/lib/tsc.js") - return c -} diff --git a/typescript/editor/config.go b/typescript/editor/config.go deleted file mode 100644 index c99f1cac..00000000 --- a/typescript/editor/config.go +++ /dev/null @@ -1,46 +0,0 @@ -package editor - -import ( - "os" -) - -// Default values for the configuration -const ( - DefaultPort = 4444 -) - -// Config the configs for the Editor plugin -type Config struct { - // Hostname if empty used the iris server's hostname - Hostname string - // Port if 0 4444 - Port int - // KeyFile the key file(ssl optional) - KeyFile string - // CertFile the cert file (ssl optional) - CertFile string - // WorkingDir if empty "./" - WorkingDir string - // Username defaults to empty, you should set this - Username string - // Password defaults to empty, you should set this - Password string - // DisableOutput set that to true if you don't care about alm-tools' messages - // they are useful because that the default value is "false" - DisableOutput bool -} - -// DefaultConfig returns the default configs for the Editor plugin -func DefaultConfig() Config { - // explicit - return Config{ - Hostname: "", - Port: 4444, - KeyFile: "", - CertFile: "", - WorkingDir: "." + string(os.PathSeparator), // alm-tools should end with path separator. - Username: "", - Password: "", - DisableOutput: false, - } -} diff --git a/typescript/editor/editor.go b/typescript/editor/editor.go deleted file mode 100644 index aaca608b..00000000 --- a/typescript/editor/editor.go +++ /dev/null @@ -1,209 +0,0 @@ -package editor - -/* Package editor provides alm-tools cloud editor automation for the iris web framework. - -Usage: - - - import "github.com/kataras/iris/v12/typescript/editor" - [...] - - app := iris.New() - e := editor.New(editor.Config{}) - e.Run(app.Logger().Infof) - - [...] - app.Listen(":8080") - e.Stop() - - -General notes for authentication - - -The Authorization specifies the authentication mechanism (in this case Basic) followed by the username and password. -Although, the string aHR0cHdhdGNoOmY= may look encrypted it is simply a base64 encoded version of :. -Would be readily available to anyone who could intercept the HTTP request. -*/ -import ( - "bufio" - "os" - "path/filepath" - "strconv" - - "github.com/kataras/iris/v12/typescript/npm" -) - -type ( - // Editor is the alm-tools adaptor. - // - // It holds a logger from the iris' station - // username,password for basic auth - // directory which the client side code is - // keyfile,certfile for TLS listening - // and a host which is listening for - Editor struct { - config *Config - log func(format string, a ...interface{}) - enabled bool // default true - // after alm started - process *os.Process - } -) - -// NoOpLogger can be used as the logger argument, it prints nothing. -var NoOpLogger = func(string, ...interface{}) {} - -// New creates and returns an Editor Plugin instance -func New(cfg ...Config) *Editor { - c := DefaultConfig() - if len(cfg) > 0 { - c = cfg[0] - } - c.WorkingDir = validateWorkingDir(c.WorkingDir) // add "/" if not exists - - return &Editor{ - enabled: true, - config: &c, - } -} - -// User set a user, accepts two parameters: username (string), string (string) -func (e *Editor) User(username string, password string) *Editor { - e.config.Username = username - e.config.Password = password - return e -} - -func validateWorkingDir(workingDir string) string { - l := workingDir[len(workingDir)-1] - - if l != '/' && l != os.PathSeparator { - workingDir += "/" - } - return workingDir -} - -// Dir sets the directory which the client side source code alive -func (e *Editor) Dir(workingDir string) *Editor { - e.config.WorkingDir = validateWorkingDir(workingDir) - return e -} - -// Port sets the port (int) for the editor adaptor's standalone server -func (e *Editor) Port(port int) *Editor { - e.config.Port = port - return e -} - -// SetEnable if true enables the editor adaptor, otherwise disables it -func (e *Editor) SetEnable(enable bool) { - e.enabled = enable -} - -// DisableOutput call that if you don't care about alm-tools' messages -// they are useful because that the default configuration shows them -func (e *Editor) DisableOutput() { - e.config.DisableOutput = true -} - -// GetDescription EditorPlugin is a bridge between iris and the alm-tools, the browser-based IDE for client-side sources. -func (e *Editor) GetDescription() string { - return "A bridge between iris and the alm-tools, the browser-based IDE." -} - -// Run starts the editor's server. -// -// Developers should call the `Stop` to shutdown the editor's server when main server will be closed. -func (e *Editor) Run(logger func(format string, a ...interface{})) { - if logger == nil { - logger = NoOpLogger - } - - e.log = logger - if e.config.Hostname == "" { - e.config.Hostname = "0.0.0.0" - } - - if e.config.Port <= 0 { - e.config.Port = DefaultPort - } - - if s, err := filepath.Abs(e.config.WorkingDir); err == nil { - e.config.WorkingDir = s - } - - e.start() -} - -// Stop kills the editor's server. -func (e *Editor) Stop() { - if e.process != nil { - err := e.process.Kill() - if err != nil { - e.log("error while trying to terminate the Editor,please kill this process by yourself, process id: %d", e.process.Pid) - } - } -} - -// start starts the job -func (e *Editor) start() { - if e.config.Username == "" || e.config.Password == "" { - e.log("error before running alm-tools. You have to set username & password for security reasons, otherwise this adaptor won't run.") - return - } - - if !npm.NodeModuleExists("alm/bin/alm") { - e.log("installing alm-tools, please wait...") - res := npm.NodeModuleInstall("alm") - if res.Error != nil { - e.log(res.Error.Error()) - return - } - e.log(res.Message) - } - - cmd := npm.CommandBuilder("node", npm.NodeModuleAbs("alm/src/server.js")) - cmd.AppendArguments("-a", e.config.Username+":"+e.config.Password, - "-h", e.config.Hostname, "-t", strconv.Itoa(e.config.Port), "-d", e.config.WorkingDir) - // for auto-start in the browser: cmd.AppendArguments("-o") - if e.config.KeyFile != "" && e.config.CertFile != "" { - cmd.AppendArguments("--httpskey", e.config.KeyFile, "--httpscert", e.config.CertFile) - } - - prefix := "" - // when debug is not disabled - // show any messages to the user( they are useful here) - // to the io.Writer that iris' user is defined from configuration - if !e.config.DisableOutput { - - outputReader, err := cmd.StdoutPipe() - if err == nil { - outputScanner := bufio.NewScanner(outputReader) - - go func() { - for outputScanner.Scan() { - e.log(prefix + outputScanner.Text()) - } - }() - - errReader, err := cmd.StderrPipe() - if err == nil { - errScanner := bufio.NewScanner(errReader) - go func() { - for errScanner.Scan() { - e.log(prefix + errScanner.Text()) - } - }() - } - } - } - - err := cmd.Start() - if err != nil { - e.log(prefix + err.Error()) - return - } - - // no need, alm-tools post these - // e.logger.Printf("Editor is running at %s:%d | %s", e.config.Hostname, e.config.Port, e.config.WorkingDir) -} diff --git a/typescript/npm/exec.go b/typescript/npm/exec.go deleted file mode 100644 index cb3d9a3c..00000000 --- a/typescript/npm/exec.go +++ /dev/null @@ -1,112 +0,0 @@ -package npm // #nosec - -import ( - "fmt" - "os" - "os/exec" - "strings" -) - -// PathSeparator is the string of os.PathSeparator -var PathSeparator = string(os.PathSeparator) - -type ( - // Cmd is a custom struch which 'implements' the *exec.Cmd - Cmd struct { - *exec.Cmd - } -) - -// Arguments sets the command line arguments, including the command as Args[0]. -// If the args parameter is empty or nil, Run uses {Path}. -// -// In typical use, both Path and args are set by calling Command. -func (cmd *Cmd) Arguments(args ...string) *Cmd { - cmd.Cmd.Args = append(cmd.Cmd.Args[0:1], args...) // we need the first argument which is the command - return cmd -} - -// AppendArguments appends the arguments to the exists -func (cmd *Cmd) AppendArguments(args ...string) *Cmd { - cmd.Cmd.Args = append(cmd.Cmd.Args, args...) - return cmd -} - -// ResetArguments resets the arguments -func (cmd *Cmd) ResetArguments() *Cmd { - cmd.Args = cmd.Args[0:1] // keep only the first because is the command - return cmd -} - -// Directory sets the working directory of the command. -// If workingDirectory is the empty string, Run runs the command in the -// calling process's current directory. -func (cmd *Cmd) Directory(workingDirectory string) *Cmd { - cmd.Cmd.Dir = workingDirectory - return cmd -} - -// CommandBuilder creates a Cmd object and returns it -// accepts 2 parameters, one is optionally -// first parameter is the command (string) -// second variatic parameter is the argument(s) (slice of string) -// -// the difference from the normal Command function is that you can re-use this Cmd, it doesn't execute until you call its Command function -func CommandBuilder(command string, args ...string) *Cmd { - return &Cmd{Cmd: exec.Command(command, args...)} -} - -// the below is just for exec.Command: - -// Command executes a command in shell and returns it's output, it's block version -func Command(command string, a ...string) (output string, err error) { - var out []byte - // if no args given, try to get them from the command - if len(a) == 0 { - commandArgs := strings.Split(command, " ") - for _, commandArg := range commandArgs { - if commandArg[0] == '-' { // if starts with - means that this is an argument, append it to the arguments - a = append(a, commandArg) - } - } - } - out, err = exec.Command(command, a...).Output() - - if err == nil { - output = string(out) - } - - return -} - -// MustCommand executes a command in shell and returns it's output, it's block version. It panics on an error -func MustCommand(command string, a ...string) (output string) { - var out []byte - var err error - if len(a) == 0 { - commandArgs := strings.Split(command, " ") - for _, commandArg := range commandArgs { - if commandArg[0] == '-' { // if starts with - means that this is an argument, append it to the arguments - a = append(a, commandArg) - } - } - } - - out, err = exec.Command(command, a...).Output() - if err != nil { - argsToString := strings.Join(a, " ") - panic(fmt.Sprintf("\nError running the command %s", command+" "+argsToString)) - } - - output = string(out) - - return -} - -// Exists returns true if directory||file exists -func Exists(dir string) bool { - if _, err := os.Stat(dir); os.IsNotExist(err) { - return false - } - return true -} diff --git a/typescript/npm/npm.go b/typescript/npm/npm.go deleted file mode 100644 index 6137e808..00000000 --- a/typescript/npm/npm.go +++ /dev/null @@ -1,118 +0,0 @@ -package npm - -import ( - "fmt" - "path/filepath" - "strings" - "time" -) - -// nodeModulesPath is the path of the root npm modules -// Ex: C:\\Users\\iris\\AppData\\Roaming\\npm\\node_modules -var nodeModulesPath string - -type ( - // NodeModuleResult holds Message and Error, if error != nil then the npm command has failed - NodeModuleResult struct { - // Message the message (string) - Message string - // Error the error (if any) - Error error - } -) - -// NodeModulesPath sets the root directory for the node_modules and returns that -func NodeModulesPath() string { - if nodeModulesPath == "" { - nodeModulesPath = MustCommand("npm", "root", "-g") // here it ends with \n we have to remove it - nodeModulesPath = nodeModulesPath[0 : len(nodeModulesPath)-1] - } - return nodeModulesPath -} - -func success(output string, a ...interface{}) NodeModuleResult { - return NodeModuleResult{fmt.Sprintf(output, a...), nil} -} - -func fail(errMsg string, a ...interface{}) NodeModuleResult { - return NodeModuleResult{"", fmt.Errorf("\n"+errMsg, a...)} -} - -// Output returns the error message if result.Error exists, otherwise returns the result.Message -func (res NodeModuleResult) Output() (out string) { - if res.Error != nil { - out = res.Error.Error() - } else { - out = res.Message - } - return -} - -// NodeModuleInstall installs a module -func NodeModuleInstall(moduleName string) NodeModuleResult { - finish := make(chan bool) - - go func() { - print("\n|") - print("_") - print("|") - - for { - select { - case v := <-finish: - { - if v { - print("\010\010\010") // remove the loading chars - close(finish) - return - } - } - default: - print("\010\010-") - time.Sleep(time.Second / 2) - print("\010\\") - time.Sleep(time.Second / 2) - print("\010|") - time.Sleep(time.Second / 2) - print("\010/") - time.Sleep(time.Second / 2) - print("\010-") - time.Sleep(time.Second / 2) - print("|") - } - } - }() - out, err := Command("npm", "install", moduleName, "-g") - finish <- true - if err != nil { - return fail("Error installing module %s. Trace: %s", moduleName, err.Error()) - } - - return success("\n%s installed %s", moduleName, out) -} - -// NodeModuleUnistall removes a module -func NodeModuleUnistall(moduleName string) NodeModuleResult { - out, err := Command("npm", "unistall", "-g", moduleName) - if err != nil { - return fail("Error unstalling module %s. Trace: %s", moduleName, err.Error()) - } - return success("\n %s unistalled %s", moduleName, out) -} - -// NodeModuleAbs returns the absolute path of the global node_modules directory + relative -func NodeModuleAbs(relativePath string) string { - return NodeModulesPath() + PathSeparator + strings.Replace(relativePath, "/", PathSeparator, -1) -} - -// NodeModuleExists returns true if a module exists -// here we have two options -// 1 . search by command something like npm -ls -g --depth=x -// 2. search on files, we choose the second -func NodeModuleExists(execPath string) bool { - if !filepath.IsAbs(execPath) { - execPath = NodeModuleAbs(execPath) - } - - return Exists(execPath) -} diff --git a/typescript/typescript.go b/typescript/typescript.go deleted file mode 100644 index 50d9ee1e..00000000 --- a/typescript/typescript.go +++ /dev/null @@ -1,270 +0,0 @@ -// Package typescript provides a typescript compiler with hot-reloader -// and optionally a cloud-based editor, called 'alm-tools'. -// typescript (by microsoft) and alm-tools (by @basarat) have their own (open-source) licenses -// the tools are not used directly by this adaptor, but it's good to know where you can find -// the software. -package typescript - -import ( - "errors" - "os" - "path/filepath" - "strings" - - "github.com/kataras/iris/v12/typescript/npm" -) - -type ( - // Typescript contains the unique iris' typescript loader, holds all necessary fields & methods. - Typescript struct { - Config *Config - log func(format string, a ...interface{}) - } -) - -// New creates & returns a new instnace typescript plugin -func New(cfg ...Config) *Typescript { - c := DefaultConfig() - if len(cfg) > 0 { - c = cfg[0] - } - - return &Typescript{Config: &c} -} - -// NoOpLogger can be used as the logger argument, it prints nothing. -var NoOpLogger = func(string, ...interface{}) {} - -// Run starts the typescript filewatcher watcher and the typescript compiler. -func (t *Typescript) Run(logger func(format string, a ...interface{})) { - c := t.Config - if c.Tsconfig == nil { - tsC := DefaultTsconfig() - c.Tsconfig = &tsC - } - - if c.Dir == "" { - c.Tsconfig.CompilerOptions.OutDir = c.Dir - } - - if c.Dir == "" { - c.Dir = "./" - } - - if !strings.Contains(c.Ignore, nodeModules) { - c.Ignore += "," + nodeModules - } - - if logger == nil { - logger = NoOpLogger - } - - t.log = logger - - t.start() -} - -func (t *Typescript) start() { - if t.hasTypescriptFiles() { - // Can't check if permission denied returns always exists = true.... - - if !npm.NodeModuleExists(t.Config.Bin) { - t.log("installing typescript, please wait...") - res := npm.NodeModuleInstall("typescript") - if res.Error != nil { - t.log(res.Error.Error()) - return - } - t.log(res.Message) - } - - projects := t.getTypescriptProjects() - if len(projects) > 0 { - watchedProjects := 0 - // typescript project (.tsconfig) found - for _, project := range projects { - cmd := npm.CommandBuilder("node", t.Config.Bin, "-p", project[0:strings.LastIndex(project, npm.PathSeparator)]) // remove the /tsconfig.json) - projectConfig, perr := FromFile(project) - if perr != nil { - t.log("error while trying to read tsconfig: %s", perr.Error()) - continue - } - - if projectConfig.CompilerOptions.Watch { - watchedProjects++ - // if has watch : true then we have to wrap the command to a goroutine (I don't want to use the .Start here) - go func() { - _, err := cmd.Output() - if err != nil { - t.log("error when 'watch' is true: %v", err) - return - } - }() - } else { - _, err := cmd.Output() - if err != nil { - t.log("unexpected error from output: %v", err) - return - } - - } - - } - return - } - // search for standalone typescript (.ts) files and compile them - files := t.getTypescriptFiles() - if len(files) > 0 { - /* watchedFiles := 0 - if t.Config.Tsconfig.CompilerOptions.Watch { - watchedFiles = len(files) - }*/ - //it must be always > 0 if we came here, because of if hasTypescriptFiles == true. - for _, file := range files { - - absPath, err := filepath.Abs(file) - if err != nil { - t.log("error while trying to resolve absolute path for %s: %v", file, err) - continue - } - - // these will be used if no .tsconfig found. - // cmd := npm.CommandBuilder("node", t.Config.Bin) - // cmd.Arguments(t.Config.Bin, t.Config.Tsconfig.CompilerArgs()...) - // cmd.AppendArguments(absPath) - compilerArgs := t.Config.Tsconfig.CompilerArgs() - cmd := npm.CommandBuilder("node", t.Config.Bin) - - for _, s := range compilerArgs { - cmd.AppendArguments(s) - } - cmd.AppendArguments(absPath) - go func() { - compilerMsgB, _ := cmd.Output() - compilerMsg := string(compilerMsgB) - cmd.Args = cmd.Args[0 : len(cmd.Args)-1] // remove the last, which is the file - - if strings.Contains(compilerMsg, "error") { - t.log(compilerMsg) - } - }() - - } - return - } - return - } - absPath, err := filepath.Abs(t.Config.Dir) - if err != nil { - t.log("no typescript file, the directory cannot be resolved: %v", err) - return - } - t.log("no typescript files found on : %s", absPath) -} - -func (t *Typescript) hasTypescriptFiles() bool { - root := t.Config.Dir - ignoreFolders := t.getIgnoreFolders() - hasTs := false - if !npm.Exists(root) { - t.log("typescript error: directory '%s' couldn't be found,\nplease specify a valid path for your *.ts files", root) - return false - } - - err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { - if fi.IsDir() { - return nil - } - for _, s := range ignoreFolders { - if strings.HasSuffix(path, s) || path == s { - return filepath.SkipDir - } - } - - if strings.HasSuffix(path, ".ts") { - hasTs = true - return errors.New("typescript found, hope that will stop here") - } - - return nil - }) - if err != nil { - t.log("typescript: hasTypescriptFiles: %v", err) - } - return hasTs -} - -func (t *Typescript) getIgnoreFolders() (folders []string) { - ignoreFolders := strings.Split(t.Config.Ignore, ",") - - for _, s := range ignoreFolders { - if s != "" { - folders = append(folders, s) - } - } - - return folders -} - -func (t *Typescript) getTypescriptProjects() []string { - var projects []string - ignoreFolders := t.getIgnoreFolders() - - root := t.Config.Dir - // t.logger.Printf("\nSearching for typescript projects in %s", root) - - err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { - if fi.IsDir() { - return nil - } - for _, s := range ignoreFolders { - if strings.HasSuffix(path, s) || path == s { - return filepath.SkipDir - } - } - - if strings.HasSuffix(path, npm.PathSeparator+"tsconfig.json") { - // t.logger.Printf("\nTypescript project found in %s", path) - projects = append(projects, path) - } - - return nil - }) - - if err != nil { - t.log("typescript: getTypescriptProjects: %v", err) - } - return projects -} - -// this is being called if getTypescriptProjects return 0 len, then we are searching for files using that: -func (t *Typescript) getTypescriptFiles() []string { - var files []string - ignoreFolders := t.getIgnoreFolders() - - root := t.Config.Dir - - err := filepath.Walk(root, func(path string, fi os.FileInfo, err error) error { - if fi.IsDir() { - return nil - } - for _, s := range ignoreFolders { - if strings.HasSuffix(path, s) || path == s { - return nil - } - } - - if strings.HasSuffix(path, ".ts") { - // t.logger.Printf("\nTypescript file found in %s", path) - files = append(files, path) - } - - return nil - }) - - if err != nil { - t.log("typescript: getTypescriptFiles: %v", err) - } - - return files -}