mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
feat : adds pipx support to PMG (#292)
* adding the pipx support to project Signed-off-by: DivyanshuVortex <divyanshuchandra9027@gmail.com> * create excutors for pipx Signed-off-by: DivyanshuVortex <divyanshuchandra9027@gmail.com> * add pipx yml Signed-off-by: DivyanshuVortex <divyanshuchandra9027@gmail.com> * chores Signed-off-by: DivyanshuVortex <divyanshuchandra9027@gmail.com> * pipx to use standard executor pattern Signed-off-by: DivyanshuVortex <divyanshuchandra9027@gmail.com> * Address PR feedback for pipx support Signed-off-by: DivyanshuVortex <divyanshuchandra9027@gmail.com> * Update pipx flags comments Signed-off-by: DivyanshuVortex <divyanshuchandra9027@gmail.com> --------- Signed-off-by: DivyanshuVortex <divyanshuchandra9027@gmail.com> Co-authored-by: Abhisek Datta <abhisek.datta@gmail.com> Co-authored-by: Sahil Bansal <bansalsahil315@gmail.com>
This commit is contained in:
co-authored by
Abhisek Datta
Sahil Bansal
parent
ab1a5386d3
commit
7620097613
@@ -0,0 +1,254 @@
|
||||
package packagemanager
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPipxExecutorParseCommand(t *testing.T) {
|
||||
pm, err := NewPypiPackageExecutor(DefaultPipxPackageExecutorConfig())
|
||||
assert.NoError(t, err)
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expectedManifest bool
|
||||
expectedTargets int
|
||||
expectedPackages []string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "pipx install simple package",
|
||||
args: []string{"install", "black"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 1,
|
||||
expectedPackages: []string{"black"},
|
||||
},
|
||||
{
|
||||
name: "pipx install with specific version",
|
||||
args: []string{"install", "black==22.3.0"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 1,
|
||||
expectedPackages: []string{"black"},
|
||||
},
|
||||
{
|
||||
name: "pipx install with --force flag",
|
||||
args: []string{"install", "--force", "ruff"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 1,
|
||||
expectedPackages: []string{"ruff"},
|
||||
},
|
||||
{
|
||||
name: "pipx install with --pip-args flag",
|
||||
args: []string{"install", "--pip-args", "--no-cache-dir", "black"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 1,
|
||||
expectedPackages: []string{"black"},
|
||||
},
|
||||
{
|
||||
name: "pipx install with --python flag",
|
||||
args: []string{"install", "--python", "python3.11", "black"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 1,
|
||||
expectedPackages: []string{"black"},
|
||||
},
|
||||
{
|
||||
name: "pipx run simple package",
|
||||
args: []string{"run", "cowsay", "hello"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 1,
|
||||
expectedPackages: []string{"cowsay"},
|
||||
},
|
||||
{
|
||||
name: "pipx run with --spec flag",
|
||||
args: []string{"run", "--spec", "black==22.3.0", "black", "--check", "."},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 1,
|
||||
expectedPackages: []string{"black"},
|
||||
},
|
||||
{
|
||||
name: "pipx run with --no-cache flag",
|
||||
args: []string{"run", "--no-cache", "cowsay", "hello"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 1,
|
||||
expectedPackages: []string{"cowsay"},
|
||||
},
|
||||
{
|
||||
name: "pipx run bare (no package)",
|
||||
args: []string{"run"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 0,
|
||||
expectedPackages: []string{},
|
||||
},
|
||||
{
|
||||
name: "pipx inject skips target venv",
|
||||
args: []string{"inject", "poetry", "poetry-plugin-export"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 1,
|
||||
expectedPackages: []string{"poetry-plugin-export"},
|
||||
},
|
||||
{
|
||||
name: "pipx inject multiple packages",
|
||||
args: []string{"inject", "myapp", "requests", "flask"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 2,
|
||||
expectedPackages: []string{"requests", "flask"},
|
||||
},
|
||||
{
|
||||
name: "pipx inject with --force flag",
|
||||
args: []string{"inject", "--force", "poetry", "poetry-plugin-export"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 1,
|
||||
expectedPackages: []string{"poetry-plugin-export"},
|
||||
},
|
||||
{
|
||||
name: "pipx inject with --include-apps flag",
|
||||
args: []string{"inject", "--include-apps", "myapp", "flask"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 1,
|
||||
expectedPackages: []string{"flask"},
|
||||
},
|
||||
{
|
||||
name: "pipx inject with --pip-args flag",
|
||||
args: []string{"inject", "--pip-args", "--no-deps", "myapp", "flask"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 1,
|
||||
expectedPackages: []string{"flask"},
|
||||
},
|
||||
{
|
||||
name: "pipx inject only target venv (no packages)",
|
||||
args: []string{"inject", "poetry"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 0,
|
||||
expectedPackages: []string{},
|
||||
},
|
||||
{
|
||||
name: "pipx inject bare (no args)",
|
||||
args: []string{"inject"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 0,
|
||||
expectedPackages: []string{},
|
||||
},
|
||||
{
|
||||
name: "pipx list",
|
||||
args: []string{"list"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 0,
|
||||
expectedPackages: []string{},
|
||||
},
|
||||
{
|
||||
name: "pipx uninstall",
|
||||
args: []string{"uninstall", "black"},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 0,
|
||||
expectedPackages: []string{},
|
||||
},
|
||||
{
|
||||
name: "bare pipx invocation",
|
||||
args: []string{},
|
||||
expectedManifest: false,
|
||||
expectedTargets: 0,
|
||||
expectedPackages: []string{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
result, err := pm.ParseCommand(tc.args)
|
||||
if tc.wantErr {
|
||||
assert.Error(t, err)
|
||||
return
|
||||
}
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, tc.expectedManifest, result.HasManifestInstall(), "HasManifestInstall mismatch")
|
||||
assert.Equal(t, tc.expectedTargets, len(result.InstallTargets), "Number of install targets mismatch")
|
||||
|
||||
for i, expectedPkg := range tc.expectedPackages {
|
||||
if i < len(result.InstallTargets) {
|
||||
target := result.InstallTargets[i]
|
||||
assert.Equal(t, expectedPkg, target.PackageVersion.Package.Name, "Package name mismatch for package %d", i)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPipxExecutorProxyBehavior(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
command string
|
||||
isKnownNonDownloadCmd bool
|
||||
isInstallationCommand bool
|
||||
}{
|
||||
{
|
||||
name: "pipx install — proxy runs",
|
||||
command: "pipx install black",
|
||||
isKnownNonDownloadCmd: false,
|
||||
isInstallationCommand: true,
|
||||
},
|
||||
{
|
||||
name: "pipx run — proxy runs",
|
||||
command: "pipx run cowsay moo",
|
||||
isKnownNonDownloadCmd: false,
|
||||
isInstallationCommand: true,
|
||||
},
|
||||
{
|
||||
name: "pipx inject — proxy runs",
|
||||
command: "pipx inject myapp requests",
|
||||
isKnownNonDownloadCmd: false,
|
||||
isInstallationCommand: true,
|
||||
},
|
||||
{
|
||||
name: "pipx upgrade — proxy runs (downloads newer version)",
|
||||
command: "pipx upgrade black",
|
||||
isKnownNonDownloadCmd: false,
|
||||
isInstallationCommand: true,
|
||||
},
|
||||
{
|
||||
name: "pipx upgrade-all — proxy runs (downloads newer versions)",
|
||||
command: "pipx upgrade-all",
|
||||
isKnownNonDownloadCmd: false,
|
||||
isInstallationCommand: false,
|
||||
},
|
||||
{
|
||||
name: "pipx list — proxy skipped",
|
||||
command: "pipx list",
|
||||
isKnownNonDownloadCmd: true,
|
||||
isInstallationCommand: false,
|
||||
},
|
||||
{
|
||||
name: "pipx uninstall — proxy skipped",
|
||||
command: "pipx uninstall black",
|
||||
isKnownNonDownloadCmd: true,
|
||||
isInstallationCommand: false,
|
||||
},
|
||||
{
|
||||
name: "pipx uninstall-all — proxy skipped",
|
||||
command: "pipx uninstall-all",
|
||||
isKnownNonDownloadCmd: true,
|
||||
isInstallationCommand: false,
|
||||
},
|
||||
{
|
||||
name: "pipx completions — proxy skipped",
|
||||
command: "pipx completions",
|
||||
isKnownNonDownloadCmd: true,
|
||||
isInstallationCommand: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
pm, err := NewPypiPackageExecutor(DefaultPipxPackageExecutorConfig())
|
||||
assert.NoError(t, err)
|
||||
|
||||
parsed, err := pm.ParseCommand(strings.Split(tc.command, " "))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.isKnownNonDownloadCmd, parsed.IsKnownNonDownloadCommand)
|
||||
assert.Equal(t, tc.isInstallationCommand, parsed.IsInstallationCommand())
|
||||
assert.Equal(t, !tc.isKnownNonDownloadCmd, parsed.MayDownloadPackages())
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user