mirror of
https://github.com/kataras/iris.git
synced 2025-02-02 15:30:36 +01:00
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
This commit is contained in:
parent
340664dca9
commit
c5392ede6a
|
@ -18,11 +18,6 @@ after_script:
|
||||||
- go get ./...
|
- go get ./...
|
||||||
- go test -count=1 -v -cover ./...
|
- go test -count=1 -v -cover ./...
|
||||||
- cd ../
|
- cd ../
|
||||||
# typescript examples
|
|
||||||
- cd ./typescript/_examples
|
|
||||||
- go get ./...
|
|
||||||
- go test -count=1 -v -cover ./...
|
|
||||||
- cd ../../
|
|
||||||
# make sure that the _benchmarks code is working
|
# make sure that the _benchmarks code is working
|
||||||
- cd ./_benchmarks
|
- cd ./_benchmarks
|
||||||
- go get ./...
|
- go get ./...
|
||||||
|
|
|
@ -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))
|
- `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#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
|
# Su, 16 February 2020 | v12.1.8
|
||||||
|
|
||||||
|
|
|
@ -357,12 +357,6 @@ iris session manager lives on its own [package](https://github.com/kataras/iris/
|
||||||
- [Native Messages](websocket/native-messages/main.go)
|
- [Native Messages](websocket/native-messages/main.go)
|
||||||
- [TLS Enabled](websocket/secure/README.md)
|
- [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
|
### Hey, You
|
||||||
|
|
||||||
Developers should read the [godocs](https://godoc.org/github.com/kataras/iris) and https://docs.iris-go.com for a better understanding.
|
Developers should read the [godocs](https://godoc.org/github.com/kataras/iris) and https://docs.iris-go.com for a better understanding.
|
||||||
|
|
|
@ -441,10 +441,6 @@ Iris session 管理独立包 [package](https://github.com/kataras/iris/tree/mast
|
||||||
- [原生消息](websocket/native-messages/main.go) **更新**
|
- [原生消息](websocket/native-messages/main.go) **更新**
|
||||||
- [TLS支持](websocket/secure/README.md)
|
- [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
|
进一步学习可通过 [godocs](https://godoc.org/github.com/kataras/iris) 和 https://docs.iris-go.com
|
||||||
|
|
|
@ -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)
|
|
|
@ -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()
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Load my script</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script src="scripts/app.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -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);
|
|
|
@ -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);
|
|
|
@ -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"
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -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.
|
|
|
@ -1,8 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Load my script</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<script src="scripts/app.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -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);
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 <username>:<password>.
|
|
||||||
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)
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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)
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user