-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4033 from ipfs/feat/git-plugin
plugin: create plugin API and loader, add ipld-git plugin
- Loading branch information
Showing
26 changed files
with
570 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package coredag | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
|
||
node "gx/ipfs/QmYNyRZJBUYPNrLszFmrBrPJbsBh2vMsefz5gnDpB5M1P6/go-ipld-format" | ||
ipldcbor "gx/ipfs/QmemYymP73eVdTUUMZEiSpiHeZQKNJdT5dP2iuHssZh1sR/go-ipld-cbor" | ||
) | ||
|
||
// DagParser is function used for parsing stream into Node | ||
type DagParser func(r io.Reader) ([]node.Node, error) | ||
|
||
// FormatParsers is used for mapping format descriptors to DagParsers | ||
type FormatParsers map[string]DagParser | ||
|
||
// InputEncParsers is used for mapping input encodings to FormatParsers | ||
type InputEncParsers map[string]FormatParsers | ||
|
||
// DefaultInputEncParsers is InputEncParser that is used everywhere | ||
var DefaultInputEncParsers = InputEncParsers{ | ||
"json": defaultJSONParsers, | ||
"raw": defaultRawParsers, | ||
} | ||
|
||
var defaultJSONParsers = FormatParsers{ | ||
"cbor": cborJSONParser, | ||
"dag-cbor": cborJSONParser, | ||
} | ||
|
||
var defaultRawParsers = FormatParsers{ | ||
"cbor": cborRawParser, | ||
"dag-cbor": cborRawParser, | ||
} | ||
|
||
// ParseInputs uses DefaultInputEncParsers to parse io.Reader described by | ||
// input encoding and format to an instance of ipld Node | ||
func ParseInputs(ienc, format string, r io.Reader) ([]node.Node, error) { | ||
return DefaultInputEncParsers.ParseInputs(ienc, format, r) | ||
} | ||
|
||
// AddParser adds DagParser under give input encoding and format | ||
func (iep InputEncParsers) AddParser(ienv, format string, f DagParser) { | ||
m, ok := iep[ienv] | ||
if !ok { | ||
m = make(FormatParsers) | ||
iep[ienv] = m | ||
} | ||
|
||
m[format] = f | ||
} | ||
|
||
// ParseInputs parses io.Reader described by input encoding and format to | ||
// an instance of ipld Node | ||
func (iep InputEncParsers) ParseInputs(ienc, format string, r io.Reader) ([]node.Node, error) { | ||
pset, ok := iep[ienc] | ||
if !ok { | ||
return nil, fmt.Errorf("no input parser for %q", ienc) | ||
} | ||
|
||
parser, ok := pset[format] | ||
if !ok { | ||
return nil, fmt.Errorf("no parser for format %q using input type %q", format, ienc) | ||
} | ||
|
||
return parser(r) | ||
} | ||
|
||
func cborJSONParser(r io.Reader) ([]node.Node, error) { | ||
nd, err := ipldcbor.FromJson(r) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return []node.Node{nd}, nil | ||
} | ||
|
||
func cborRawParser(r io.Reader) ([]node.Node, error) { | ||
data, err := ioutil.ReadAll(r) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
nd, err := ipldcbor.Decode(data) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return []node.Node{nd}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
include mk/header.mk | ||
|
||
dir := $(d)/loader | ||
include $(dir)/Rules.mk | ||
|
||
dir := $(d)/plugins | ||
include $(dir)/Rules.mk | ||
|
||
include mk/footer.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package plugin | ||
|
||
import ( | ||
"github.com/ipfs/go-ipfs/core/coredag" | ||
|
||
node "gx/ipfs/QmYNyRZJBUYPNrLszFmrBrPJbsBh2vMsefz5gnDpB5M1P6/go-ipld-format" | ||
) | ||
|
||
// PluginIPLD is an interface that can be implemented to add handlers for | ||
// for different IPLD formats | ||
type PluginIPLD interface { | ||
Plugin | ||
|
||
RegisterBlockDecoders(dec node.BlockDecoder) error | ||
RegisterInputEncParsers(iec coredag.InputEncParsers) error | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
preload.go |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
include mk/header.mk | ||
|
||
$(d)/preload.go: d:=$(d) | ||
$(d)/preload.go: $(d)/preload_list | ||
$(d)/preload.sh > $@ | ||
go fmt $@ >/dev/null | ||
|
||
DEPS_GO += $(d)/preload.go | ||
|
||
include mk/footer.mk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package loader | ||
|
||
import ( | ||
"github.com/ipfs/go-ipfs/core/coredag" | ||
"github.com/ipfs/go-ipfs/plugin" | ||
|
||
format "gx/ipfs/QmYNyRZJBUYPNrLszFmrBrPJbsBh2vMsefz5gnDpB5M1P6/go-ipld-format" | ||
) | ||
|
||
func initialize(plugins []plugin.Plugin) error { | ||
for _, p := range plugins { | ||
err := p.Init() | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func run(plugins []plugin.Plugin) error { | ||
for _, pl := range plugins { | ||
err := runIPLDPlugin(pl) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func runIPLDPlugin(pl plugin.Plugin) error { | ||
ipldpl, ok := pl.(plugin.PluginIPLD) | ||
if !ok { | ||
return nil | ||
} | ||
|
||
err := ipldpl.RegisterBlockDecoders(format.DefaultBlockDecoder) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return ipldpl.RegisterInputEncParsers(coredag.DefaultInputEncParsers) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package loader | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
|
||
"github.com/ipfs/go-ipfs/plugin" | ||
|
||
logging "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log" | ||
) | ||
|
||
var log = logging.Logger("plugin/loader") | ||
|
||
var loadPluginsFunc = func(string) ([]plugin.Plugin, error) { | ||
return nil, nil | ||
} | ||
|
||
// LoadPlugins loads and initializes plugins. | ||
func LoadPlugins(pluginDir string) ([]plugin.Plugin, error) { | ||
plMap := make(map[string]plugin.Plugin) | ||
for _, v := range preloadPlugins { | ||
plMap[v.Name()] = v | ||
} | ||
|
||
newPls, err := loadDynamicPlugins(pluginDir) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
for _, pl := range newPls { | ||
if ppl, ok := plMap[pl.Name()]; ok { | ||
// plugin is already preloaded | ||
return nil, fmt.Errorf( | ||
"plugin: %s, is duplicated in version: %s, "+ | ||
"while trying to load dynamically: %s", | ||
ppl.Name(), ppl.Version(), pl.Version()) | ||
} | ||
plMap[pl.Name()] = pl | ||
} | ||
|
||
pls := make([]plugin.Plugin, 0, len(plMap)) | ||
for _, v := range plMap { | ||
pls = append(pls, v) | ||
} | ||
|
||
err = initialize(pls) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
err = run(pls) | ||
return nil, err | ||
} | ||
|
||
func loadDynamicPlugins(pluginDir string) ([]plugin.Plugin, error) { | ||
_, err := os.Stat(pluginDir) | ||
if os.IsNotExist(err) { | ||
return nil, nil | ||
} | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return loadPluginsFunc(pluginDir) | ||
} |
Oops, something went wrong.