<commit_before>package manager

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
	"strings"

	"github.com/docker/cli/cli/command"
	"github.com/docker/cli/cli/config"
	"github.com/fvbommel/sortorder"
	"github.com/spf13/cobra"
	exec "golang.org/x/sys/execabs"
)

// ReexecEnvvar is the name of an ennvar which is set to the command
// used to originally invoke the docker CLI when executing a
// plugin. Assuming $PATH and $CWD remain unchanged this should allow
// the plugin to re-execute the original CLI.
const ReexecEnvvar = "DOCKER_CLI_PLUGIN_ORIGINAL_CLI_COMMAND"

// errPluginNotFound is the error returned when a plugin could not be found.
type errPluginNotFound string

func (e errPluginNotFound) NotFound() {}

func (e errPluginNotFound) Error() string {
	return "Error: No such CLI plugin: " + string(e)
}

type notFound interface{ NotFound() }

// IsNotFound is true if the given error is due to a plugin not being found.
func IsNotFound(err error) bool {
	if e, ok := err.(*pluginError); ok {
		err = e.Cause()
	}
	_, ok := err.(notFound)
	return ok
}

func getPluginDirs(dockerCli command.Cli) ([]string, error) {
	var pluginDirs []string

	if cfg := dockerCli.ConfigFile(); cfg != nil {
		pluginDirs = append(pluginDirs, cfg.CLIPluginsExtraDirs...)
	}
	pluginDir, err := config.Path("cli-plugins")
	if err != nil {
		return nil, err
	}

	pluginDirs = append(pluginDirs, pluginDir)
	pluginDirs = append(pluginDirs, defaultSystemPluginDirs...)
	return pluginDirs, nil
}

func addPluginCandidatesFromDir(res map[string][]string, d string) error {
	dentries, err := ioutil.ReadDir(d)
	if err != nil {
		return err
	}
	for _, dentry := range dentries {
		switch dentry.Mode() & os.ModeType {
		case 0, os.ModeSymlink:
			// Regular file or symlink, keep going
		default:<commit_msg>cli-plugins/manager: remove uses of deprecated io/ioutil<commit_after>package manager

import (
	"os"
	"path/filepath"
	"sort"
	"strings"

	"github.com/docker/cli/cli/command"
	"github.com/docker/cli/cli/config"
	"github.com/fvbommel/sortorder"
	"github.com/spf13/cobra"
	exec "golang.org/x/sys/execabs"
)

// ReexecEnvvar is the name of an ennvar which is set to the command
// used to originally invoke the docker CLI when executing a
// plugin. Assuming $PATH and $CWD remain unchanged this should allow
// the plugin to re-execute the original CLI.
const ReexecEnvvar = "DOCKER_CLI_PLUGIN_ORIGINAL_CLI_COMMAND"

// errPluginNotFound is the error returned when a plugin could not be found.
type errPluginNotFound string

func (e errPluginNotFound) NotFound() {}

func (e errPluginNotFound) Error() string {
	return "Error: No such CLI plugin: " + string(e)
}

type notFound interface{ NotFound() }

// IsNotFound is true if the given error is due to a plugin not being found.
func IsNotFound(err error) bool {
	if e, ok := err.(*pluginError); ok {
		err = e.Cause()
	}
	_, ok := err.(notFound)
	return ok
}

func getPluginDirs(dockerCli command.Cli) ([]string, error) {
	var pluginDirs []string

	if cfg := dockerCli.ConfigFile(); cfg != nil {
		pluginDirs = append(pluginDirs, cfg.CLIPluginsExtraDirs...)
	}
	pluginDir, err := config.Path("cli-plugins")
	if err != nil {
		return nil, err
	}

	pluginDirs = append(pluginDirs, pluginDir)
	pluginDirs = append(pluginDirs, defaultSystemPluginDirs...)
	return pluginDirs, nil
}

func addPluginCandidatesFromDir(res map[string][]string, d string) error {
	dentries, err := os.ReadDir(d)
	if err != nil {
		return err
	}
	for _, dentry := range dentries {
		switch dentry.Type() & os.ModeType {
		case 0, os.ModeSymlink:
			// Regular file or symlink, keep going
		default:
{'fraction_non_alphanumeric': 0.11476769911504425, 'fraction_numerical': 0.00165929203539823, 'mean_word_length': 4.137784090909091, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5976793', 'n_tokens_mistral': 1293, 'n_tokens_neox': 1233, 'n_words': 377}