Skip to content

Commit 5ab3246

Browse files
refactor to use codacyclient to make all api requests
1 parent a95a19d commit 5ab3246

File tree

9 files changed

+155
-255
lines changed

9 files changed

+155
-255
lines changed

cmd/init.go

Lines changed: 12 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,15 @@ import (
88
"codacy/cli-v2/tools/lizard"
99
"codacy/cli-v2/tools/pylint"
1010
"codacy/cli-v2/utils"
11-
"encoding/json"
12-
"errors"
1311
"fmt"
14-
"io"
1512
"log"
16-
"net/http"
1713
"os"
1814
"path/filepath"
1915
"strings"
20-
"time"
2116

2217
"github.com/spf13/cobra"
2318
)
2419

25-
const CodacyApiBase = "https://app.codacy.com"
26-
2720
var initFlags domain.InitFlags
2821

2922
func init() {
@@ -55,7 +48,7 @@ var initCmd = &cobra.Command{
5548
if cliLocalMode {
5649
fmt.Println()
5750
fmt.Println("ℹ️ No project token was specified, fetching codacy default configurations")
58-
noTools := []tools.Tool{}
51+
noTools := []domain.Tool{}
5952
err := createConfigurationFiles(noTools, cliLocalMode)
6053
if err != nil {
6154
log.Fatal(err)
@@ -97,7 +90,7 @@ func createGitIgnoreFile() error {
9790
return nil
9891
}
9992

100-
func createConfigurationFiles(tools []tools.Tool, cliLocalMode bool) error {
93+
func createConfigurationFiles(tools []domain.Tool, cliLocalMode bool) error {
10194
configFile, err := os.Create(config.Config.ProjectConfigFile())
10295
if err != nil {
10396
return fmt.Errorf("failed to create project config file: %w", err)
@@ -125,7 +118,7 @@ func createConfigurationFiles(tools []tools.Tool, cliLocalMode bool) error {
125118
return nil
126119
}
127120

128-
func configFileTemplate(tools []tools.Tool) string {
121+
func configFileTemplate(tools []domain.Tool) string {
129122
// Maps to track which tools are enabled
130123
toolsMap := make(map[string]bool)
131124
toolVersions := make(map[string]string)
@@ -255,11 +248,7 @@ func buildRepositoryConfigurationFiles(token string) error {
255248
return fmt.Errorf("failed to clean configuration directory: %w", err)
256249
}
257250

258-
client := &http.Client{
259-
Timeout: 10 * time.Second,
260-
}
261-
262-
apiTools, err := tools.GetRepositoryTools(CodacyApiBase, token, initFlags.Provider, initFlags.Organization, initFlags.Repository)
251+
apiTools, err := tools.GetRepositoryTools(initFlags)
263252
if err != nil {
264253
return err
265254
}
@@ -276,7 +265,7 @@ func buildRepositoryConfigurationFiles(token string) error {
276265
}
277266

278267
// Generate languages configuration based on API tools response
279-
if err := tools.CreateLanguagesConfigFile(apiTools, toolsConfigDir, uuidToName, token, initFlags.Provider, initFlags.Organization, initFlags.Repository); err != nil {
268+
if err := tools.CreateLanguagesConfigFile(apiTools, toolsConfigDir, uuidToName, initFlags); err != nil {
280269
return fmt.Errorf("failed to create languages configuration file: %w", err)
281270
}
282271

@@ -292,52 +281,7 @@ func buildRepositoryConfigurationFiles(token string) error {
292281
// Only generate config files for tools not using their own config file
293282
for _, tool := range configuredToolsWithUI {
294283

295-
url := fmt.Sprintf("%s/api/v3/analysis/organizations/%s/%s/repositories/%s/tools/%s/patterns?enabled=true&limit=1000",
296-
CodacyApiBase,
297-
initFlags.Provider,
298-
initFlags.Organization,
299-
initFlags.Repository,
300-
tool.Uuid)
301-
302-
// Create a new GET request
303-
req, err := http.NewRequest("GET", url, nil)
304-
if err != nil {
305-
fmt.Println("Error:", err)
306-
return err
307-
}
308-
309-
// Set the headers
310-
req.Header.Set("api-token", token)
311-
312-
// Send the request
313-
resp, err := client.Do(req)
314-
if err != nil {
315-
fmt.Println("Error:", err)
316-
return err
317-
}
318-
defer resp.Body.Close()
319-
320-
if resp.StatusCode >= 400 {
321-
return errors.New("failed to get repository's configuration from Codacy API")
322-
}
323-
324-
// Read the response body
325-
body, err := io.ReadAll(resp.Body)
326-
if err != nil {
327-
fmt.Println("Error:", err)
328-
return err
329-
}
330-
331-
var objmap map[string]json.RawMessage
332-
err = json.Unmarshal(body, &objmap)
333-
334-
if err != nil {
335-
fmt.Println("Error unmarshaling response:", err)
336-
return err
337-
}
338-
339-
var apiToolConfigurations []domain.PatternConfiguration
340-
err = json.Unmarshal(objmap["data"], &apiToolConfigurations)
284+
apiToolConfigurations, err := codacyclient.GetRepositoryToolPatterns(initFlags, tool.Uuid)
341285

342286
if err != nil {
343287
fmt.Println("Error unmarshaling tool configurations:", err)
@@ -351,7 +295,7 @@ func buildRepositoryConfigurationFiles(token string) error {
351295
}
352296

353297
// map tool uuid to tool name
354-
func createToolFileConfigurations(tool tools.Tool, patternConfiguration []domain.PatternConfiguration) error {
298+
func createToolFileConfigurations(tool domain.Tool, patternConfiguration []domain.PatternConfiguration) error {
355299
toolsConfigDir := config.Config.ToolsConfigDirectory()
356300
switch tool.Uuid {
357301
case ESLint:
@@ -544,17 +488,19 @@ func createLizardConfigFile(toolsConfigDir string, patternConfiguration []domain
544488
var patterns []domain.PatternDefinition
545489

546490
if len(patternConfiguration) == 0 {
547-
var err error
548-
patterns, err = tools.FetchDefaultEnabledPatterns(Lizard)
491+
patternsConfig, err := codacyclient.GetDefaultToolPatternsConfig(initFlags, Lizard)
549492
if err != nil {
550493
return err
551494
}
495+
patterns = make([]domain.PatternDefinition, len(patternsConfig))
496+
for i, pattern := range patternsConfig {
497+
patterns[i] = pattern.PatternDefinition
498+
}
552499
} else {
553500
patterns = make([]domain.PatternDefinition, len(patternConfiguration))
554501
for i, pattern := range patternConfiguration {
555502
patterns[i] = pattern.PatternDefinition
556503
}
557-
558504
}
559505

560506
content, err := lizard.CreateLizardConfig(patterns)

cmd/init_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package cmd
22

33
import (
44
"codacy/cli-v2/config"
5-
"codacy/cli-v2/tools"
5+
"codacy/cli-v2/domain"
66
"codacy/cli-v2/utils"
77
"os"
88
"path/filepath"
@@ -14,13 +14,13 @@ import (
1414
func TestConfigFileTemplate(t *testing.T) {
1515
tests := []struct {
1616
name string
17-
tools []tools.Tool
17+
tools []domain.Tool
1818
expected []string
1919
notExpected []string
2020
}{
2121
{
2222
name: "empty tools list uses defaults",
23-
tools: []tools.Tool{},
23+
tools: []domain.Tool{},
2424
expected: []string{
2525
2626
@@ -33,7 +33,7 @@ func TestConfigFileTemplate(t *testing.T) {
3333
},
3434
{
3535
name: "only eslint enabled",
36-
tools: []tools.Tool{
36+
tools: []domain.Tool{
3737
{
3838
Uuid: ESLint,
3939
Name: "eslint",
@@ -53,7 +53,7 @@ func TestConfigFileTemplate(t *testing.T) {
5353
},
5454
{
5555
name: "only pylint enabled",
56-
tools: []tools.Tool{
56+
tools: []domain.Tool{
5757
{
5858
Uuid: PyLint,
5959
Name: "pylint",
@@ -73,7 +73,7 @@ func TestConfigFileTemplate(t *testing.T) {
7373
},
7474
{
7575
name: "eslint and trivy enabled",
76-
tools: []tools.Tool{
76+
tools: []domain.Tool{
7777
{
7878
Uuid: ESLint,
7979
Name: "eslint",
@@ -98,7 +98,7 @@ func TestConfigFileTemplate(t *testing.T) {
9898
},
9999
{
100100
name: "all tools enabled",
101-
tools: []tools.Tool{
101+
tools: []domain.Tool{
102102
{
103103
Uuid: ESLint,
104104
Name: "eslint",
@@ -216,7 +216,7 @@ func TestInitCommand_NoToken(t *testing.T) {
216216

217217
cliLocalMode := len(initFlags.ApiToken) == 0
218218
if cliLocalMode {
219-
noTools := []tools.Tool{}
219+
noTools := []domain.Tool{}
220220
err := createConfigurationFiles(noTools, cliLocalMode)
221221
assert.NoError(t, err, "createConfigurationFiles should not return an error")
222222
if err := buildDefaultConfigurationFiles(toolsConfigDir); err != nil {

codacy-client/client.go

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
const timeout = 10 * time.Second
1414
const CodacyApiBase = "https://app.codacy.com"
1515

16-
func getRequest(url string, initFlags domain.InitFlags) ([]byte, error) {
16+
func getRequest(url string, apiToken string) ([]byte, error) {
1717
client := &http.Client{
1818
Timeout: timeout,
1919
}
@@ -23,7 +23,9 @@ func getRequest(url string, initFlags domain.InitFlags) ([]byte, error) {
2323
return nil, fmt.Errorf("failed to create request: %w", err)
2424
}
2525

26-
req.Header.Set("api-token", initFlags.ApiToken)
26+
if apiToken != "" {
27+
req.Header.Set("api-token", apiToken)
28+
}
2729

2830
resp, err := client.Do(req)
2931

@@ -52,7 +54,7 @@ func GetPage[T any](
5254
initFlags domain.InitFlags,
5355
parser func([]byte) ([]T, string, error),
5456
) ([]T, string, error) {
55-
response, err := getRequest(url, initFlags)
57+
response, err := getRequest(url, initFlags.ApiToken)
5658
if err != nil {
5759
return nil, "", fmt.Errorf("failed to get page: %w", err)
5860
}
@@ -148,3 +150,64 @@ func GetRepositoryToolPatterns(initFlags domain.InitFlags, toolUUID string) ([]d
148150
toolUUID)
149151
return getAllPages(baseURL, initFlags, parsePatternConfigurations)
150152
}
153+
154+
func GetRepositoryTools(initFlags domain.InitFlags) ([]domain.Tool, error) {
155+
baseURL := fmt.Sprintf("%s/api/v3/analysis/organizations/%s/%s/repositories/%s/tools",
156+
CodacyApiBase,
157+
initFlags.Provider,
158+
initFlags.Organization,
159+
initFlags.Repository)
160+
161+
bodyResponse, err := getRequest(baseURL, initFlags.ApiToken)
162+
if err != nil {
163+
return nil, fmt.Errorf("failed to get repository tools: %w", err)
164+
}
165+
166+
var toolsResponse domain.ToolsResponse
167+
168+
err = json.Unmarshal(bodyResponse, &toolsResponse)
169+
if err != nil {
170+
fmt.Println("Error unmarshaling response:", err)
171+
return nil, err
172+
}
173+
174+
return toolsResponse.Data, nil
175+
}
176+
177+
func GetToolsVersions() ([]domain.Tool, error) {
178+
baseURL := fmt.Sprintf("%s/api/v3/tools", CodacyApiBase)
179+
180+
bodyResponse, err := getRequest(baseURL, "")
181+
if err != nil {
182+
return nil, fmt.Errorf("failed to get tool versions: %w", err)
183+
}
184+
185+
var toolsResponse domain.ToolsResponse
186+
err = json.Unmarshal(bodyResponse, &toolsResponse)
187+
if err != nil {
188+
return nil, fmt.Errorf("failed to unmarshal response: %w", err)
189+
}
190+
191+
return toolsResponse.Data, nil
192+
}
193+
194+
func GetRepositoryLanguages(initFlags domain.InitFlags) ([]domain.Language, error) {
195+
baseURL := fmt.Sprintf("%s/api/v3/analysis/organizations/%s/%s/repositories/%s/settings/languages",
196+
CodacyApiBase,
197+
initFlags.Provider,
198+
initFlags.Organization,
199+
initFlags.Repository)
200+
201+
bodyResponse, err := getRequest(baseURL, initFlags.ApiToken)
202+
if err != nil {
203+
return nil, fmt.Errorf("failed to get repository languages: %w", err)
204+
}
205+
206+
var languagesResponse domain.LanguagesResponse
207+
err = json.Unmarshal(bodyResponse, &languagesResponse)
208+
if err != nil {
209+
return nil, fmt.Errorf("failed to unmarshal response: %w", err)
210+
}
211+
212+
return languagesResponse.Languages, nil
213+
}

codacy-client/client_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func TestGetRequest_Success(t *testing.T) {
1919
defer ts.Close()
2020

2121
initFlags := domain.InitFlags{ApiToken: "dummy"}
22-
resp, err := getRequest(ts.URL, initFlags)
22+
resp, err := getRequest(ts.URL, initFlags.ApiToken)
2323
assert.NoError(t, err)
2424
assert.Contains(t, string(resp), "ok")
2525
}
@@ -31,7 +31,7 @@ func TestGetRequest_Failure(t *testing.T) {
3131
defer ts.Close()
3232

3333
initFlags := domain.InitFlags{ApiToken: "dummy"}
34-
_, err := getRequest(ts.URL, initFlags)
34+
_, err := getRequest(ts.URL, initFlags.ApiToken)
3535
assert.Error(t, err)
3636
}
3737

domain/language.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package domain
2+
3+
type Language struct {
4+
Name string `json:"name"`
5+
CodacyDefaults []string `json:"codacyDefaults"`
6+
Extensions []string `json:"extensions"`
7+
Enabled bool `json:"enabled"`
8+
Detected bool `json:"detected"`
9+
}
10+
11+
type LanguagesResponse struct {
12+
Languages []Language `json:"languages"`
13+
}
14+
15+
// ToolLanguageInfo contains language and extension information for a tool
16+
type ToolLanguageInfo struct {
17+
Name string `yaml:"name"`
18+
Languages []string `yaml:"languages,flow"`
19+
Extensions []string `yaml:"extensions,flow"`
20+
}
21+
22+
// LanguagesConfig represents the structure of the languages configuration file
23+
type LanguagesConfig struct {
24+
Tools []ToolLanguageInfo `yaml:"tools"`
25+
}

domain/tool.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package domain
2+
3+
type ToolsResponse struct {
4+
Data []Tool `json:"data"`
5+
}
6+
7+
type Tool struct {
8+
Uuid string `json:"uuid"`
9+
Name string `json:"name"`
10+
Version string `json:"version"`
11+
Settings struct {
12+
Enabled bool `json:"isEnabled"`
13+
HasConfigurationFile bool `json:"hasConfigurationFile"`
14+
UsesConfigurationFile bool `json:"usesConfigurationFile"`
15+
} `json:"settings"`
16+
}

0 commit comments

Comments
 (0)