diff --git a/main.go b/main.go index 138be2a..3fb992c 100644 --- a/main.go +++ b/main.go @@ -265,6 +265,17 @@ func main() { podfilePath = absPodfilePath } + isUsingSpecsRepo, err := isPodfileUsingSpecsRepo(podfilePath) + if err != nil { + log.Warnf("Failed to determine if Podfile is using Specs repo, error: %s", err) + } else { + tracker.Enqueue("step_cocoapods_install_podfile_used", analytics.Properties{ + "step_execution_id": envRepository.Get("BITRISE_STEP_EXECUTION_ID"), + "build_slug": envRepository.Get("BITRISE_BUILD_SLUG"), + "is_using_specs_repo": isUsingSpecsRepo, + }) + } + podfileDir := filepath.Dir(podfilePath) // diff --git a/podfile.go b/podfile.go new file mode 100644 index 0000000..93a41aa --- /dev/null +++ b/podfile.go @@ -0,0 +1,35 @@ +package main + +import ( + "bufio" + "os" + "strings" +) + +// isPodfileUsingSpecsRepo returns true if the Podfile contains a source 'https://github.com/CocoaPods/Specs.git'. +// It returns false if the CDN source or any other 3rd party git source is used. +func isPodfileUsingSpecsRepo(path string) (bool, error) { + file, err := os.Open(path) + if err != nil { + return false, err + } + defer file.Close() + + specsRepoDefined := false + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + cleanLine := strings.ReplaceAll(line, "\"", "'") + cleanLine = strings.ToLower(cleanLine) + if cleanLine == "source 'https://github.com/cocoapods/specs.git'" { + specsRepoDefined = true + break + } + } + + if err := scanner.Err(); err != nil { + return false, err + } + + return specsRepoDefined, nil +} diff --git a/podfile_test.go b/podfile_test.go new file mode 100644 index 0000000..cade475 --- /dev/null +++ b/podfile_test.go @@ -0,0 +1,122 @@ +package main + +import ( + "os" + "path/filepath" + "testing" +) + +func TestIsPodfileUsingSpecsRepo(t *testing.T) { + tests := []struct { + name string + podfileContent string + expected bool + wantErr bool + }{ + { + name: "Empty file", + podfileContent: "", + expected: false, + wantErr: false, + }, + { + name: "Specs repo defined", + podfileContent: repoPodfile, + expected: true, + wantErr: false, + }, + { + name: "Specs repo not defined", + podfileContent: cdnPodfile, + expected: false, + wantErr: false, + }, + { + name: "Specs repo defined with quotes and whitespace", + podfileContent: repoPodfileWithQuotes, + expected: true, + wantErr: false, + }, + { + name: "Other specs repo defined", + podfileContent: otherRepoPodfile, + expected: false, + wantErr: false, + }, + { + name: "Specs repo with lowercase URL", + podfileContent: repoPodfileLowercase, + expected: true, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + path := filepath.Join(t.TempDir(), "Podfile") + err := os.WriteFile(path, []byte(tt.podfileContent), 0777) + if err != nil { + t.Fatalf(err.Error()) + } + + actual, err := isPodfileUsingSpecsRepo(path) + if (err != nil) != tt.wantErr { + t.Errorf("Unexpected error status. Got error: %v, want error: %v", err, tt.wantErr) + } + if actual != tt.expected { + t.Errorf("Expected %v, but got %v", tt.expected, actual) + } + }) + } +} + +const cdnPodfile = ` +source 'https://cdn.cocoapods.org/' + +platform :ios, '11.7' + +def common_pods + pod 'FirebaseAnalytics', '~> 9.4' +end +` + +const repoPodfile = ` +source 'https://github.com/CocoaPods/Specs.git' + +platform :ios, '11.7' + +def common_pods + pod 'FirebaseAnalytics', '~> 9.4' +end +` + +const repoPodfileWithQuotes = ` +source "https://github.com/CocoaPods/Specs.git" + +platform :ios, '11.7' + +def common_pods + pod 'FirebaseAnalytics', '~> 9.4' +end +` + +const otherRepoPodfile = ` +source 'https://cdn.cocoapods.org/' +source 'https://github.com/artsy/Specs.git' + +platform :ios, '11.7' + +def common_pods + pod 'FirebaseAnalytics', '~> 9.4' +end +` + +const repoPodfileLowercase = ` +source 'https://github.com/cocoapods/specs.git' + +platform :ios, '11.7' + +def common_pods + pod 'FirebaseAnalytics', '~> 9.4' +end +`