graphql-engine/cli/plugins/paths/paths.go

112 lines
3.6 KiB
Go

// Copyright 2019 The Kubernetes Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package paths
import (
"os"
"path/filepath"
"github.com/pkg/errors"
)
const (
ManifestExtension string = ".yaml"
ManifestFile string = "manifest.yaml"
)
// Paths contains all important environment paths
type Paths struct {
base string
tmp string
}
func NewPaths(base string) Paths {
return Paths{base: base, tmp: os.TempDir()}
}
// BasePath returns hasura base directory.
func (p Paths) BasePath() string { return p.base }
// IndexPath returns the base directory where plugin index repository is cloned.
//
// e.g. {BasePath}/index/
func (p Paths) IndexPath() string { return filepath.Join(p.base, "index") }
// IndexPluginsPath returns the plugins directory of the index repository.
//
// e.g. {BasePath}/index/plugins/
func (p Paths) IndexPluginsPath() string { return filepath.Join(p.base, "index", "plugins") }
// InstallReceiptsPath returns the base directory where plugin receipts are stored.
//
// e.g. {BasePath}/receipts
func (p Paths) InstallReceiptsPath() string { return filepath.Join(p.base, "receipts") }
// BinPath returns the path where plugin executable symbolic links are found.
// This path should be added to $PATH in client machine.
//
// e.g. {BasePath}/bin
func (p Paths) BinPath() string { return filepath.Join(p.base, "bin") }
// DownloadPath returns a temporary directory for downloading plugins. It does
// not create a new directory on each call.
func (p Paths) DownloadPath() string { return filepath.Join(p.tmp, "plugins-downloads") }
// InstallPath returns the base directory for plugin installations.
//
// e.g. {BasePath}/store
func (p Paths) InstallPath() string { return filepath.Join(p.base, "store") }
// PluginInstallPath returns the path to install the plugin.
//
// e.g. {InstallPath}/{version}/{..files..}
func (p Paths) PluginInstallPath(plugin string) string {
return filepath.Join(p.InstallPath(), plugin)
}
// PluginInstallReceiptPath returns the path to the install receipt for plugin.
//
// e.g. {InstallReceiptsPath}/{plugin}.yaml
func (p Paths) PluginInstallReceiptPath(plugin string) string {
return filepath.Join(p.InstallReceiptsPath(), plugin+ManifestExtension)
}
// PluginVersionInstallPath returns the path to the specified version of specified
// plugin.
//
// e.g. {PluginInstallPath}/{plugin}/{version}
func (p Paths) PluginVersionInstallPath(plugin, version string) string {
return filepath.Join(p.InstallPath(), plugin, version)
}
// Realpath evaluates symbolic links. If the path is not a symbolic link, it
// returns the cleaned path. Symbolic links with relative paths return error.
func Realpath(path string) (string, error) {
s, err := os.Lstat(path)
if err != nil {
return "", errors.Wrapf(err, "failed to stat the currently executed path (%q)", path)
}
if s.Mode()&os.ModeSymlink != 0 {
if path, err = os.Readlink(path); err != nil {
return "", errors.Wrap(err, "failed to resolve the symlink of the currently executed version")
}
if !filepath.IsAbs(path) {
return "", errors.Errorf("symbolic link is relative (%s)", path)
}
}
return filepath.Clean(path), nil
}