Giter Club home page Giter Club logo

gosh's Introduction

Gosh - A pluggable interactive shell written Go

Gosh (or Go shell) is a framework that uses Go's plugin system to create for building interactive console-based shell programs. A gosh shell is comprised of a collection of Go plugins which implement one or more commands. When gosh starts, it searches directory ./plugins for available shared object files that implement command plugins.

Getting started

Pre-requisites

  • Go 1.8 or above
  • Linux
  • Mac OSX

Gosh makes it easy to create shell programs. First, download or clone this repository. For a quick start, run the following:

go run shell/gosh.go

This will produce the following output:

                        888
                        888
                        888
 .d88b.  .d88b. .d8888b 88888b.
d88P"88bd88""88b88K     888 "88b
888  888888  888"Y8888b.888  888
Y88b 888Y88..88P     X88888  888
 "Y88888 "Y88P"  88888P'888  888
     888
Y8b d88P
 "Y88P"

No commands found

After the splashscreen is displayed, gosh informs you that no commands found, as expected. Next, exit the gosh shell (Ctrl-C) and let us compile the example plugins that comes with the source code.

go build -buildmode=plugin  -o plugins/sys_command.so plugins/syscmd.go

The previous command will compile plugins/syscmd.go and outputs shared object plugins/sys_command.so, as a Go plugin file. Verify the shared object file was created:

> ls -lh plugins/
total 3.2M
-rw-rw-r-- 1  4.5K Mar 19 18:23 syscmd.go
-rw-rw-r-- 1  3.2M Mar 19 19:14 sys_command.so
-rw-rw-r-- 1  1.4K Mar 19 18:23 testcmd.go

Now, when gosh is restarted, it will dynamically load the commands implemented in the shared object file:

> go run shell/gosh.go
...

Loaded 4 command(s)...
Type help for available commands

gosh>

As indicated, typing help lists all available commands in the shell:

gosh> help

help: prints help information for other commands.

Available commands
------------------
      prompt:	sets a new shell prompt
         sys:	sets a new shell prompt
        help:	prints help information for other commands.
        exit:	exits the interactive shell immediately

Use "help <command-name>" for detail about the specified command

A command

A Gosh Command is represented by type api/Command:

type Command interface {
	Name() string
	Usage() string
	ShortDesc() string
	LongDesc() string
	Exec(context.Context, []string) (context.Context, error)
}

The Gosh framework searches for Go plugin files in the ./plugins directory. Each package plugin must export a variable named Commands which is of type :

type Commands interface {
  ...
	Registry() map[string]Command
}

Type Commands type returns a list of Command via the Registry().

The following shows example command file plugins/testcmd.go. It implements two commands via types helloCmd and goodbyeCmd. The commands are exported via type testCmds using method Registry():

package main

import (
	"context"
	"fmt"
	"io"

	"github.com/vladimirvivien/gosh/api"
)

type helloCmd string

func (t helloCmd) Name() string      { return string(t) }
func (t helloCmd) Usage() string     { return `hello` }
func (t helloCmd) ShortDesc() string { return `prints greeting "hello there"` }
func (t helloCmd) LongDesc() string  { return t.ShortDesc() }
func (t helloCmd) Exec(ctx context.Context, args []string) (context.Context, error) {
	out := ctx.Value("gosh.stdout").(io.Writer)
	fmt.Fprintln(out, "hello there")
	return ctx, nil
}

type goodbyeCmd string

func (t goodbyeCmd) Name() string      { return string(t) }
func (t goodbyeCmd) Usage() string     { return t.Name() }
func (t goodbyeCmd) ShortDesc() string { return `prints message "bye bye"` }
func (t goodbyeCmd) LongDesc() string  { return t.ShortDesc() }
func (t goodbyeCmd) Exec(ctx context.Context, args []string) (context.Context, error) {
	out := ctx.Value("gosh.stdout").(io.Writer)
	fmt.Fprintln(out, "bye bye")
	return ctx, nil
}

// command module
type testCmds struct{}

func (t *testCmds) Init(ctx context.Context) error {
	out := ctx.Value("gosh.stdout").(io.Writer)
	fmt.Fprintln(out, "test module loaded OK")
	return nil
}

func (t *testCmds) Registry() map[string]api.Command {
	return map[string]api.Command{
		"hello":   helloCmd("hello"),
		"goodbye": goodbyeCmd("goodbye"),
	}
}

var Commands testCmds

License

MIT

gosh's People

Contributors

atakanyenel avatar gavinwade12 avatar merith-tk avatar philippgille avatar vladimirvivien avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.