github.com/jfrog/jfrog-cli-core/v2@v2.51.0/common/project/projectconfig.go (about) 1 package project 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "path/filepath" 8 "reflect" 9 10 "github.com/jfrog/jfrog-cli-core/v2/utils/config" 11 "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" 12 "github.com/jfrog/jfrog-client-go/utils/errorutils" 13 "github.com/jfrog/jfrog-client-go/utils/io/fileutils" 14 "github.com/jfrog/jfrog-client-go/utils/log" 15 "github.com/spf13/viper" 16 ) 17 18 const ( 19 ProjectConfigResolverPrefix = "resolver" 20 ProjectConfigDeployerPrefix = "deployer" 21 ProjectConfigRepo = "repo" 22 ProjectConfigReleaseRepo = "releaseRepo" 23 ProjectConfigServerId = "serverId" 24 ) 25 26 type ProjectType int 27 28 const ( 29 Go ProjectType = iota 30 Pip 31 Pipenv 32 Poetry 33 Npm 34 Pnpm 35 Yarn 36 Nuget 37 Maven 38 Gradle 39 Dotnet 40 Build 41 Terraform 42 ) 43 44 type ConfigType string 45 46 const ( 47 YAML ConfigType = "yaml" 48 PROPERTIES ConfigType = "properties" 49 ) 50 51 var ProjectTypes = []string{ 52 "go", 53 "pip", 54 "pipenv", 55 "poetry", 56 "npm", 57 "pnpm", 58 "yarn", 59 "nuget", 60 "maven", 61 "gradle", 62 "dotnet", 63 "build", 64 "terraform", 65 } 66 67 func (projectType ProjectType) String() string { 68 return ProjectTypes[projectType] 69 } 70 71 type MissingResolverErr struct { 72 message string 73 } 74 75 func (mre *MissingResolverErr) Error() string { 76 return mre.message 77 } 78 79 type Repository struct { 80 Repo string `yaml:"repo,omitempty"` 81 ServerId string `yaml:"serverId,omitempty"` 82 SnapshotRepo string `yaml:"snapshotRepo,omitempty"` 83 ReleaseRepo string `yaml:"releaseRepo,omitempty"` 84 DeployMavenDesc bool `yaml:"deployMavenDescriptors,omitempty"` 85 DeployIvyDesc bool `yaml:"deployIvyDescriptors,omitempty"` 86 IvyPattern string `yaml:"ivyPattern,omitempty"` 87 ArtifactsPattern string `yaml:"artifactPattern,omitempty"` 88 NugetV2 bool `yaml:"nugetV2,omitempty"` 89 IncludePatterns string `yaml:"includePatterns,omitempty"` 90 ExcludePatterns string `yaml:"excludePatterns,omitempty"` 91 } 92 93 type RepositoryConfig struct { 94 targetRepo string 95 serverDetails *config.ServerDetails 96 } 97 98 // If configuration file exists in the working dir or in one of its parent dirs return its path, 99 // otherwise return the global configuration file path 100 func GetProjectConfFilePath(projectType ProjectType) (confFilePath string, exists bool, err error) { 101 confFileName := filepath.Join("projects", projectType.String()+".yaml") 102 projectDir, exists, err := fileutils.FindUpstream(".jfrog", fileutils.Dir) 103 if err != nil { 104 return 105 } 106 if exists { 107 filePath := filepath.Join(projectDir, ".jfrog", confFileName) 108 exists, err = fileutils.IsFileExists(filePath, false) 109 if err != nil { 110 return 111 } 112 113 if exists { 114 confFilePath = filePath 115 return 116 } 117 } 118 // If missing in the root project, check in the home dir 119 jfrogHomeDir, err := coreutils.GetJfrogHomeDir() 120 if err != nil { 121 return 122 } 123 filePath := filepath.Join(jfrogHomeDir, confFileName) 124 exists, err = fileutils.IsFileExists(filePath, false) 125 if exists { 126 confFilePath = filePath 127 } 128 return 129 } 130 131 func GetRepoConfigByPrefix(configFilePath, prefix string, vConfig *viper.Viper) (repoConfig *RepositoryConfig, err error) { 132 defer func() { 133 if err != nil { 134 err = errors.Join(err, fmt.Errorf("please run 'jf %s-config' with your %s repository information", vConfig.GetString("type"), prefix)) 135 } 136 }() 137 if !vConfig.IsSet(prefix) { 138 err = &MissingResolverErr{fmt.Sprintf("the %s repository is missing from the config file (%s)", prefix, configFilePath)} 139 return 140 } 141 log.Debug(fmt.Sprintf("Found %s in the config file %s", prefix, configFilePath)) 142 repo := vConfig.GetString(prefix + "." + ProjectConfigRepo) 143 if repo == "" { 144 // In the maven.yaml config, there's a resolver repository field named "releaseRepo" 145 if repo = vConfig.GetString(prefix + "." + ProjectConfigReleaseRepo); repo == "" { 146 err = errorutils.CheckErrorf("missing repository for %s within %s", prefix, configFilePath) 147 return 148 } 149 } 150 serverId := vConfig.GetString(prefix + "." + ProjectConfigServerId) 151 if serverId == "" { 152 err = errorutils.CheckErrorf("missing server ID for %s within %s", prefix, configFilePath) 153 return 154 } 155 rtDetails, err := config.GetSpecificConfig(serverId, false, true) 156 if err != nil { 157 return 158 } 159 repoConfig = &RepositoryConfig{targetRepo: repo, serverDetails: rtDetails} 160 return 161 } 162 163 func (repo *RepositoryConfig) IsServerDetailsEmpty() bool { 164 if repo.serverDetails != nil && reflect.DeepEqual(config.ServerDetails{}, repo.serverDetails) { 165 return false 166 } 167 return true 168 } 169 170 func (repo *RepositoryConfig) SetTargetRepo(targetRepo string) *RepositoryConfig { 171 repo.targetRepo = targetRepo 172 return repo 173 } 174 175 func (repo *RepositoryConfig) TargetRepo() string { 176 return repo.targetRepo 177 } 178 179 func (repo *RepositoryConfig) SetServerDetails(rtDetails *config.ServerDetails) *RepositoryConfig { 180 repo.serverDetails = rtDetails 181 return repo 182 } 183 184 func (repo *RepositoryConfig) ServerDetails() (*config.ServerDetails, error) { 185 return repo.serverDetails, nil 186 } 187 188 func GetResolutionOnlyConfiguration(projectType ProjectType) (*RepositoryConfig, error) { 189 // Get configuration file path. 190 confFilePath, exists, err := GetProjectConfFilePath(projectType) 191 if err != nil { 192 return nil, err 193 } 194 if !exists { 195 return nil, errorutils.CheckErrorf(projectType.String() + " Project configuration does not exist.") 196 } 197 return ReadResolutionOnlyConfiguration(confFilePath) 198 } 199 200 func ReadConfigFile(configPath string, configType ConfigType) (config *viper.Viper, err error) { 201 config = viper.New() 202 config.SetConfigType(string(configType)) 203 204 f, err := os.Open(configPath) 205 if err != nil { 206 return config, errorutils.CheckError(err) 207 } 208 defer func() { 209 err = errorutils.CheckError(f.Close()) 210 }() 211 err = config.ReadConfig(f) 212 return config, errorutils.CheckError(err) 213 } 214 215 func ReadResolutionOnlyConfiguration(confFilePath string) (*RepositoryConfig, error) { 216 log.Debug("Preparing to read the config file", confFilePath) 217 vConfig, err := ReadConfigFile(confFilePath, YAML) 218 if err != nil { 219 return nil, err 220 } 221 return GetRepoConfigByPrefix(confFilePath, ProjectConfigResolverPrefix, vConfig) 222 }