internal/platform/nuget/nuget.go (122 lines of code) (raw):

/* * Copyright 2021-2024 JetBrains s.r.o. * * 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 * * https://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 nuget import ( "bufio" "fmt" "os" "path/filepath" "regexp" "strings" "github.com/JetBrains/qodana-cli/internal/cloud" "github.com/JetBrains/qodana-cli/internal/platform/product" "github.com/JetBrains/qodana-cli/internal/platform/qdenv" log "github.com/sirupsen/logrus" ) const ( nugetConfigName = "nuget.config" nugetConfigNamePascalCase = "NuGet.Config" ) func UnsetNugetVariables() { variables := []string{qdenv.QodanaNugetUser, qdenv.QodanaNugetPassword, qdenv.QodanaNugetName, qdenv.QodanaNugetUrl} for _, variable := range variables { if err := os.Unsetenv(variable); err != nil { log.Fatal("couldn't unset env variable ", err.Error()) } } } func isNonNativeDotnetLinter(analyser product.Analyzer) bool { return analyser.IsContainer() && (analyser.GetLinter() == product.DotNetLinter || analyser.GetLinter() == product.DotNetCommunityLinter) } func WarnIfPrivateFeedDetected(analyzer product.Analyzer, projectPath string) { if !isNonNativeDotnetLinter(analyzer) { return } configFileNames := []string{nugetConfigName, nugetConfigNamePascalCase} for _, fileName := range configFileNames { if _, err := os.Stat(filepath.Join(projectPath, fileName)); err == nil { nugetPath := filepath.Join(projectPath, fileName) if checkForPrivateFeed(nugetPath) { _, _ = fmt.Fprintf( os.Stderr, "\nWarning: private NuGet feed detected (%s). Please set %s, %s, %s and %s (optional) environment variables to provide credentials for the private feed.\n", nugetPath, qdenv.QodanaNugetUser, qdenv.QodanaNugetPassword, qdenv.QodanaNugetUrl, qdenv.QodanaNugetName, ) return } } } } func checkForPrivateFeed(fileName string) bool { file, err := os.Open(fileName) if err != nil { fmt.Println("Failed to open file:", fileName) return false } defer func(file *os.File) { err := file.Close() if err != nil { log.Error("couldn't close file ", err.Error()) } }(file) scanner := bufio.NewScanner(file) for scanner.Scan() { line := scanner.Text() if strings.Contains(line, "<add ") { match, _ := regexp.MatchString(`http(s)?://`, line) return match } } return false } func IsNugetConfigNeeded() bool { return qdenv.IsContainer() && qodanaNugetVarsSet() } func qodanaNugetVarsSet() bool { return os.Getenv(qdenv.QodanaNugetUrl) != "" && os.Getenv(qdenv.QodanaNugetUser) != "" && os.Getenv(qdenv.QodanaNugetPassword) != "" } func PrepareNugetConfig(userPath string) { nugetConfig := filepath.Join(userPath, ".nuget", "NuGet") if _, err := os.Stat(nugetConfig); err != nil { // mkdir -p ~/.nuget/NuGet if err := os.MkdirAll(nugetConfig, os.ModePerm); err != nil { log.Fatal("couldn't create a directory ", err.Error()) } } nugetConfig = filepath.Join(nugetConfig, "NuGet.Config") config := nugetWithPrivateFeed( cloud.GetEnvWithDefault(qdenv.QodanaNugetName, "qodana"), os.Getenv(qdenv.QodanaNugetUrl), os.Getenv(qdenv.QodanaNugetUser), os.Getenv(qdenv.QodanaNugetPassword), ) if err := os.WriteFile(nugetConfig, []byte(config), 0644); err != nil { log.Fatal("couldn't create a file ", err.Error()) } } func nugetWithPrivateFeed(nugetSourceName string, nugetUrl string, nugetUser string, nugetPassword string) string { return fmt.Sprintf( `<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <clear /> <add key="nuget.org" value="https://api.nuget.org/v3/index.json" /> <add key="%s" value="%s" /> </packageSources> <packageSourceCredentials> <%s> <add key="Username" value="%s" /> <add key="ClearTextPassword" value="%s" /> </%s> </packageSourceCredentials> </configuration>`, nugetSourceName, nugetUrl, nugetSourceName, nugetUser, nugetPassword, nugetSourceName, ) }