예제 #1
0
파일: tests.go 프로젝트: kego/ke
func (c *ContextBuilder) initEnv() *envctx.Env {
	env := envctx.FromContextOrNil(c.ctx)
	if env == nil {
		env = &envctx.Env{Aliases: map[string]string{}}
		c.ctx = envctx.NewContext(c.ctx, env)
	}
	return env
}
예제 #2
0
파일: tests.go 프로젝트: kego/ke
func Context(path string) *ContextBuilder {

	env := &envctx.Env{
		Path:    path,
		Aliases: map[string]string{},
	}

	ctx := context.Background()
	ctx = envctx.NewContext(ctx, env)

	return From(ctx)
}
예제 #3
0
파일: parser.go 프로젝트: kego/ke
func scanForTypesAndExports(ctx context.Context, env *envctx.Env, cache *sysctx.SysPackageInfo, hash *PackageHasher) error {

	// While we're scanning for types, we should use a custom unpacking env,
	// because the env from the context is the one of the local package.

	files := scanner.ScanDirToFiles(ctx, env.Dir, env.Recursive)
	bytes := scanner.ScanFilesToBytes(ctx, files)
	localContext := envctx.NewContext(ctx, env)
	for b := range bytes {
		if b.Err != nil {
			return kerr.Wrap("JACKALTIGG", b.Err)
		}

		o := &system.ObjectStub{}
		if err := system.Unmarshal(localContext, b.Bytes, o); err != nil {
			return kerr.Wrap("HCYGNBDFFA", err)
		}
		if o.Type == nil {
			return kerr.New("NUKWIHYFMQ", "%s has no type", b.File)
		}
		if o.Id == nil && *o.Type != *system.NewReference("kego.io/system", "package") {
			// we tolerate missing ID only for system:package
			return kerr.New("DLLMKTDYFW", "%s has no id", b.File)
		}
		relativeFile, err := filepath.Rel(env.Dir, b.File)
		if err != nil {
			return kerr.Wrap("AWYRJSCYQS", err)
		}
		switch *o.Type {
		case *system.NewReference("kego.io/system", "type"):
			if err := ProcessTypeFileBytes(ctx, env, relativeFile, b.Bytes, cache, hash); err != nil {
				return kerr.Wrap("IVEFDDSKHE", err)
			}
		case *system.NewReference("kego.io/system", "package"):
			cache.PackageBytes = b.Bytes
			cache.PackageFilename = relativeFile
		default:
			cache.Globals.Set(o.Id.Name, relativeFile)
			if o.Export {
				cache.Exports.Set(o.Id.Name, o.Type.Name, o.Type.Package, b.Bytes)
				if hash != nil {
					hash.Exports[o.Id.Name+" "+o.Type.Name+" "+o.Type.Package] = cityhash.CityHash64(b.Bytes, uint32(len(b.Bytes)))
				}
			}
		}

	}
	return nil
}
예제 #4
0
파일: initialise.go 프로젝트: kego/ke
func Initialise(ctx context.Context, overrides OptionsInterface) (context.Context, context.CancelFunc, error) {
	if overrides == nil {
		overrides = Flags{}
	}
	options := overrides.getOptions()

	ctx, cancel := context.WithCancel(ctx)
	ctx = jsonctx.AutoContext(ctx)
	ctx = wgctx.NewContext(ctx)
	ctx = sysctx.NewContext(ctx)

	cmd := &cmdctx.Cmd{}

	vos := vosctx.FromContext(ctx)

	path := ""
	cmd.Edit = options.Edit
	cmd.Validate = options.Validate
	cmd.Update = options.Update
	cmd.Log = options.Log
	cmd.Debug = options.Debug
	cmd.Port = options.Port
	if options.Path == "" {
		dir, err := vos.Getwd()
		if err != nil {
			return nil, nil, kerr.Wrap("OKOLXAMBSJ", err)
		}
		p, err := packages.GetPackageFromDir(ctx, dir)
		if err != nil {
			return nil, nil, kerr.Wrap("ADNJKTLAWY", err)
		}
		path = p
	} else {
		path = options.Path
	}

	ctx = cmdctx.NewContext(ctx, cmd)

	pcache, err := parser.Parse(ctx, path)
	if err != nil {
		return nil, nil, kerr.Wrap("EBMBIBIKUF", err)
	}

	ctx = envctx.NewContext(ctx, pcache.Env)

	return ctx, cancel, nil
}
예제 #5
0
파일: parser.go 프로젝트: kego/ke
func ProcessTypeFileBytes(ctx context.Context, env *envctx.Env, filename string, bytes []byte, cache *sysctx.SysPackageInfo, hash *PackageHasher) error {
	t := new(system.Type)
	if err := system.Unmarshal(envctx.NewContext(ctx, env), bytes, t); err != nil {
		return kerr.Wrap("NLRRVIDVWM", err)
	}
	if hash != nil {
		hash.Types[t.Id.Name] = cityhash.CityHash64(bytes, uint32(len(bytes)))
	}
	cache.Types.Set(t.Id.Name, filename, t)
	cache.Files.Set(t.Id.Name, filename, bytes)
	if t.Rule != nil {
		id := system.NewReference(t.Id.Package, fmt.Sprint("@", t.Id.Name))
		if t.Rule.Id != nil && *t.Rule.Id != *id {
			return kerr.New("JKARKEDTIW", "Incorrect id for %v - it should be %v", t.Rule.Id.String(), id.String())
		}
		t.Rule.Id = id

		// Check that the rule embeds system:rule
		found := false
		for _, em := range t.Rule.Embed {
			if *em == *system.NewReference("kego.io/system", "rule") {
				found = true
			}
		}
		if !found {
			return kerr.New("LMALEMKFDI", "%s does not embed system:rule", id.String())
		}

		cache.Types.Set(id.Name, filename, t.Rule)
	} else {
		// If the rule is missing, automatically create a default.
		id := system.NewReference(t.Id.Package, fmt.Sprint("@", t.Id.Name))
		rule := &system.Type{
			Object: &system.Object{
				Description: fmt.Sprintf("Automatically created basic rule for %s", t.Id.Name),
				Type:        system.NewReference("kego.io/system", "type"),
				Id:          id,
			},
			Embed:     []*system.Reference{system.NewReference("kego.io/system", "rule")},
			Native:    system.NewString("object"),
			Interface: false,
		}
		cache.Types.Set(id.Name, filename, rule)
	}

	return nil
}
예제 #6
0
파일: package.go 프로젝트: kego/ke
func Scan(ctx context.Context, path string) (*Package, error) {
	p := new(Package)
	// use a new system context for the duration of the scan
	ctx = sysctx.NewContext(ctx)
	env, err := parser.ScanForEnv(ctx, path)
	if err != nil {
		return nil, kerr.Wrap("SFPSTLPKMX", err)
	}
	p.Env = env
	files := scanner.ScanDirToFiles(ctx, env.Dir, env.Recursive)
	bytes := scanner.ScanFilesToBytes(ctx, files)
	localContext := envctx.NewContext(ctx, env)
	for b := range bytes {
		f := new(File)
		f.Package = p
		if b.Err != nil {
			return nil, kerr.Wrap("IPUHPBBWEA", b.Err)
		}
		o := &system.ObjectStub{}
		if err := system.Unmarshal(localContext, b.Bytes, o); err != nil {
			return nil, kerr.Wrap("DCAGIDLXRT", err)
		}
		if o.Type == nil {
			return nil, kerr.New("AJPCEQTWPS", "%s has no type", b.File)
		}
		if o.Id == nil && *o.Type != *system.NewReference("kego.io/system", "package") {
			// we tolerate missing ID only for system:package
			return nil, kerr.New("YDKYLXTGYC", "%s has no id", b.File)
		}
		f.AbsoluteFilepath = b.File
		f.Type = o.Type
		f.Id = o.Id
		if f.RelativeFilepath, err = filepath.Rel(env.Dir, b.File); err != nil {
			return nil, kerr.Wrap("QDAEGOWTWP", err)
		}
		f.Directory, f.Filename = filepath.Split(b.File)
		f.IsInRoot = DirEqual(f.Directory, env.Dir)
		f.Extension = filepath.Ext(b.File)
		f.Yaml = f.Extension == ".yaml" || f.Extension == ".yml"
		p.Files = append(p.Files, f)
	}
	return p, nil
}
예제 #7
0
파일: parser.go 프로젝트: kego/ke
func scanForPackage(ctx context.Context, env *envctx.Env) (*system.Package, error) {
	localContext := envctx.NewContext(ctx, env)
	files := scanner.ScanDirToFiles(ctx, env.Dir, false)
	bytes := scanner.ScanFilesToBytes(ctx, files)
	for b := range bytes {
		if b.Err != nil {
			return nil, kerr.Wrap("GATNNQKNHY", b.Err, b.File)
		}
		o := &system.ObjectStub{}
		if err := system.Unmarshal(localContext, b.Bytes, o); err != nil {
			switch kerr.Source(err).(type) {
			case system.UnknownPackageError, system.UnknownTypeError:
				// don't return error
			default:
				return nil, kerr.Wrap("MTDCXBYBEJ", err, b.File)
			}
		}
		if o.Type == nil {
			return nil, kerr.New("MSNIGTIDIO", "%s has no type", b.File)
		}
		switch *o.Type {
		case *system.NewReference("kego.io/system", "package"):
			var i interface{}
			err := system.Unmarshal(localContext, b.Bytes, &i)
			if err != nil {
				switch kerr.Source(err).(type) {
				case system.UnknownPackageError, system.UnknownTypeError:
					// don't return error
				default:
					return nil, kerr.Wrap("XTEQCAYQJP", err)
				}
			}
			if pkg, ok := i.(*system.Package); ok {
				return pkg, nil
			}
		}
	}
	return nil, nil
}
예제 #8
0
파일: calls.go 프로젝트: kego/ke
func (s *Server) Data(request *shared.DataRequest, response *shared.DataResponse) error {
	if !s.auth.Auth([]byte(request.Path), request.Hash) {
		return kerr.New("SYEKLIUMVY", "Auth failed")
	}

	env, err := parser.ScanForEnv(s.ctx, request.Package)
	if err != nil {
		return kerr.Wrap("PNAGGKHDYL", err)
	}

	full, err := pkghelp.Check(env.Dir, request.File, env.Recursive)
	if err != nil {
		return kerr.Wrap("JEYTFWKMYF", err)
	}

	bytes, err := scanner.ProcessFile(full)
	if err != nil {
		return kerr.Wrap("HQXMIMWXFY", err)
	}
	if bytes == nil {
		return kerr.New("HIUINHIAPY", "Error reading %s", request.File)
	}

	localContext := envctx.NewContext(s.ctx, env)
	o := &system.ObjectStub{}
	if err := system.Unmarshal(localContext, bytes, o); err != nil {
		return kerr.Wrap("SVINFEMKBG", err)
	}
	if o.Id.Name != request.Name {
		return kerr.New("TNJSLMPMLB", "Id %s in %s does not match request %s", o.Id.Name, request.File, request.Name)
	}

	response.Package = request.Package
	response.Name = request.Name
	response.Found = true
	response.Data = bytes
	return nil
}
예제 #9
0
func NewContext(ctx context.Context, path string, aliases map[string]string) context.Context {
	ctx = envctx.NewContext(ctx, &envctx.Env{Path: path, Aliases: aliases})
	ctx = jsonctx.AutoContext(ctx)
	return ctx
}
예제 #10
0
파일: client.go 프로젝트: kego/ke
func Start() error {

	loc := dom.GetWindow().Location()
	addr := fmt.Sprintf("ws://%s:%s/_rpc", loc.Hostname, loc.Port)
	ws, err := websocket.Dial(addr)
	if err != nil {
		return kerr.Wrap("HNQFLPFAJD", err)
	}

	app := &stores.App{
		Conn: connection.New(rpc.NewClient(ws)),
		Fail: make(chan error),
	}

	// We parse the info attribute from the body tag
	info, err := getInfo(getRawInfo())
	if err != nil {
		return kerr.Wrap("MGLVIQIDDY", err)
	}

	var ctx context.Context
	ctx = context.Background()
	ctx = envctx.NewContext(ctx, &envctx.Env{Path: info.Path, Aliases: info.Aliases})
	ctx = sysctx.NewContext(ctx)
	ctx = jsonctx.AutoContext(ctx)
	ctx = stores.NewContext(ctx, app)
	ctx = clientctx.NewContext(ctx)

	app.Init(ctx)

	// Don't do this. Implement the Editable interface instead. We can't do
	// this for system types so we use this method instead.
	editors.Register(ctx)

	if _, err := registerTypes(ctx, info.Path, info.Imports); err != nil {
		return kerr.Wrap("MMJDDOBAUK", err)
	}

	p := views.NewPage(ctx)
	vecty.RenderBody(p)

	// TODO: work out why I can't seem to call this without using eval
	js.Global.Get("window").Call("eval", "Split(['#tree', '#main'], {sizes:[25, 75]});")

	app.Dispatch(&actions.InitialState{
		Info: info,
	})

	go func() {
		err, open := <-app.Fail
		if !open {
			// Channel has been closed, so app should gracefully exit.
			fmt.Println("Server disconnected")
		} else {
			// Error received, so app should display error.
			fmt.Println(err.Error())
		}
	}()

	return nil
}
예제 #11
0
파일: calls.go 프로젝트: kego/ke
func (s *Server) Save(request *shared.SaveRequest, response *shared.SaveResponse) error {
	if !s.auth.Auth([]byte(request.Path), request.Hash) {
		return kerr.New("GIONMMGOWA", "Auth failed")
	}
	pkg, err := pkghelp.Scan(s.ctx, request.Path)
	if err != nil {
		return kerr.Wrap("YKYVDSDGNV", err)
	}
	localContext := envctx.NewContext(s.ctx, pkg.Env)
	for _, info := range request.Files {

		// Check we only have yml, yaml or json extension.
		ext := filepath.Ext(info.File)
		if ext != ".json" && ext != ".yml" && ext != ".yaml" {
			return kerr.New("NDTPTCDOET", "Unsupported extension %s in %s", ext, info.File)
		}

		// Check the bytes are well formed json...
		o := &system.ObjectStub{}
		if err := system.Unmarshal(localContext, info.Bytes, o); err != nil {
			return kerr.Wrap("QISVPOXTCJ", err)
		}
		// Check type field exists
		if o.Type == nil {
			return kerr.New("PHINYFTGEC", "%s has no type", info.File)
		}
		// Check id field exists apart from system:package type.
		if o.Id == nil && *o.Type != *system.NewReference("kego.io/system", "package") {
			return kerr.New("NNOEQPRQXS", "%s has no id", info.File)
		}
		// Convert output to YAML if needed.
		output := info.Bytes
		if ext == ".yaml" || ext == ".yml" {
			var err error
			if output, err = yaml.JSONToYAML(output); err != nil {
				return kerr.Wrap("EAMEWSCAGB", err)
			}
		}

		var mode os.FileMode
		var full string

		file := pkg.File(info.File)
		if file != nil {
			// The file already exists, so we should use the existing filemode
			full = file.AbsoluteFilepath
			fs, err := os.Stat(full)
			if err != nil {
				return kerr.Wrap("VLIJSSVSXU", err)
			}
			mode = fs.Mode()
		} else {
			if full, err = pkghelp.Check(pkg.Env.Dir, info.File, pkg.Env.Recursive); err != nil {
				return kerr.Wrap("YSQEHPFIVF", err)
			}
			mode = 0644
			if _, err := os.Stat(full); err == nil || !os.IsNotExist(err) {
				return kerr.New("XOEPAUNCXB", "Can't overwrite %s - existing file is not a valid ke data file", info.File)
			}
		}

		if err := ioutil.WriteFile(full, output, mode); err != nil {
			return kerr.Wrap("KPDYGCYOYQ", err)
		}

		response.Files = append(response.Files, shared.SaveResponseFile{
			File: info.File,
			Hash: info.Hash,
		})
	}
	return nil
}