mirror of
				https://github.com/go-micro/go-micro.git
				synced 2025-10-30 23:27:41 +02:00 
			
		
		
		
	Add runtime => run
This commit is contained in:
		
							
								
								
									
										7
									
								
								runtime/.travis.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								runtime/.travis.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| language: go | ||||
| go: | ||||
| - 1.9.4 | ||||
| - 1.10.x | ||||
| notifications: | ||||
|   slack: | ||||
|     secure: fQJsxnChA2JDbdNti8cLiBlVj/ws38vaLyDJzkM+jhrU8NmdPbnjYu99lauDak0Yy9qdLNYUUO1KP6Kn8gl5VcbdC0++T3jPNCgIkJpvm/DJZKKtWlDXCavCDZ3EtCv8IhviD2dguHGtcX08/G6zc9V44GQu3sPWDdGdYnplh7OBIvicJZ5v8o6TR/WZ/4waGCLxeR84fIamXcZTlHGk3hJMKqCsb6urJX42rOlfSgjourb1yu8Tyg8uTXsO3Z7fgiZ73mYvZ1iD1v5thHB8T6bfB4g3U3KE53IjV9oV9bL6iDoiHbPWTIHD6yaZKXDbMxyw/sZ70GgxXH795pJeVBAWv9X6nH+aemwR72kgszvDLq64jxeAqJAmK5OqRs0YSQMKmvceSCIbEptCnpdl0KhhDZg/ojsfJOHyJb/SrEcntuvvig7O3Qyp9OtJdXJa5JnXi7Z2tPDXy+QnL/WSXUHU7JnDfQeQJC6QawxVGllxECcStIVb2/FrT0wnEinS66uhQhW48zLFcbJIFYNVsTlCMkTjXBkSvbjn3qSQr9IaMvpmDXhp9EC99Y5DgkPFP0S7aGjPCxfgrMHxqyxeEwmJQ+vYO6sZxnZbOzUMYVgPdAptQJ30QjovoF3lcQoBnZjvoKdunKE4qvSFYsMlxDV0SJhS5bc+eIXNIN5jYE8= | ||||
							
								
								
									
										28
									
								
								runtime/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								runtime/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| # Runtime | ||||
|  | ||||
| A runtime for self governing services. | ||||
|  | ||||
| ## Overview | ||||
|  | ||||
| In recent years we've started to develop complex architectures for the pipeline between writing code and running it. This  | ||||
| philosophy of build, run, manage or however many variations, has created a number of layers of abstraction that make it  | ||||
| all the more difficult to run code. | ||||
|  | ||||
| Runtime manages the lifecycle of a service from source to running process. If the source is the *source of truth* then  | ||||
| everything in between running is wasted breath. Applications should be self governing and self sustaining.  | ||||
| To enable that we need libraries which make it possible. | ||||
|  | ||||
| Runtime will fetch source code, build a binary and execute it. Any Go program that uses this library should be able  | ||||
| to run dependencies or itself with ease, with the ability to update itself as the source is updated. | ||||
|  | ||||
| ## Features | ||||
|  | ||||
| - **Source** - Fetches source whether it be git, go, docker, etc | ||||
| - **Package** - Compiles the source into a binary which can be executed | ||||
| - **Process** - Executes a binary and creates a running process | ||||
|  | ||||
| ## Usage | ||||
|  | ||||
| TODO | ||||
|  | ||||
|  | ||||
							
								
								
									
										93
									
								
								runtime/package/docker/docker.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								runtime/package/docker/docker.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| // Package docker builds docker images | ||||
| package docker | ||||
|  | ||||
| import ( | ||||
| 	"archive/tar" | ||||
| 	"bytes" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
|  | ||||
| 	"github.com/fsouza/go-dockerclient" | ||||
| 	"github.com/micro/go-log" | ||||
| 	"github.com/micro/go-run/package" | ||||
| ) | ||||
|  | ||||
| type Packager struct { | ||||
| 	Options packager.Options | ||||
| 	Client  *docker.Client | ||||
| } | ||||
|  | ||||
| func (d *Packager) Compile(s *packager.Source) (*packager.Binary, error) { | ||||
| 	image := filepath.Join(s.Repository.Path, s.Repository.Name) | ||||
|  | ||||
| 	buf := new(bytes.Buffer) | ||||
| 	tw := tar.NewWriter(buf) | ||||
| 	defer tw.Close() | ||||
|  | ||||
| 	dockerFile := "Dockerfile" | ||||
|  | ||||
| 	// open docker file | ||||
| 	f, err := os.Open(filepath.Join(s.Repository.Path, s.Repository.Name, dockerFile)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	// read docker file | ||||
| 	by, err := ioutil.ReadAll(f) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	tarHeader := &tar.Header{ | ||||
| 		Name: dockerFile, | ||||
| 		Size: int64(len(by)), | ||||
| 	} | ||||
| 	err = tw.WriteHeader(tarHeader) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	_, err = tw.Write(by) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	tr := bytes.NewReader(buf.Bytes()) | ||||
|  | ||||
| 	err = d.Client.BuildImage(docker.BuildImageOptions{ | ||||
| 		Name:           image, | ||||
| 		Dockerfile:     dockerFile, | ||||
| 		InputStream:    tr, | ||||
| 		OutputStream:   ioutil.Discard, | ||||
| 		RmTmpContainer: true, | ||||
| 		SuppressOutput: true, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &packager.Binary{ | ||||
| 		Name:   image, | ||||
| 		Path:   image, | ||||
| 		Type:   "docker", | ||||
| 		Source: s, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| func (d *Packager) Delete(b *packager.Binary) error { | ||||
| 	image := filepath.Join(b.Path, b.Name) | ||||
| 	return d.Client.RemoveImage(image) | ||||
| } | ||||
|  | ||||
| func NewPackager(opts ...packager.Option) packager.Packager { | ||||
| 	options := packager.Options{} | ||||
| 	for _, o := range opts { | ||||
| 		o(&options) | ||||
| 	} | ||||
| 	endpoint := "unix:///var/run/docker.sock" | ||||
| 	client, err := docker.NewClient(endpoint) | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
| 	} | ||||
| 	return &Packager{ | ||||
| 		Options: options, | ||||
| 		Client:  client, | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										70
									
								
								runtime/package/go/golang.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								runtime/package/go/golang.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| // Package golang is a go package manager | ||||
| package golang | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"path/filepath" | ||||
|  | ||||
| 	"github.com/micro/go-run/package" | ||||
| ) | ||||
|  | ||||
| type Packager struct { | ||||
| 	Options packager.Options | ||||
| 	Cmd     string | ||||
| 	Path    string | ||||
| } | ||||
|  | ||||
| // whichGo locates the go command | ||||
| func whichGo() string { | ||||
| 	// check GOROOT | ||||
| 	if gr := os.Getenv("GOROOT"); len(gr) > 0 { | ||||
| 		return filepath.Join(gr, "bin", "go") | ||||
| 	} | ||||
|  | ||||
| 	// check path | ||||
| 	for _, p := range filepath.SplitList(os.Getenv("PATH")) { | ||||
| 		bin := filepath.Join(p, "go") | ||||
| 		if _, err := os.Stat(bin); err == nil { | ||||
| 			return bin | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// best effort | ||||
| 	return "go" | ||||
| } | ||||
|  | ||||
| func (g *Packager) Compile(s *packager.Source) (*packager.Binary, error) { | ||||
| 	binary := filepath.Join(g.Path, s.Repository.Name) | ||||
| 	source := filepath.Join(s.Repository.Path, s.Repository.Name) | ||||
|  | ||||
| 	cmd := exec.Command(g.Cmd, "build", "-o", binary, source) | ||||
| 	if err := cmd.Run(); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &packager.Binary{ | ||||
| 		Name:   s.Repository.Name, | ||||
| 		Path:   binary, | ||||
| 		Type:   "go", | ||||
| 		Source: s, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| func (g *Packager) Delete(b *packager.Binary) error { | ||||
| 	binary := filepath.Join(b.Path, b.Name) | ||||
| 	return os.Remove(binary) | ||||
| } | ||||
|  | ||||
| func NewPackager(opts ...packager.Option) packager.Packager { | ||||
| 	options := packager.Options{ | ||||
| 		Path: os.TempDir(), | ||||
| 	} | ||||
| 	for _, o := range opts { | ||||
| 		o(&options) | ||||
| 	} | ||||
| 	return &Packager{ | ||||
| 		Options: options, | ||||
| 		Cmd:     whichGo(), | ||||
| 		Path:    options.Path, | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										15
									
								
								runtime/package/options.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								runtime/package/options.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| package packager | ||||
|  | ||||
| type Options struct { | ||||
| 	// local path to download source | ||||
| 	Path string | ||||
| } | ||||
|  | ||||
| type Option func(o *Options) | ||||
|  | ||||
| // Local path for repository | ||||
| func Path(p string) Option { | ||||
| 	return func(o *Options) { | ||||
| 		o.Path = p | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										34
									
								
								runtime/package/package.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								runtime/package/package.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| // Package packager creates a binary image. Due to package being a reserved keyword we use packager. | ||||
| package packager | ||||
|  | ||||
| import ( | ||||
| 	"github.com/micro/go-run/source" | ||||
| ) | ||||
|  | ||||
| // Package builds binaries | ||||
| type Packager interface { | ||||
| 	// Compile builds a binary | ||||
| 	Compile(*Source) (*Binary, error) | ||||
| 	// Deletes the binary | ||||
| 	Delete(*Binary) error | ||||
| } | ||||
|  | ||||
| // Source is the source of a build | ||||
| type Source struct { | ||||
| 	// Language is the language of code | ||||
| 	Language string | ||||
| 	// Location of the source | ||||
| 	Repository *source.Repository | ||||
| } | ||||
|  | ||||
| // Binary is the representation of a binary | ||||
| type Binary struct { | ||||
| 	// Name of the binary | ||||
| 	Name string | ||||
| 	// Location of the binary | ||||
| 	Path string | ||||
| 	// Type of binary | ||||
| 	Type string | ||||
| 	// Source of the binary | ||||
| 	Source *Source | ||||
| } | ||||
							
								
								
									
										5
									
								
								runtime/process/options.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								runtime/process/options.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| package process | ||||
|  | ||||
| type Options struct{} | ||||
|  | ||||
| type Option func(o *Options) | ||||
							
								
								
									
										86
									
								
								runtime/process/os/os.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								runtime/process/os/os.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| // Package os runs processes locally | ||||
| package os | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"strconv" | ||||
|  | ||||
| 	"github.com/micro/go-run/process" | ||||
| ) | ||||
|  | ||||
| type Process struct { | ||||
| } | ||||
|  | ||||
| func (p *Process) Exec(exe *process.Executable) error { | ||||
| 	cmd := exec.Command(exe.Binary.Path) | ||||
| 	return cmd.Run() | ||||
| } | ||||
|  | ||||
| func (p *Process) Fork(exe *process.Executable) (*process.PID, error) { | ||||
| 	cmd := exec.Command(exe.Binary.Path) | ||||
| 	if err := cmd.Start(); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	in, err := cmd.StdinPipe() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	out, err := cmd.StdoutPipe() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	er, err := cmd.StderrPipe() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &process.PID{ | ||||
| 		ID:     fmt.Sprintf("%d", cmd.Process.Pid), | ||||
| 		Input:  in, | ||||
| 		Output: out, | ||||
| 		Error:  er, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| func (p *Process) Kill(pid *process.PID) error { | ||||
| 	id, err := strconv.Atoi(pid.ID) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	pr, err := os.FindProcess(id) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	return pr.Kill() | ||||
| } | ||||
|  | ||||
| func (p *Process) Wait(pid *process.PID) error { | ||||
| 	id, err := strconv.Atoi(pid.ID) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	pr, err := os.FindProcess(id) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	ps, err := pr.Wait() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if ps.Success() { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	return fmt.Errorf(ps.String()) | ||||
| } | ||||
|  | ||||
| func NewProcess(opts ...process.Option) process.Process { | ||||
| 	return &Process{} | ||||
| } | ||||
							
								
								
									
										37
									
								
								runtime/process/process.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								runtime/process/process.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| // Package process executes a binary | ||||
| package process | ||||
|  | ||||
| import ( | ||||
| 	"io" | ||||
|  | ||||
| 	"github.com/micro/go-run/package" | ||||
| ) | ||||
|  | ||||
| // Process manages a running process | ||||
| type Process interface { | ||||
| 	// Executes a process to completion | ||||
| 	Exec(*Executable) error | ||||
| 	// Creates a new process | ||||
| 	Fork(*Executable) (*PID, error) | ||||
| 	// Kills the process | ||||
| 	Kill(*PID) error | ||||
| 	// Waits for a process to exit | ||||
| 	Wait(*PID) error | ||||
| } | ||||
|  | ||||
| type Executable struct { | ||||
| 	// The executable binary | ||||
| 	Binary *packager.Binary | ||||
| } | ||||
|  | ||||
| // PID is the running process | ||||
| type PID struct { | ||||
| 	// ID of the process | ||||
| 	ID string | ||||
| 	// Stdin | ||||
| 	Input io.Writer | ||||
| 	// Stdout | ||||
| 	Output io.Reader | ||||
| 	// Stderr | ||||
| 	Error io.Reader | ||||
| } | ||||
							
								
								
									
										87
									
								
								runtime/source/git/git.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								runtime/source/git/git.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| // Package git provides a git source | ||||
| package git | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/micro/go-run/source" | ||||
| 	"gopkg.in/src-d/go-git.v4" | ||||
| ) | ||||
|  | ||||
| // Source retrieves source code | ||||
| // An empty struct can be used | ||||
| type Source struct { | ||||
| 	Options source.Options | ||||
| } | ||||
|  | ||||
| func (g *Source) Fetch(url string) (*source.Repository, error) { | ||||
| 	purl := url | ||||
|  | ||||
| 	if parts := strings.Split(url, "://"); len(parts) > 1 { | ||||
| 		purl = parts[len(parts)-1] | ||||
| 	} | ||||
|  | ||||
| 	name := filepath.Base(url) | ||||
| 	path := filepath.Join(g.Options.Path, purl) | ||||
|  | ||||
| 	_, err := git.PlainClone(path, false, &git.CloneOptions{ | ||||
| 		URL: url, | ||||
| 	}) | ||||
| 	if err == nil { | ||||
| 		return &source.Repository{ | ||||
| 			Name: name, | ||||
| 			Path: path, | ||||
| 			URL:  url, | ||||
| 		}, nil | ||||
| 	} | ||||
|  | ||||
| 	// repo already exists | ||||
| 	if err != git.ErrRepositoryAlreadyExists { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// open repo | ||||
| 	re, err := git.PlainOpen(path) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// update it | ||||
| 	if err := re.Fetch(nil); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &source.Repository{ | ||||
| 		Name: name, | ||||
| 		Path: path, | ||||
| 		URL:  url, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| func (g *Source) Commit(r *source.Repository) error { | ||||
| 	repo := filepath.Join(r.Path) | ||||
| 	re, err := git.PlainOpen(repo) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return re.Push(nil) | ||||
| } | ||||
|  | ||||
| func (g *Source) String() string { | ||||
| 	return "git" | ||||
| } | ||||
|  | ||||
| func NewSource(opts ...source.Option) *Source { | ||||
| 	options := source.Options{ | ||||
| 		Path: os.TempDir(), | ||||
| 	} | ||||
| 	for _, o := range opts { | ||||
| 		o(&options) | ||||
| 	} | ||||
|  | ||||
| 	return &Source{ | ||||
| 		Options: options, | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										93
									
								
								runtime/source/go/golang.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								runtime/source/go/golang.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| // Package golang is a source for Go | ||||
| package golang | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/micro/go-run/source" | ||||
| ) | ||||
|  | ||||
| type Source struct { | ||||
| 	Options source.Options | ||||
| 	// Go Command | ||||
| 	Cmd  string | ||||
| 	Path string | ||||
| } | ||||
|  | ||||
| func (g *Source) Fetch(url string) (*source.Repository, error) { | ||||
| 	purl := url | ||||
|  | ||||
| 	if parts := strings.Split(url, "://"); len(parts) > 1 { | ||||
| 		purl = parts[len(parts)-1] | ||||
| 	} | ||||
|  | ||||
| 	// name of repo | ||||
| 	name := filepath.Base(url) | ||||
| 	// local path of repo | ||||
| 	path := filepath.Join(g.Path, purl) | ||||
| 	args := []string{"get", "-d", url, path} | ||||
|  | ||||
| 	cmd := exec.Command(g.Cmd, args...) | ||||
| 	if err := cmd.Run(); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &source.Repository{ | ||||
| 		Name: name, | ||||
| 		Path: path, | ||||
| 		URL:  url, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| // Commit is not yet supported | ||||
| func (g *Source) Commit(r *source.Repository) error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (g *Source) String() string { | ||||
| 	return "golang" | ||||
| } | ||||
|  | ||||
| // whichGo locates the go command | ||||
| func whichGo() string { | ||||
| 	// check GOROOT | ||||
| 	if gr := os.Getenv("GOROOT"); len(gr) > 0 { | ||||
| 		return filepath.Join(gr, "bin", "go") | ||||
| 	} | ||||
|  | ||||
| 	// check path | ||||
| 	for _, p := range filepath.SplitList(os.Getenv("PATH")) { | ||||
| 		bin := filepath.Join(p, "go") | ||||
| 		if _, err := os.Stat(bin); err == nil { | ||||
| 			return bin | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// best effort | ||||
| 	return "go" | ||||
| } | ||||
|  | ||||
| func NewSource(opts ...source.Option) source.Source { | ||||
| 	options := source.Options{ | ||||
| 		Path: os.TempDir(), | ||||
| 	} | ||||
| 	for _, o := range opts { | ||||
| 		o(&options) | ||||
| 	} | ||||
|  | ||||
| 	cmd := whichGo() | ||||
| 	path := options.Path | ||||
|  | ||||
| 	// point of no return | ||||
| 	if len(cmd) == 0 { | ||||
| 		panic("Could not find Go executable") | ||||
| 	} | ||||
|  | ||||
| 	return &Source{ | ||||
| 		Options: options, | ||||
| 		Cmd:     cmd, | ||||
| 		Path:    path, | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										15
									
								
								runtime/source/options.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								runtime/source/options.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| package source | ||||
|  | ||||
| type Options struct { | ||||
| 	// local path to download source | ||||
| 	Path string | ||||
| } | ||||
|  | ||||
| type Option func(o *Options) | ||||
|  | ||||
| // Local path for repository | ||||
| func Path(p string) Option { | ||||
| 	return func(o *Options) { | ||||
| 		o.Path = p | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										22
									
								
								runtime/source/source.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								runtime/source/source.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| // Package source retrieves source code | ||||
| package source | ||||
|  | ||||
| // Source retrieves source code | ||||
| type Source interface { | ||||
| 	// Fetch repo from a url | ||||
| 	Fetch(url string) (*Repository, error) | ||||
| 	// Commit and upload repo | ||||
| 	Commit(*Repository) error | ||||
| 	// The sourcerer | ||||
| 	String() string | ||||
| } | ||||
|  | ||||
| // Repository is the source repository | ||||
| type Repository struct { | ||||
| 	// Name or repo | ||||
| 	Name string | ||||
| 	// Local path where repo is stored | ||||
| 	Path string | ||||
| 	// URL from which repo was retrieved | ||||
| 	URL string | ||||
| } | ||||
		Reference in New Issue
	
	Block a user