Skip to content

Commit 9b6cc83

Browse files
authored
Feat/cf 2275 analyze api (#199)
* feat: Fix for already existing config CF-2275 If config does not exist in .codacy/tools-configs it will first check if the root of the project contains any configurations. * feat: Small fix, added tests CF-2275
1 parent 6351f2f commit 9b6cc83

File tree

2 files changed

+111
-48
lines changed

2 files changed

+111
-48
lines changed

cmd/analyze.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,10 +272,10 @@ var versionedToolNames = map[string]map[int]string{
272272
}
273273

274274
var simpleToolAliases = map[string]string{
275-
"lizard": "Lizard",
275+
"lizard": "Lizard",
276276
"opengrep": "Opengrep",
277-
"pylint": "pylintpython3",
278-
"trivy": "Trivy",
277+
"pylint": "pylintpython3",
278+
"trivy": "Trivy",
279279
}
280280

281281
func getToolName(toolName string, version string) string {
@@ -328,8 +328,15 @@ func checkIfConfigExistsAndIsNeeded(toolName string, cliLocalMode bool) error {
328328

329329
// Check if the config file exists
330330
if _, err := os.Stat(toolConfigPath); os.IsNotExist(err) {
331-
// Config file does not exist - create it if we have the means to do so
332-
if (!cliLocalMode && initFlags.ApiToken != "") || cliLocalMode {
331+
repoConfigPath := filepath.Join(config.Config.RepositoryDirectory(), configFileName)
332+
if _, repoErr := os.Stat(repoConfigPath); repoErr == nil {
333+
// Config not in .codacy/tools-configs/ - check if it exists in the repo root
334+
logger.Info("Config file found in repository root for tool, skipping config creation", logrus.Fields{
335+
"tool": toolName,
336+
"toolConfigPath": repoConfigPath,
337+
})
338+
return nil
339+
} else if (!cliLocalMode && initFlags.ApiToken != "") || cliLocalMode {
333340
if err := configsetup.CreateToolConfigurationFile(toolName, initFlags); err != nil {
334341
return fmt.Errorf("failed to create config file for tool %s: %w", toolName, err)
335342
}

cmd/analyze_test.go

Lines changed: 99 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -332,49 +332,81 @@ func TestCheckIfConfigExistsAndIsNeeded(t *testing.T) {
332332
}()
333333

334334
tests := []struct {
335-
name string
336-
toolName string
337-
cliLocalMode bool
338-
apiToken string
339-
configFileExists bool
340-
expectError bool
341-
description string
335+
name string
336+
toolName string
337+
cliLocalMode bool
338+
apiToken string
339+
configFileExists bool
340+
repoRootConfigExists bool
341+
expectError bool
342+
expectConfigCreatedInToolsDir bool
343+
description string
342344
}{
343345
{
344-
name: "tool_without_config_file",
345-
toolName: "unsupported-tool",
346-
cliLocalMode: false,
347-
apiToken: "test-token",
348-
configFileExists: false,
349-
expectError: false,
350-
description: "Tool that doesn't use config files should return without error",
346+
name: "tool_without_config_file",
347+
toolName: "unsupported-tool",
348+
cliLocalMode: false,
349+
apiToken: "test-token",
350+
configFileExists: false,
351+
repoRootConfigExists: false,
352+
expectError: false,
353+
expectConfigCreatedInToolsDir: false,
354+
description: "Tool that doesn't use config files should return without error",
351355
},
352356
{
353-
name: "config_file_exists",
354-
toolName: "eslint",
355-
cliLocalMode: false,
356-
apiToken: "test-token",
357-
configFileExists: true,
358-
expectError: false,
359-
description: "When config file exists, should find it successfully",
357+
name: "config_file_exists_in_tools_dir",
358+
toolName: "eslint",
359+
cliLocalMode: false,
360+
apiToken: "test-token",
361+
configFileExists: true,
362+
repoRootConfigExists: false,
363+
expectError: false,
364+
expectConfigCreatedInToolsDir: true,
365+
description: "When config file exists in tools-configs, should find it successfully",
360366
},
361367
{
362-
name: "remote_mode_without_token_no_config",
363-
toolName: "eslint",
364-
cliLocalMode: false,
365-
apiToken: "",
366-
configFileExists: false,
367-
expectError: false,
368-
description: "Remote mode without token should show appropriate message",
368+
name: "remote_mode_without_token_no_config",
369+
toolName: "eslint",
370+
cliLocalMode: false,
371+
apiToken: "",
372+
configFileExists: false,
373+
repoRootConfigExists: false,
374+
expectError: false,
375+
expectConfigCreatedInToolsDir: false,
376+
description: "Remote mode without token and no config anywhere should not create defaults",
369377
},
370378
{
371-
name: "local_mode_no_config",
372-
toolName: "eslint",
373-
cliLocalMode: true,
374-
apiToken: "",
375-
configFileExists: false,
376-
expectError: false,
377-
description: "Local mode should create config file if tools-configs directory exists",
379+
name: "local_mode_no_config",
380+
toolName: "eslint",
381+
cliLocalMode: true,
382+
apiToken: "",
383+
configFileExists: false,
384+
repoRootConfigExists: false,
385+
expectError: false,
386+
expectConfigCreatedInToolsDir: true,
387+
description: "Local mode with no config anywhere should create a default config in tools-configs",
388+
},
389+
{
390+
name: "local_mode_config_exists_in_repo_root",
391+
toolName: "eslint",
392+
cliLocalMode: true,
393+
apiToken: "",
394+
configFileExists: false,
395+
repoRootConfigExists: true,
396+
expectError: false,
397+
expectConfigCreatedInToolsDir: false,
398+
description: "Local mode should not create default config when user's own config exists in repo root",
399+
},
400+
{
401+
name: "remote_mode_with_token_config_exists_in_repo_root",
402+
toolName: "eslint",
403+
cliLocalMode: false,
404+
apiToken: "test-token",
405+
configFileExists: false,
406+
repoRootConfigExists: true,
407+
expectError: false,
408+
expectConfigCreatedInToolsDir: false,
409+
description: "Remote mode should not create default config when user's own config exists in repo root",
378410
},
379411
}
380412

@@ -392,7 +424,7 @@ func TestCheckIfConfigExistsAndIsNeeded(t *testing.T) {
392424
// Mock config to use our temporary directory BEFORE creating files
393425
config.Config = *config.NewConfigType(tmpDir, tmpDir, tmpDir)
394426

395-
// Create config file if needed - using the same path logic as the function under test
427+
// Create config file in tools-configs if needed
396428
if tt.configFileExists && constants.ToolConfigFileNames[tt.toolName] != "" {
397429
// Use config.Config.ToolsConfigDirectory() to get the exact same path the function will use
398430
toolsConfigDir := config.Config.ToolsConfigDirectory()
@@ -408,6 +440,13 @@ func TestCheckIfConfigExistsAndIsNeeded(t *testing.T) {
408440
require.NoError(t, err, "Config file should exist at %s", configPath)
409441
}
410442

443+
// Create config file in repo root if needed
444+
if tt.repoRootConfigExists && constants.ToolConfigFileNames[tt.toolName] != "" {
445+
repoRootConfigPath := filepath.Join(config.Config.RepositoryDirectory(), constants.ToolConfigFileNames[tt.toolName])
446+
err = os.WriteFile(repoRootConfigPath, []byte("user's own config"), constants.DefaultFilePerms)
447+
require.NoError(t, err)
448+
}
449+
411450
// Setup initFlags
412451
initFlags = domain.InitFlags{
413452
ApiToken: tt.apiToken,
@@ -423,6 +462,30 @@ func TestCheckIfConfigExistsAndIsNeeded(t *testing.T) {
423462
// Execute the function
424463
err = checkIfConfigExistsAndIsNeeded(tt.toolName, tt.cliLocalMode)
425464

465+
// Verify results
466+
if tt.expectError {
467+
assert.Error(t, err, tt.description)
468+
} else {
469+
assert.NoError(t, err, tt.description)
470+
}
471+
// Verify whether a config was created in .codacy/tools-configs/
472+
if constants.ToolConfigFileNames[tt.toolName] != "" {
473+
toolsConfigDir := config.Config.ToolsConfigDirectory()
474+
generatedConfigPath := filepath.Join(toolsConfigDir, constants.ToolConfigFileNames[tt.toolName])
475+
_, statErr := os.Stat(generatedConfigPath)
476+
configCreated := statErr == nil
477+
478+
if tt.expectConfigCreatedInToolsDir {
479+
assert.True(t, configCreated,
480+
"%s: expected a config file to exist in tools-configs at %s",
481+
tt.description, generatedConfigPath)
482+
} else {
483+
assert.True(t, os.IsNotExist(statErr),
484+
"%s: expected NO config file to be created in tools-configs, but found one at %s",
485+
tt.description, generatedConfigPath)
486+
}
487+
}
488+
426489
// Clean up any files that might have been created by the function under test
427490
if !tt.configFileExists && constants.ToolConfigFileNames[tt.toolName] != "" {
428491
toolsConfigDir := config.Config.ToolsConfigDirectory()
@@ -431,13 +494,6 @@ func TestCheckIfConfigExistsAndIsNeeded(t *testing.T) {
431494
os.Remove(configPath)
432495
}
433496
}
434-
435-
// Verify results
436-
if tt.expectError {
437-
assert.Error(t, err, tt.description)
438-
} else {
439-
assert.NoError(t, err, tt.description)
440-
}
441497
})
442498
}
443499
}

0 commit comments

Comments
 (0)