mirror of
https://github.com/zyedidia/micro.git
synced 2026-03-29 14:22:42 +09:00
Change project layout and use go.mod
This commit is contained in:
77
internal/manager/fetch.go
Normal file
77
internal/manager/fetch.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
git "gopkg.in/src-d/go-git.v4"
|
||||
)
|
||||
|
||||
// NewPluginInfoFromUrl creates a new PluginInfo from a URL by fetching
|
||||
// the data at that URL and parsing the JSON (running a GET request at
|
||||
// the URL should return the JSON for a plugin info)
|
||||
func NewPluginInfoFromUrl(url string) (*PluginInfo, error) {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
dat, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewPluginInfo(dat)
|
||||
}
|
||||
|
||||
// FetchRepo downloads this plugin's git repository
|
||||
func (i *PluginInfo) FetchRepo() error {
|
||||
dir := path.Join(config.ConfigDir, "plugin", i.Name)
|
||||
r, err := git.PlainClone(dir, false, &git.CloneOptions{
|
||||
URL: i.Repo,
|
||||
Progress: nil,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p := &Plugin{
|
||||
info: i,
|
||||
dir: dir,
|
||||
repo: r,
|
||||
}
|
||||
|
||||
err = p.ResolveVersion()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = p.WriteVersion()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *Plugin) ResolveVersion() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Plugin) WriteVersion() error {
|
||||
return ioutil.WriteFile(path.Join(p.dir, versionfile), []byte(p.version.String()), os.ModePerm)
|
||||
}
|
||||
|
||||
func (p *Plugin) FetchDeps() error {
|
||||
_, err := ListInstalledPlugins()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Plugin) PostInstallHooks() error {
|
||||
return nil
|
||||
}
|
||||
72
internal/manager/manager_test.go
Normal file
72
internal/manager/manager_test.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
)
|
||||
|
||||
func init() {
|
||||
config.InitConfigDir("./")
|
||||
}
|
||||
|
||||
var sampleJson = []byte(`{
|
||||
"name": "comment",
|
||||
"description": "Plugin to auto comment or uncomment lines",
|
||||
"website": "https://github.com/micro-editor/comment-plugin",
|
||||
"repository": "https://github.com/micro-editor/comment-plugin",
|
||||
"versions": [
|
||||
{
|
||||
"version": "1.0.6",
|
||||
"tag": "v1.0.6",
|
||||
"require": {
|
||||
"micro": ">=1.1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "1.0.5",
|
||||
"tag": "v1.0.5",
|
||||
"require": {
|
||||
"micro": ">=1.0.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"version": "1.0.6-dev",
|
||||
"tag": "nightly",
|
||||
"require": {
|
||||
"micro": ">=1.3.1"
|
||||
}
|
||||
}
|
||||
]
|
||||
}`)
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
_, err := NewPluginInfo(sampleJson)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// func TestFetch(t *testing.T) {
|
||||
// i, err := NewPluginInfoFromUrl("http://zbyedidia.webfactional.com/micro/test.json")
|
||||
// if err != nil {
|
||||
// t.Error(err)
|
||||
// }
|
||||
//
|
||||
// err = i.FetchRepo()
|
||||
// if err != nil {
|
||||
// t.Error(err)
|
||||
// }
|
||||
// }
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
is, err := ListInstalledPlugins()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
for _, i := range is {
|
||||
fmt.Println(i.Name)
|
||||
}
|
||||
}
|
||||
172
internal/manager/plugin.go
Normal file
172
internal/manager/plugin.go
Normal file
@@ -0,0 +1,172 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
|
||||
"github.com/blang/semver"
|
||||
"github.com/zyedidia/micro/internal/config"
|
||||
git "gopkg.in/src-d/go-git.v4"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrMissingName = errors.New("Missing or empty name field")
|
||||
ErrMissingDesc = errors.New("Missing or empty description field")
|
||||
ErrMissingSite = errors.New("Missing or empty website field")
|
||||
ErrMissingRepo = errors.New("Missing or empty repository field")
|
||||
ErrMissingVersions = errors.New("Missing or empty versions field")
|
||||
ErrMissingTag = errors.New("Missing or empty tag field")
|
||||
ErrMissingRequire = errors.New("Missing or empty require field")
|
||||
)
|
||||
|
||||
const (
|
||||
infojson = "plugin.json"
|
||||
versionfile = "version.lock"
|
||||
)
|
||||
|
||||
type Plugin struct {
|
||||
info *PluginInfo
|
||||
dir string
|
||||
repo *git.Repository
|
||||
version semver.Version // currently installed version
|
||||
}
|
||||
|
||||
func (p *Plugin) GetRequires() *PluginVersion {
|
||||
for _, v := range p.info.Versions {
|
||||
if p.version.Equals(v.Vers) {
|
||||
return &v
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PluginVersion describes a version for a plugin as well as any dependencies that
|
||||
// version might have
|
||||
// This marks a tag that corresponds to the version in the git repo
|
||||
type PluginVersion struct {
|
||||
Vers semver.Version
|
||||
Vstr string `json:"version"`
|
||||
Tag string `json:"tag"`
|
||||
Require map[string]string `json:"require"`
|
||||
}
|
||||
|
||||
// PluginInfo contains all the needed info about a plugin
|
||||
type PluginInfo struct {
|
||||
Name string `json:"name"`
|
||||
Desc string `json:"description"`
|
||||
Site string `json:"website"`
|
||||
Repo string `json:"repository"`
|
||||
Versions []PluginVersion `json:"versions"`
|
||||
}
|
||||
|
||||
// NewPluginInfo parses a JSON input into a valid PluginInfo struct
|
||||
// Returns an error if there are any missing fields or any invalid fields
|
||||
// There are no optional fields in a plugin info json file
|
||||
func NewPluginInfo(data []byte) (*PluginInfo, error) {
|
||||
var info PluginInfo
|
||||
|
||||
dec := json.NewDecoder(bytes.NewReader(data))
|
||||
dec.DisallowUnknownFields() // Force errors
|
||||
|
||||
if err := dec.Decode(&info); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(info.Name) == 0 {
|
||||
return nil, ErrMissingName
|
||||
} else if len(info.Desc) == 0 {
|
||||
return nil, ErrMissingDesc
|
||||
} else if len(info.Site) == 0 {
|
||||
return nil, ErrMissingSite
|
||||
} else if len(info.Repo) == 0 {
|
||||
return nil, ErrMissingRepo
|
||||
} else if err := info.makeVersions(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info, nil
|
||||
}
|
||||
|
||||
func (i *PluginInfo) makeVersions() error {
|
||||
if len(i.Versions) == 0 {
|
||||
return ErrMissingVersions
|
||||
}
|
||||
|
||||
for _, v := range i.Versions {
|
||||
sv, err := semver.Make(v.Vstr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v.Vers = sv
|
||||
if len(v.Tag) == 0 {
|
||||
return ErrMissingTag
|
||||
} else if v.Require == nil {
|
||||
return ErrMissingRequire
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListInstalledPlugins searches the config directory for all installed plugins
|
||||
// and returns the list of plugin infos corresponding to them
|
||||
func ListInstalledPlugins() ([]*Plugin, error) {
|
||||
pdir := path.Join(config.ConfigDir, "plugin")
|
||||
|
||||
files, err := ioutil.ReadDir(pdir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var plugins []*Plugin
|
||||
|
||||
for _, dir := range files {
|
||||
if dir.IsDir() {
|
||||
files, err := ioutil.ReadDir(path.Join(pdir, dir.Name()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
if f.Name() == infojson {
|
||||
dat, err := ioutil.ReadFile(path.Join(pdir, dir.Name(), infojson))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
info, err := NewPluginInfo(dat)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
versiondat, err := ioutil.ReadFile(path.Join(pdir, dir.Name(), versionfile))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sv, err := semver.Make(string(versiondat))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dirname := path.Join(pdir, dir.Name())
|
||||
r, err := git.PlainOpen(dirname)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p := &Plugin{
|
||||
info: info,
|
||||
dir: dirname,
|
||||
repo: r,
|
||||
version: sv,
|
||||
}
|
||||
|
||||
plugins = append(plugins, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return plugins, nil
|
||||
}
|
||||
Reference in New Issue
Block a user