Skip to content

Commit

Permalink
Merge branch 'main' into fingerprinting-improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
emilwareus authored Jan 17, 2024
2 parents 76e8813 + 525f851 commit 24b0da0
Show file tree
Hide file tree
Showing 24 changed files with 564 additions and 354 deletions.
9 changes: 9 additions & 0 deletions internal/resolution/job/base_job.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package job
import (
"errors"
"os/exec"
"strings"
)

type BaseJob struct {
Expand Down Expand Up @@ -49,3 +50,11 @@ func (j *BaseJob) GetExitError(err error, commandOutput string) error {

return errors.New(errorMessage)
}

func (j *BaseJob) GetExecutableNotFoundErrorDocumentation(pm string) string {
return strings.Join(
[]string{
pm + " wasn't found.",
"Please check if it is installed and accessible by the CLI.",
}, " ")
}
32 changes: 12 additions & 20 deletions internal/resolution/pm/bower/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
const (
bower = "bower"
fileName = "bower.debricked.lock"
bowerNotFoundErrRegex = `executable file not found`
executableNotFoundErrRegex = `executable file not found`
versionNotFoundErrRegex = `([^"\s:]+)\s+ENORESTARGET No tag found`
dependencyNotFoundErrRegex = `ENOTFOUND Package ([^"\s:]+) not found`
registryUnavailableErrRegex = `getaddrinfo EAI_AGAIN ([\w\/\-\.]+)`
Expand Down Expand Up @@ -111,7 +111,7 @@ func (j *Job) createError(error string, cmd string, status string) job.IError {

func (j *Job) handleError(cmdError job.IError) {
expressions := []string{
bowerNotFoundErrRegex,
executableNotFoundErrRegex,
versionNotFoundErrRegex,
dependencyNotFoundErrRegex,
registryUnavailableErrRegex,
Expand All @@ -137,32 +137,24 @@ func (j *Job) addDocumentation(expr string, matches [][]string, cmdError job.IEr
documentation := cmdError.Documentation()

switch expr {
case bowerNotFoundErrRegex:
documentation = getBowerNotFoundErrorDocumentation()
case executableNotFoundErrRegex:
documentation = j.GetExecutableNotFoundErrorDocumentation("Bower")
case versionNotFoundErrRegex:
documentation = getVersionNotFoundErrorDocumentation(matches)
documentation = j.getVersionNotFoundErrorDocumentation(matches)
case dependencyNotFoundErrRegex:
documentation = getDependencyNotFoundErrorDocumentation(matches)
documentation = j.getDependencyNotFoundErrorDocumentation(matches)
case registryUnavailableErrRegex:
documentation = getRegistryUnavailableErrorDocumentation(matches)
documentation = j.getRegistryUnavailableErrorDocumentation(matches)
case permissionDeniedErrRegex:
documentation = getPermissionDeniedErrorDocumentation(matches)
documentation = j.getPermissionDeniedErrorDocumentation(matches)
}

cmdError.SetDocumentation(documentation)

return cmdError
}

func getBowerNotFoundErrorDocumentation() string {
return strings.Join(
[]string{
"Bower wasn't found.",
"Please check if it is installed and accessible by the CLI.",
}, " ")
}

func getDependencyNotFoundErrorDocumentation(matches [][]string) string {
func (j *Job) getDependencyNotFoundErrorDocumentation(matches [][]string) string {
dependency := ""
if len(matches) > 0 && len(matches[0]) > 1 {
dependency = matches[0][1]
Expand All @@ -178,7 +170,7 @@ func getDependencyNotFoundErrorDocumentation(matches [][]string) string {
}, " ")
}

func getVersionNotFoundErrorDocumentation(matches [][]string) string {
func (j *Job) getVersionNotFoundErrorDocumentation(matches [][]string) string {
dependency := ""
if len(matches) > 0 && len(matches[0]) > 1 {
dependency = matches[0][1]
Expand All @@ -194,7 +186,7 @@ func getVersionNotFoundErrorDocumentation(matches [][]string) string {
}, " ")
}

func getRegistryUnavailableErrorDocumentation(matches [][]string) string {
func (j *Job) getRegistryUnavailableErrorDocumentation(matches [][]string) string {
registry := ""
if len(matches) > 0 && len(matches[0]) > 1 {
registry = matches[0][1]
Expand All @@ -209,7 +201,7 @@ func getRegistryUnavailableErrorDocumentation(matches [][]string) string {
}, " ")
}

func getPermissionDeniedErrorDocumentation(matches [][]string) string {
func (j *Job) getPermissionDeniedErrorDocumentation(matches [][]string) string {
path := ""
if len(matches) > 0 && len(matches[0]) > 1 {
path = matches[0][1]
Expand Down
8 changes: 6 additions & 2 deletions internal/resolution/pm/composer/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

const (
composer = "composer"
executableNotFoundErrRegex = `executable file not found`
composerMissingExtension = "Composer requires it to run"
invalidRequirement = `require\.([^ ]*) is invalid, it should have a vendor name`
noNetworkRegex = `The following exception probably indicates you( are offline or)? have misconfigured DNS resolver\(s\)`
Expand Down Expand Up @@ -72,6 +73,7 @@ func (j *Job) runInstallCmd() ([]byte, error) {

func (j *Job) handleError(cmdErr job.IError) {
expressions := []string{
executableNotFoundErrRegex,
composerMissingExtension,
invalidRequirement,
noNetworkRegex,
Expand All @@ -84,7 +86,7 @@ func (j *Job) handleError(cmdErr job.IError) {
matches := regex.FindAllStringSubmatch(cmdErr.Error(), -1)

if len(matches) > 0 {
cmdErr = j.addDocumentation(expression, regex, matches, cmdErr)
cmdErr = j.addDocumentation(expression, matches, cmdErr)
j.Errors().Critical(cmdErr)

return
Expand All @@ -94,10 +96,12 @@ func (j *Job) handleError(cmdErr job.IError) {
j.Errors().Critical(cmdErr)
}

func (j *Job) addDocumentation(expr string, regex *regexp.Regexp, matches [][]string, cmdErr job.IError) job.IError {
func (j *Job) addDocumentation(expr string, matches [][]string, cmdErr job.IError) job.IError {
documentation := cmdErr.Documentation()

switch expr {
case executableNotFoundErrRegex:
documentation = j.GetExecutableNotFoundErrorDocumentation("Composer")
case composerMissingExtension:
documentation = j.addComposerMissingRequirementsErrorDocumentation(cmdErr)
case invalidRequirement:
Expand Down
33 changes: 24 additions & 9 deletions internal/resolution/pm/composer/job_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,54 +42,69 @@ func TestInstall(t *testing.T) {

func TestRunInstallCmdErr(t *testing.T) {
cases := []struct {
name string
error string
doc string
}{
{
name: "General error",
error: "cmd-error",
doc: util.UnknownError,
},
{
name: "Composer not found",
error: " |exec: \"composer\": executable file not found in $PATH",
doc: "Composer wasn't found. Please check if it is installed and accessible by the CLI.",
},
{
name: "Phar extension is missing",
error: "\n\n PHP's phar extension is missing. Composer requires it to run. Enable the extension or recompile php without --disable-phar then try again.",
doc: "Failed to build Composer dependency tree. Your runtime environment is missing one or more Composer requirements. Check error message below for more details:\n\n \n\n PHP's phar extension is missing. Composer requires it to run. Enable the extension or recompile php without --disable-phar then try again.",
},
{
name: "Invalid package name",
error: "require.debricked is invalid, it should have a vendor name, a forward slash, and a package name",
doc: "Couldn't resolve dependency debricked , please make sure it is spelt correctly:\n",
},
{
name: "No internet connection 1",
error: "The following exception probably indicates you have misconfigured DNS resolver(s)\n\n[Composer\\Downloader\\TransportException]\ncurl error 6 while downloading https://flex.symfony.com/versions.json: Could not resolve host: flex.symfony.com",
doc: "We weren't able to retrieve one or more dependencies. Please check your Internet connection and try again.",
},
{
name: "No internet connection 2",
error: "The following exception probably indicates you are offline or have misconfigured DNS resolver(s)\n\n[Composer\\Downloader\\TransportException]\ncurl error 6 while downloading https://flex.symfony.com/versions.json: Could not resolve host: flex.symfony.com",
doc: "We weren't able to retrieve one or more dependencies. Please check your Internet connection and try again.",
},
{
name: "Invalid package version",
error: "Root composer.json requires drupal/entity_pager 1.0@RC, found drupal/entity_pager[dev-1.x, dev-2.0.x, 1.0.0-alpha1, ..., 1.x-dev (alias of dev-1.x), 2.0.x-dev (alias of dev-2.0.x)] but it does not match the constraint.",
doc: "Couldn't resolve version drupal/entity_pager 1.0@RC , please make sure it exists:\n",
},
{
name: "Invalid package name",
error: "Loading composer repositories with package information\nUpdating dependencies\nYour requirements could not be resolved to an installable set of packages.\n\n Problem 1\n - Root composer.json requires blablabla/blabla, it could not be found in any version, there may be a typo in the package name.\n\nPotential causes:\n - A typo in the package name\n - The package is not available in a stable-enough version according to your minimum-stability setting\n see <https://getcomposer.org/doc/04-schema.md#minimum-stability> for more details.\n - It's a private package and you forgot to add a custom repository to find it\n\nRead <https://getcomposer.org/doc/articles/troubleshooting.md> for further common problems.\n",
doc: "An error occurred during dependencies resolve for: blablabla/blabla\n\nIf this is a private dependency, please make sure that the debricked CLI has access to install it or pre-install it before running the debricked CLI.\n\n",
},
}

for _, c := range cases {
expectedError := util.NewPMJobError(c.error)
expectedError.SetDocumentation(c.doc)
t.Run(c.name, func(t *testing.T) {
expectedError := util.NewPMJobError(c.error)
expectedError.SetDocumentation(c.doc)

cmdErr := errors.New(c.error)
j := NewJob("file", true, testdata.CmdFactoryMock{InstallCmdName: "echo", MakeInstallErr: cmdErr})
cmdErr := errors.New(c.error)
j := NewJob("file", true, testdata.CmdFactoryMock{InstallCmdName: "echo", MakeInstallErr: cmdErr})

go jobTestdata.WaitStatus(j)
go jobTestdata.WaitStatus(j)

j.Run()
j.Run()

errors := j.Errors().GetAll()
allErrors := j.Errors().GetAll()

assert.Len(t, errors, 1)
assert.Contains(t, errors, expectedError)
assert.Len(t, allErrors, 1)
assert.Contains(t, allErrors, expectedError)
})
}
}

Expand Down
28 changes: 16 additions & 12 deletions internal/resolution/pm/gomod/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

const (
fileName = "gomod.debricked.lock"
executableNotFoundErrRegex = `executable file not found`
versionNotFoundErrRegex = `require ([^"'\s:]+): version "[^"'\s:]+" invalid: ([^"'\n:]+)`
revisionNotFoundErrRegex = `([^"'\s\n:]+): reading [^"'\n:]+ at revision [^"'\n:]+: unknown revision ([^"'\n:]+)`
dependencyNotFoundErrRegex = `go: ([^"'\s:]+): .*\n.*fatal: could not read Username`
Expand Down Expand Up @@ -120,6 +121,7 @@ func (j *Job) createError(error string, cmd string, status string) job.IError {

func (j *Job) handleError(cmdError job.IError) {
expressions := []string{
executableNotFoundErrRegex,
versionNotFoundErrRegex,
revisionNotFoundErrRegex,
dependencyNotFoundErrRegex,
Expand Down Expand Up @@ -148,28 +150,30 @@ func (j *Job) addDocumentation(expr string, matches [][]string, cmdError job.IEr
documentation := cmdError.Documentation()

switch expr {
case executableNotFoundErrRegex:
documentation = j.GetExecutableNotFoundErrorDocumentation("Go")
case versionNotFoundErrRegex:
documentation = getVersionNotFoundErrorDocumentation(matches)
documentation = j.getVersionNotFoundErrorDocumentation(matches)
case revisionNotFoundErrRegex:
documentation = getRevisionNotFoundErrorDocumentation(matches)
documentation = j.getRevisionNotFoundErrorDocumentation(matches)
case dependencyNotFoundErrRegex:
documentation = getDependencyNotFoundErrorDocumentation(matches)
documentation = j.getDependencyNotFoundErrorDocumentation(matches)
case repositoryNotFoundErrRegex:
documentation = getDependencyNotFoundErrorDocumentation(matches)
documentation = j.getDependencyNotFoundErrorDocumentation(matches)
case noPackageErrRegex:
documentation = getNoPackageErrorDocumentation(matches)
documentation = j.getNoPackageErrorDocumentation(matches)
case unableToResolveErrRegex:
documentation = getDependencyNotFoundErrorDocumentation(matches)
documentation = j.getDependencyNotFoundErrorDocumentation(matches)
case noInternetErrRegex:
documentation = getNoInternetErrorDocumentation(matches)
documentation = j.getNoInternetErrorDocumentation(matches)
}

cmdError.SetDocumentation(documentation)

return cmdError
}

func getVersionNotFoundErrorDocumentation(matches [][]string) string {
func (j *Job) getVersionNotFoundErrorDocumentation(matches [][]string) string {
dependency := ""
recommendation := ""
if len(matches) > 0 && len(matches[0]) > 1 {
Expand All @@ -186,7 +190,7 @@ func getVersionNotFoundErrorDocumentation(matches [][]string) string {
}, " ")
}

func getRevisionNotFoundErrorDocumentation(matches [][]string) string {
func (j *Job) getRevisionNotFoundErrorDocumentation(matches [][]string) string {
dependency := ""
revision := ""
if len(matches) > 0 && len(matches[0]) > 1 {
Expand All @@ -202,7 +206,7 @@ func getRevisionNotFoundErrorDocumentation(matches [][]string) string {
}, " ")
}

func getDependencyNotFoundErrorDocumentation(matches [][]string) string {
func (j *Job) getDependencyNotFoundErrorDocumentation(matches [][]string) string {
dependency := ""
if len(matches) > 0 && len(matches[0]) > 1 {
dependency = matches[0][1]
Expand All @@ -218,7 +222,7 @@ func getDependencyNotFoundErrorDocumentation(matches [][]string) string {
}, " ")
}

func getNoPackageErrorDocumentation(matches [][]string) string {
func (j *Job) getNoPackageErrorDocumentation(matches [][]string) string {
repository := ""
if len(matches) > 0 && len(matches[0]) > 1 {
repository = matches[0][1]
Expand All @@ -232,7 +236,7 @@ func getNoPackageErrorDocumentation(matches [][]string) string {
}, " ")
}

func getNoInternetErrorDocumentation(matches [][]string) string {
func (j *Job) getNoInternetErrorDocumentation(matches [][]string) string {
registry := ""
if len(matches) > 0 && len(matches[0]) > 1 {
registry = matches[0][1]
Expand Down
5 changes: 5 additions & 0 deletions internal/resolution/pm/gomod/job_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ func TestRunGraphCmdErr(t *testing.T) {
error: "cmd-error",
doc: util.UnknownError,
},
{
name: "Go not found",
error: " |exec: \"go\": executable file not found in $PATH",
doc: "Go wasn't found. Please check if it is installed and accessible by the CLI.",
},
{
name: "Invalid package version",
error: " |go: errors parsing go.mod:\n |/home/asus/Projects/playground/imessage/go.mod:8:2: require github.com/google/uuid: version \"v111.5.0\" invalid: should be v0 or v1, not v111",
Expand Down
Loading

0 comments on commit 24b0da0

Please sign in to comment.