diff --git a/Gopkg.lock b/Gopkg.lock index dee1c955..5b1bd9dd 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -2,56 +2,111 @@ [[projects]] - branch = "master" - name = "github.com/bitrise-io/go-utils" - packages = ["colorstring","command","errorutil","fileutil","log","pathutil","pkcs12","pkcs12/internal/rc2","retry","urlutil","ziputil"] - revision = "961320f9011cedf55e1da0578949bf63450a96c0" + name = "github.com/bitrise-io/bitrise" + packages = ["models"] + revision = "d517b4ec062349d3b475a1928a804bfa284e86d9" + version = "1.30.0" + +[[projects]] + name = "github.com/bitrise-io/envman" + packages = ["models"] + revision = "1716460e0651c3f40b9542f9e237b9a3d35773bb" + version = "2.2.3" [[projects]] branch = "master" - name = "github.com/bitrise-tools/go-android" + name = "github.com/bitrise-io/go-android" packages = ["sdk"] - revision = "00b72392d46cd594ca6a1c240ec9d8936127f4a4" + revision = "8082fe069ed29f394c2fd0724dd6bdc64e5cf6b4" [[projects]] branch = "master" - name = "github.com/bitrise-tools/go-steputils" - packages = ["input","tools"] - revision = "a848c9870ff7d745a8fb2a951e1c81fcb147b4ec" + name = "github.com/bitrise-io/go-steputils" + packages = [ + "stepconf", + "tools" + ] + revision = "cecc766da84859e37e780d9d1c416f0f3993e6b1" [[projects]] branch = "master" - name = "github.com/bitrise-tools/go-xcode" - packages = ["certificateutil","exportoptions","ipa","models","plistutil","profileutil","utility"] - revision = "6ef1fa022c0b47d73da0028f52b4be86bc6248a0" + name = "github.com/bitrise-io/go-utils" + packages = [ + "colorstring", + "command", + "errorutil", + "fileutil", + "log", + "parseutil", + "pathutil", + "pkcs12", + "pkcs12/internal/rc2", + "pointers", + "retry", + "urlutil", + "ziputil" + ] + revision = "8898129615c9e407fc6b0e60ea882f2b18ec4dc2" + +[[projects]] + branch = "master" + name = "github.com/bitrise-io/go-xcode" + packages = [ + "certificateutil", + "exportoptions", + "ipa", + "models", + "plistutil", + "profileutil", + "utility" + ] + revision = "a49d262bd2151997b9b18f882654eae3aab31a9d" + +[[projects]] + name = "github.com/bitrise-io/stepman" + packages = ["models"] + revision = "050220145c5a1c555ae67c6f62677d95eb46ed26" + version = "0.11.5" [[projects]] branch = "master" name = "github.com/fullsailor/pkcs7" packages = ["."] - revision = "a009d8d7de53d9503c797cb8ec66fa3b21eed209" + revision = "d7302db945fa6ea264fb79d8e13e931ea514a602" + +[[projects]] + name = "github.com/gorilla/mux" + packages = ["."] + revision = "ed099d42384823742bba0bf9a72b53b55c9e2e38" + version = "v1.7.2" [[projects]] - branch = "master" name = "github.com/hashicorp/go-version" packages = ["."] - revision = "fc61389e27c71d120f87031ca8c88a3428f372dd" + revision = "ac23dc3fea5d1a983c43f6a0f6e2c13f0195d8bd" + version = "v1.2.0" [[projects]] name = "github.com/pkg/errors" packages = ["."] - revision = "645ef00459ed84a119197bfb8d8205042c6df63d" - version = "v0.8.0" + revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4" + version = "v0.8.1" + +[[projects]] + name = "github.com/ryanuber/go-glob" + packages = ["."] + revision = "51a8f68e6c24dc43f1e371749c89a267de4ebc53" + version = "v1.0.0" [[projects]] branch = "master" name = "howett.net/plist" packages = ["."] - revision = "233df3c4f07b0c562da0e8a6fb850681ac49bb90" + revision = "591f970eefbbeb04d7b37f334a0c4c3256e32876" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "11a91fd6c3234bea574b52e6e71f55047f3899549ff2667886c4b444e9ed2e4b" + inputs-digest = "6f055692080f152d58792e94af9eed0f4c4e5afd0e5685e4c637807056259f0a" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 7ff3227a..66e71cb3 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -1,15 +1,36 @@ + +[[constraint]] + branch = "master" + name = "github.com/bitrise-io/bitrise" + +[[constraint]] + branch = "master" + name = "github.com/bitrise-io/go-android" + [[constraint]] - name = "github.com/bitrise-io/go-utils" branch = "master" + name = "github.com/bitrise-io/go-steputils" [[constraint]] - name = "github.com/bitrise-tools/go-android" branch = "master" + name = "github.com/bitrise-io/go-utils" [[constraint]] - name = "github.com/bitrise-tools/go-steputils" branch = "master" + name = "github.com/bitrise-io/go-xcode" + +[[constraint]] + name = "github.com/gorilla/mux" + version = "1.7.2" + +[[constraint]] + name = "github.com/pkg/errors" + version = "0.8.1" [[constraint]] - name = "github.com/bitrise-tools/go-xcode" branch = "master" + name = "howett.net/plist" + +[prune] + go-tests = true + unused-packages = true diff --git a/main.go b/main.go index 1283ca83..5103b53e 100644 --- a/main.go +++ b/main.go @@ -6,29 +6,36 @@ import ( "html/template" "os" "path/filepath" - "strings" + "github.com/bitrise-steplib/steps-deploy-to-bitrise-io/test" + + "github.com/bitrise-io/go-steputils/stepconf" + "github.com/bitrise-io/go-steputils/tools" "github.com/bitrise-io/go-utils/log" "github.com/bitrise-io/go-utils/pathutil" "github.com/bitrise-io/go-utils/ziputil" - "github.com/bitrise-io/steps-deploy-to-bitrise-io/uploaders" - "github.com/bitrise-tools/go-steputils/input" - "github.com/bitrise-tools/go-steputils/tools" + "github.com/bitrise-steplib/steps-deploy-to-bitrise-io/uploaders" ) var fileBaseNamesToSkip = []string{".DS_Store"} -// ConfigsModel ... -type ConfigsModel struct { - BuildURL string - APIToken string - IsCompress string - ZipName string - DeployPath string - NotifyUserGroups string - NotifyEmailList string - IsPublicPageEnabled string - PublicInstallPageMapFormat string +// Config ... +type Config struct { + BuildURL string `env:"build_url,required"` + APIToken string `env:"build_api_token,required"` + IsCompress string `env:"is_compress,opt[true,false]"` + ZipName string `env:"zip_name"` + DeployPath string `env:"deploy_path,dir"` + NotifyUserGroups string `env:"notify_user_groups"` + NotifyEmailList string `env:"notify_email_list"` + IsPublicPageEnabled string `env:"is_enable_public_page,opt[true,false]"` + PublicInstallPageMapFormat string `env:"public_install_page_url_map_format,required"` + BuildSlug string `env:"BITRISE_BUILD_SLUG,required"` + TestDeployDir string `env:"BITRISE_TEST_DEPLOY_DIR,required"` + AppSlug string `env:"BITRISE_APP_SLUG,required"` + AddonAPIBaseURL string `env:"addon_api_base_url,required"` + AddonAPIToken string `env:"addon_api_token"` + DebugMode bool `env:"debug_mode,opt[true,false]"` } // PublicInstallPage ... @@ -37,76 +44,29 @@ type PublicInstallPage struct { URL string } -func createConfigsModelFromEnvs() ConfigsModel { - return ConfigsModel{ - BuildURL: os.Getenv("build_url"), - APIToken: os.Getenv("build_api_token"), - IsCompress: os.Getenv("is_compress"), - ZipName: os.Getenv("zip_name"), - DeployPath: os.Getenv("deploy_path"), - NotifyUserGroups: os.Getenv("notify_user_groups"), - NotifyEmailList: os.Getenv("notify_email_list"), - IsPublicPageEnabled: os.Getenv("is_enable_public_page"), - PublicInstallPageMapFormat: os.Getenv("public_install_page_url_map_format"), - } -} - -func (configs ConfigsModel) validate() error { - if err := input.ValidateIfNotEmpty(configs.BuildURL); err != nil { - return fmt.Errorf("BuildURL - %s", err) - } - if err := input.ValidateIfNotEmpty(configs.APIToken); err != nil { - return fmt.Errorf("APIToken - %s", err) - } - if err := input.ValidateWithOptions(configs.IsCompress, "true", "false"); err != nil { - return fmt.Errorf("IsCompress - %s", err) - } - if err := input.ValidateIfPathExists(configs.DeployPath); err != nil { - return fmt.Errorf("DeployPath - %s", err) - } - if err := input.ValidateWithOptions(configs.IsPublicPageEnabled, "true", "false"); err != nil { - return fmt.Errorf("IsPublicPageEnabled - %s", err) - } - if err := input.ValidateIfNotEmpty(configs.PublicInstallPageMapFormat); err != nil { - return fmt.Errorf("PublicInstallPageMapFormat - %s", err) - } - if err := validateGoTemplate(configs.PublicInstallPageMapFormat); err != nil { - return fmt.Errorf("PublicInstallPageMapFormat - %s", err) - } - return nil -} - -func (configs ConfigsModel) print() { - log.Infof("Configs:") - log.Printf("- BuildURL: %s", configs.BuildURL) - log.Printf("- APIToken: %s", configs.APIToken) - log.Printf("- IsCompress: %s", configs.IsCompress) - log.Printf("- DeployPath: %s", configs.DeployPath) - log.Printf("- NotifyUserGroups: %s", configs.NotifyUserGroups) - log.Printf("- NotifyEmailList: %s", configs.NotifyEmailList) - log.Printf("- IsPublicPageEnabled: %s", configs.IsPublicPageEnabled) - log.Printf("- PublicInstallPageMapFormat: %s", configs.PublicInstallPageMapFormat) -} - func fail(format string, v ...interface{}) { log.Errorf(format, v...) os.Exit(1) } func main() { - configs := createConfigsModelFromEnvs() - configs.DeployPath = strings.TrimSpace(configs.DeployPath) + var config Config + if err := stepconf.Parse(&config); err != nil { + fail("Issue with input: %s", err) + } + if err := validateGoTemplate(config.PublicInstallPageMapFormat); err != nil { + fail("PublicInstallPageMapFormat - %s", err) + } + + stepconf.Print(config) fmt.Println() - configs.print() - if err := configs.validate(); err != nil { - fail("Issue with input: %s", err) - } + log.SetEnableDebugLog(config.DebugMode) - absDeployPth, err := pathutil.AbsPath(configs.DeployPath) + absDeployPth, err := pathutil.AbsPath(config.DeployPath) if err != nil { - fail("Failed to expand path: %s, error: %s", configs.DeployPath, err) + fail("Failed to expand path: %s, error: %s", config.DeployPath, err) } filesToDeploy := []string{} @@ -127,13 +87,13 @@ func main() { log.Infof("Deploying single file") filesToDeploy = []string{absDeployPth} - } else if configs.IsCompress == "true" { + } else if config.IsCompress == "true" { fmt.Println() log.Infof("Deploying compressed Deploy directory") zipName := filepath.Base(absDeployPth) - if configs.ZipName != "" { - zipName = configs.ZipName + if config.ZipName != "" { + zipName = config.ZipName } tmpZipPath := filepath.Join(tmpDir, zipName+".zip") @@ -195,7 +155,7 @@ func main() { case ".ipa": log.Donef("Uploading ipa file: %s", pth) - installPage, err := uploaders.DeployIPA(pth, configs.BuildURL, configs.APIToken, configs.NotifyUserGroups, configs.NotifyEmailList, configs.IsPublicPageEnabled) + installPage, err := uploaders.DeployIPA(pth, config.BuildURL, config.APIToken, config.NotifyUserGroups, config.NotifyEmailList, config.IsPublicPageEnabled) if err != nil { fail("Deploy failed, error: %s", err) } @@ -206,7 +166,7 @@ func main() { case ".apk": log.Donef("Uploading apk file: %s", pth) - installPage, err := uploaders.DeployAPK(pth, configs.BuildURL, configs.APIToken, configs.NotifyUserGroups, configs.NotifyEmailList, configs.IsPublicPageEnabled) + installPage, err := uploaders.DeployAPK(pth, config.BuildURL, config.APIToken, config.NotifyUserGroups, config.NotifyEmailList, config.IsPublicPageEnabled) if err != nil { fail("Deploy failed, error: %s", err) } @@ -217,14 +177,14 @@ func main() { default: log.Donef("Uploading file: %s", pth) - installPage, err := uploaders.DeployFile(pth, configs.BuildURL, configs.APIToken, configs.NotifyUserGroups, configs.NotifyEmailList, configs.IsPublicPageEnabled) + installPage, err := uploaders.DeployFile(pth, config.BuildURL, config.APIToken, config.NotifyUserGroups, config.NotifyEmailList, config.IsPublicPageEnabled) if err != nil { fail("Deploy failed, error: %s", err) } if installPage != "" { publicInstallPages[filepath.Base(pth)] = installPage - } else if configs.IsPublicPageEnabled == "true" { + } else if config.IsPublicPageEnabled == "true" { log.Warnf("is_enable_public_page is set, but public download isn't allowed for this type of file") } } @@ -232,7 +192,7 @@ func main() { fmt.Println() log.Donef("Success") - log.Printf("You can find the Artifact on Bitrise, on the Build's page: %s", configs.BuildURL) + log.Printf("You can find the Artifact on Bitrise, on the Build's page: %s", config.BuildURL) if len(publicInstallPages) > 0 { temp := template.New("Public Install Page template") @@ -249,7 +209,7 @@ func main() { } log.Printf("The public install page url is now available in the Environment Variable: BITRISE_PUBLIC_INSTALL_PAGE_URL (value: %s)\n", pages[0].URL) - temp, err := temp.Parse(configs.PublicInstallPageMapFormat) + temp, err := temp.Parse(config.PublicInstallPageMapFormat) if err != nil { fail("Error during parsing PublicInstallPageMap: ", err) } @@ -265,6 +225,25 @@ func main() { log.Printf("A map of deployed files and their public install page urls is now available in the Environment Variable: BITRISE_PUBLIC_INSTALL_PAGE_URL_MAP (value: %s)", buf.String()) log.Printf("") } + + // Deploy test files + if config.AddonAPIToken != "" { + fmt.Println() + log.Infof("Upload test results") + + testResults, err := test.ParseTestResults(config.TestDeployDir) + if err != nil { + fail("Error during parsing test results: ", err) + } + + log.Printf("- uploading (%d) test results", len(testResults)) + + if err := testResults.Upload(config.AddonAPIToken, config.AddonAPIBaseURL, config.AppSlug, config.BuildSlug); err != nil { + fail("Failed to upload test results: ", err) + } + + log.Donef("Success") + } } func validateGoTemplate(publicInstallPageMapFormat string) error { diff --git a/step.yml b/step.yml index f860f085..50dba83d 100644 --- a/step.yml +++ b/step.yml @@ -5,9 +5,9 @@ description: |- This generic artifacts deployer attaches the artifacts to bitrise.io builds. You'll see the deployed files in the `Apps and Artifacts` section of the build's page on bitrise.io. -website: https://github.com/bitrise-io/steps-deploy-to-bitrise-io -source_code_url: https://github.com/bitrise-io/steps-deploy-to-bitrise-io -support_url: https://github.com/bitrise-io/steps-deploy-to-bitrise-io/issues +website: https://github.com/bitrise-steplib/steps-deploy-to-bitrise-io +source_code_url: https://github.com/bitrise-steplib/steps-deploy-to-bitrise-io +support_url: https://github.com/bitrise-steplib/steps-deploy-to-bitrise-io/issues host_os_tags: - "osx-10.10" project_type_tags: [] @@ -19,7 +19,7 @@ is_skippable: false run_if: .IsCI toolkit: go: - package_name: github.com/bitrise-io/steps-deploy-to-bitrise-io + package_name: github.com/bitrise-steplib/steps-deploy-to-bitrise-io inputs: - deploy_path: "$BITRISE_DEPLOY_DIR" opts: @@ -146,6 +146,32 @@ inputs: is_required: true is_dont_change_value: true is_sensitive: true + - addon_api_base_url: "https://vdt.bitrise.io/test" + opts: + title: "Test API's base URL" + summary: The URL where test API is accessible. + description: | + The URL where test API is accessible. + is_required: true + is_dont_change_value: true + - addon_api_token: $ADDON_VDTESTING_API_TOKEN + opts: + title: "API Token" + summary: The token required to authenticate with the API. + description: | + The token required to authenticate with the API. + is_dont_change_value: true + is_sensitive: true + - debug_mode: "false" + opts: + category: Debug + title: "Enable Debug Mode" + summary: The step will print more verbose logs if enabled. + description: The step will print more verbose logs if enabled. + is_required: true + value_options: + - "false" + - "true" outputs: - BITRISE_PUBLIC_INSTALL_PAGE_URL: opts: diff --git a/test/converters/converters.go b/test/converters/converters.go new file mode 100644 index 00000000..2c164d86 --- /dev/null +++ b/test/converters/converters.go @@ -0,0 +1,28 @@ +// Package converters contains the interface that is required to be a package a test result converter. +// It must be possible to set files from outside(for example if someone wants to use +// a pre-filtered files list), need to return Junit4 xml test result, and needs to have a +// Detect method to see if the converter can run with the files included in the test result dictionary. +// (So a converter can run only if the dir has a TestSummaries.plist file for example) +package converters + +import ( + "github.com/bitrise-steplib/steps-deploy-to-bitrise-io/test/converters/junitxml" + "github.com/bitrise-steplib/steps-deploy-to-bitrise-io/test/converters/xcresult" + "github.com/bitrise-steplib/steps-deploy-to-bitrise-io/test/junit" +) + +// Intf is the required interface a converter need to match +type Intf interface { + XML() (junit.XML, error) + Detect([]string) bool +} + +var converters = []Intf{ + &junitxml.Converter{}, + &xcresult.Converter{}, +} + +// List lists all supported converters +func List() []Intf { + return converters +} diff --git a/test/converters/junitxml/junitxml.go b/test/converters/junitxml/junitxml.go new file mode 100644 index 00000000..48c109ea --- /dev/null +++ b/test/converters/junitxml/junitxml.go @@ -0,0 +1,62 @@ +package junitxml + +import ( + "encoding/xml" + "strings" + + "github.com/bitrise-io/go-utils/fileutil" + "github.com/bitrise-steplib/steps-deploy-to-bitrise-io/test/junit" + "github.com/pkg/errors" +) + +// Converter holds data of the converter +type Converter struct { + files []string +} + +// Detect return true if the test results a Juni4 XML file +func (h *Converter) Detect(files []string) bool { + h.files = nil + for _, file := range files { + if strings.HasSuffix(file, ".xml") { + h.files = append(h.files, file) + } + } + return len(h.files) > 0 +} + +func parseTestSuites(filePath string) ([]junit.TestSuite, error) { + data, err := fileutil.ReadBytesFromFile(filePath) + if err != nil { + return nil, err + } + + var testSuites junit.XML + testSuitesError := xml.Unmarshal(data, &testSuites) + if testSuitesError == nil { + return testSuites.TestSuites, nil + } + + var testSuite junit.TestSuite + if err := xml.Unmarshal(data, &testSuite); err != nil { + return nil, errors.Wrap(errors.Wrap(err, string(data)), testSuitesError.Error()) + } + + return []junit.TestSuite{testSuite}, nil +} + +// XML returns the xml content bytes +func (h *Converter) XML() (junit.XML, error) { + var xmlContent junit.XML + + for _, file := range h.files { + testSuites, err := parseTestSuites(file) + if err != nil { + return junit.XML{}, err + } + + xmlContent.TestSuites = append(xmlContent.TestSuites, testSuites...) + } + + return xmlContent, nil +} diff --git a/test/converters/junitxml/junitxml_test.go b/test/converters/junitxml/junitxml_test.go new file mode 100644 index 00000000..d1df091c --- /dev/null +++ b/test/converters/junitxml/junitxml_test.go @@ -0,0 +1,25 @@ +package junitxml + +import ( + "testing" +) + +func Test_parseTestSuites(t *testing.T) { + tests := []struct { + name string + path string + wantErr bool + }{ + {name: "root element is testsuites", path: "./testdata/testsuites.xml", wantErr: false}, + {name: "root element is testsuite", path: "./testdata/testsuite.xml", wantErr: false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := parseTestSuites(tt.path) + if (err != nil) != tt.wantErr { + t.Errorf("parseTestSuites() error = %v, wantErr %v", err, tt.wantErr) + return + } + }) + } +} diff --git a/test/converters/junitxml/testdata/testsuite.xml b/test/converters/junitxml/testdata/testsuite.xml new file mode 100644 index 00000000..48016845 --- /dev/null +++ b/test/converters/junitxml/testdata/testsuite.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/test/converters/junitxml/testdata/testsuites.xml b/test/converters/junitxml/testdata/testsuites.xml new file mode 100644 index 00000000..dc7fd42f --- /dev/null +++ b/test/converters/junitxml/testdata/testsuites.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/test/converters/xcresult/testsummariesplist.go b/test/converters/xcresult/testsummariesplist.go new file mode 100644 index 00000000..a60ab66d --- /dev/null +++ b/test/converters/xcresult/testsummariesplist.go @@ -0,0 +1,105 @@ +package xcresult + +import ( + "fmt" + "strings" +) + +// TestSummaryPlist ... +type TestSummaryPlist struct { + FormatVersion string + TestableSummaries []TestableSummary +} + +func collapseSubtestTree(data Subtests) (tests Subtests) { + for _, test := range data { + if len(test.Subtests) > 0 { + tests = append(tests, collapseSubtestTree(test.Subtests)...) + } + if test.TestStatus != "" { + tests = append(tests, test) + } + } + return +} + +// Tests returns the collapsed tree of tests +func (summaryPlist TestSummaryPlist) Tests() map[string]Subtests { + tests := map[string]Subtests{} + var subTests Subtests + for _, testableSummary := range summaryPlist.TestableSummaries { + for _, test := range testableSummary.Tests { + subTests = append(subTests, collapseSubtestTree(test.Subtests)...) + } + } + for _, test := range subTests { + // TestIdentifier is in a format of testID/testCase + testID := strings.Split(test.TestIdentifier, "/")[0] + tests[testID] = append(tests[testID], test) + } + return tests +} + +// Test ... +type Test struct { + Subtests Subtests +} + +// TestableSummary ... +type TestableSummary struct { + TargetName string + TestKind string + TestName string + TestObjectClass string + Tests []Test +} + +// FailureSummary ... +type FailureSummary struct { + FileName string + LineNumber int + Message string + PerformanceFailure bool +} + +// Subtest ... +type Subtest struct { + Duration float64 + TestStatus string + TestIdentifier string + TestName string + TestObjectClass string + Subtests Subtests + FailureSummaries []FailureSummary +} + +// Failure ... +func (st Subtest) Failure() (message string) { + prefix := "" + for _, failure := range st.FailureSummaries { + message += fmt.Sprintf("%s%s:%d - %s", prefix, failure.FileName, failure.LineNumber, failure.Message) + prefix = "\n" + } + return +} + +// Subtests ... +type Subtests []Subtest + +// FailuresCount ... +func (sts Subtests) FailuresCount() (count int) { + for _, test := range sts { + if len(test.FailureSummaries) > 0 { + count++ + } + } + return count +} + +// TotalTime ... +func (sts Subtests) TotalTime() (time float64) { + for _, test := range sts { + time += test.Duration + } + return time +} diff --git a/test/converters/xcresult/xcresult.go b/test/converters/xcresult/xcresult.go new file mode 100644 index 00000000..30c6c0a2 --- /dev/null +++ b/test/converters/xcresult/xcresult.go @@ -0,0 +1,64 @@ +package xcresult + +import ( + "path/filepath" + "strings" + + "github.com/bitrise-io/go-utils/fileutil" + "github.com/bitrise-steplib/steps-deploy-to-bitrise-io/test/junit" + "howett.net/plist" +) + +// Converter ... +type Converter struct { + files []string + testSummariesPlistPath string +} + +// Detect ... +func (h *Converter) Detect(files []string) bool { + h.files = files + for _, file := range h.files { + if strings.HasSuffix(file, ".xcresult") { + h.testSummariesPlistPath = filepath.Join(file, "TestSummaries.plist") + return true + } + } + return false +} + +// XML ... +func (h *Converter) XML() (junit.XML, error) { + data, err := fileutil.ReadBytesFromFile(h.testSummariesPlistPath) + if err != nil { + return junit.XML{}, err + } + + var plistData TestSummaryPlist + if _, err := plist.Unmarshal(data, &plistData); err != nil { + return junit.XML{}, err + } + + var xmlData junit.XML + for testID, tests := range plistData.Tests() { + testSuite := junit.TestSuite{ + Name: testID, + Tests: len(tests), + Failures: tests.FailuresCount(), + Time: tests.TotalTime(), + } + + for _, test := range tests { + testSuite.TestCases = append(testSuite.TestCases, junit.TestCase{ + Name: test.TestName, + ClassName: testID, + Failure: test.Failure(), + Time: test.Duration, + }) + } + + xmlData.TestSuites = append(xmlData.TestSuites, testSuite) + } + + return xmlData, nil +} diff --git a/test/junit/xml.go b/test/junit/xml.go new file mode 100644 index 00000000..f5501e73 --- /dev/null +++ b/test/junit/xml.go @@ -0,0 +1,29 @@ +package junit + +import "encoding/xml" + +// XML ... +type XML struct { + XMLName xml.Name `xml:"testsuites"` + TestSuites []TestSuite `xml:"testsuite"` +} + +// TestSuite ... +type TestSuite struct { + XMLName xml.Name `xml:"testsuite"` + Name string `xml:"name,attr"` + Tests int `xml:"tests,attr"` + Failures int `xml:"failures,attr"` + Errors int `xml:"errors,attr"` + Time float64 `xml:"time,attr"` + TestCases []TestCase `xml:"testcase"` +} + +// TestCase ... +type TestCase struct { + XMLName xml.Name `xml:"testcase"` + Name string `xml:"name,attr"` + ClassName string `xml:"classname,attr"` + Time float64 `xml:"time,attr"` + Failure string `xml:"failure,omitempty"` +} diff --git a/test/test.go b/test/test.go new file mode 100644 index 00000000..36ccd03a --- /dev/null +++ b/test/test.go @@ -0,0 +1,275 @@ +package test + +import ( + "bytes" + "encoding/json" + "encoding/xml" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/http/httputil" + "os" + "path/filepath" + "strings" + + "github.com/bitrise-io/bitrise/models" + "github.com/bitrise-io/go-utils/colorstring" + "github.com/bitrise-io/go-utils/fileutil" + "github.com/bitrise-io/go-utils/log" + "github.com/bitrise-io/go-xcode/utility" + "github.com/bitrise-steplib/steps-deploy-to-bitrise-io/test/converters" +) + +// FileInfo ... +type FileInfo struct { + FileName string `json:"filename"` + FileSize int `json:"filesize"` +} + +// UploadURL ... +type UploadURL struct { + FileName string `json:"filename"` + URL string `json:"upload_url"` +} + +// UploadRequest ... +type UploadRequest struct { + Name string `json:"name"` + Step models.TestResultStepInfo `json:"step_info"` + Assets []FileInfo `json:"assets"` + FileInfo +} + +// UploadResponse ... +type UploadResponse struct { + ID string `json:"id"` + Assets []UploadURL `json:"assets"` + UploadURL +} + +// Result ... +type Result struct { + Name string + XMLContent []byte + ImagePaths []string + StepInfo models.TestResultStepInfo +} + +// Results ... +type Results []Result + +func httpCall(apiToken, method, url string, input io.Reader, output interface{}) error { + if apiToken != "" { + url = url + "/" + apiToken + } + req, err := http.NewRequest(method, url, input) + if err != nil { + return err + } + + b, err := httputil.DumpRequest(req, true) + if err != nil { + return err + } + fmt.Println(string(b)) + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + + b, err = httputil.DumpResponse(resp, true) + if err != nil { + return err + } + log.Debugf(string(b)) + + defer func() { + if err := resp.Body.Close(); err != nil { + fmt.Printf("Failed to close body, error: %s\n", err) + } + }() + + if resp.StatusCode < 200 || 299 < resp.StatusCode { + bodyData, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("unsuccessful response code: %d and failed to read body, error: %s", resp.StatusCode, err) + } + return fmt.Errorf("unsuccessful response code: %d\nbody:\n%s", resp.StatusCode, bodyData) + } + + if output != nil { + return json.NewDecoder(resp.Body).Decode(&output) + } + return nil +} + +func findImages(testDir string) (imageFilePaths []string) { + for _, ext := range []string{".jpg", ".jpeg", ".png"} { + if paths, err := filepath.Glob(filepath.Join(testDir, "*"+ext)); err == nil { + imageFilePaths = append(imageFilePaths, paths...) + } + if paths, err := filepath.Glob(filepath.Join(testDir, "*"+strings.ToUpper(ext))); err == nil { + imageFilePaths = append(imageFilePaths, paths...) + } + } + return +} + +// ParseTestResults ... +func ParseTestResults(testsRootDir string) (results Results, err error) { + // read dirs in base tests dir + // + + testDirs, err := ioutil.ReadDir(testsRootDir) + if err != nil { + return nil, err + } + + // find test results in each dir, skip if invalid test dir + for _, testDir := range testDirs { + // / + testDirPath := filepath.Join(testsRootDir, testDir.Name()) + + if !testDir.IsDir() { + log.Debugf(colorstring.Yellowf("%s is not a directory", testDirPath)) + continue + } + + // read unique test phase dirs + testPhaseDirs, err := ioutil.ReadDir(testDirPath) + if err != nil { + return nil, err + } + + // find step-info in dir, continue if no step-info.json as this file is only required if step has exported artifacts also + // //step-info.json + var stepInfo *models.TestResultStepInfo + stepInfoFileContent, err := fileutil.ReadBytesFromFile(filepath.Join(testDirPath, "step-info.json")) + if err != nil { + log.Debugf(colorstring.Yellowf("Failed to read step-info.json file in dir: %s, error: %s", testDirPath, err)) + continue + } + + if err := json.Unmarshal(stepInfoFileContent, &stepInfo); err != nil { + continue + } + + for _, testPhaseDir := range testPhaseDirs { + if !testPhaseDir.IsDir() { + continue + } + + // // + testPhaseDirPath := filepath.Join(testDirPath, testPhaseDir.Name()) + // read one level of file set only ///files_to_get + testFiles, err := filepath.Glob(filepath.Join(utility.EscapeGlobPath(testPhaseDirPath), "*")) + if err != nil { + return nil, err + } + + // get the converter that can manage test type contained in the dir + for _, converter := range converters.List() { + + // skip if couldn't find converter for content type + if converter.Detect(testFiles) { + // test-info.json file is required + testInfoFileContent, err := fileutil.ReadBytesFromFile(filepath.Join(testPhaseDirPath, "test-info.json")) + if err != nil { + return nil, err + } + + var testInfo struct { + Name string `json:"test-name"` + } + if err := json.Unmarshal(testInfoFileContent, &testInfo); err != nil { + return nil, err + } + + junitXML, err := converter.XML() + if err != nil { + return nil, err + } + xmlData, err := xml.MarshalIndent(junitXML, "", " ") + if err != nil { + return nil, err + } + xmlData = append([]byte(``+"\n"), xmlData...) + + // so here I will have image paths, xml data, and step info per test dir in a bundle info + results = append(results, Result{ + Name: testInfo.Name, + XMLContent: xmlData, + ImagePaths: findImages(testPhaseDirPath), + StepInfo: *stepInfo, + }) + } + } + } + } + return results, nil +} + +// Upload ... +func (results Results) Upload(apiToken, endpointBaseURL, appSlug, buildSlug string) error { + for _, result := range results { + uploadReq := UploadRequest{ + FileInfo: FileInfo{ + FileName: "test_result.xml", + FileSize: len(result.XMLContent), + }, + Name: result.Name, + Step: result.StepInfo, + } + for _, asset := range result.ImagePaths { + fi, err := os.Stat(asset) + if err != nil { + return err + } + uploadReq.Assets = append(uploadReq.Assets, FileInfo{ + FileName: filepath.Base(asset), + FileSize: int(fi.Size()), + }) + } + + uploadRequestBodyData, err := json.Marshal(uploadReq) + if err != nil { + return err + } + + var ( + uploadResponse UploadResponse + uploadRequestURL = fmt.Sprintf("%s/apps/%s/builds/%s/test_reports", endpointBaseURL, appSlug, buildSlug) + ) + if err := httpCall(apiToken, http.MethodPost, uploadRequestURL, bytes.NewReader(uploadRequestBodyData), &uploadResponse); err != nil { + return err + } + + if err := httpCall("", http.MethodPut, uploadResponse.URL, bytes.NewReader(result.XMLContent), nil); err != nil { + return err + } + + for _, upload := range uploadResponse.Assets { + for _, file := range result.ImagePaths { + if filepath.Base(file) == upload.FileName { + fi, err := os.Open(file) + if err != nil { + return err + } + if err := httpCall("", http.MethodPut, upload.URL, fi, nil); err != nil { + return err + } + break + } + } + } + + var uploadPatchURL = fmt.Sprintf("%s/apps/%s/builds/%s/test_reports/%s", endpointBaseURL, appSlug, buildSlug, uploadResponse.ID) + if err := httpCall(apiToken, http.MethodPatch, uploadPatchURL, strings.NewReader(`{"uploaded":true}`), nil); err != nil { + return err + } + } + + return nil +} diff --git a/test/test_test.go b/test/test_test.go new file mode 100644 index 00000000..14128e9f --- /dev/null +++ b/test/test_test.go @@ -0,0 +1,275 @@ +package test + +import ( + "encoding/json" + "io/ioutil" + "net/http" + "os" + "path/filepath" + "testing" + "time" + + "github.com/bitrise-io/bitrise/models" + "github.com/bitrise-io/go-utils/fileutil" + "github.com/bitrise-io/go-utils/pathutil" + "github.com/gorilla/mux" + "github.com/pkg/errors" +) + +func createDummyFilesInDirWithContent(dir, content string, fileNames []string) error { + for _, file := range fileNames { + if err := os.MkdirAll(filepath.Dir(filepath.Join(dir, file)), 0777); err != nil { + return err + } + if err := fileutil.WriteStringToFile(filepath.Join(dir, file), content); err != nil { + return err + } + } + return nil +} + +func Test_Upload(t *testing.T) { + tempDir, err := pathutil.NormalizedOSTempDirPath("test") + if err != nil { + t.Fatal("failed to create temp dir, error:", err) + } + + testResponseID := "mock-test-id" + testXMLContent := []byte("test xml content") + testStepInfo := models.TestResultStepInfo{ID: "test-ID", Title: "test-Title", Version: "test-Version", Number: 19} + testAssetPaths := []string{filepath.Join(tempDir, "image1.png"), filepath.Join(tempDir, "image2.png"), filepath.Join(tempDir, "image3.png")} + + if err := createDummyFilesInDirWithContent(tempDir, "dummy data", []string{"image1.png", "image2.png", "image3.png"}); err != nil { + t.Fatal(err) + } + + results := Results{ + Result{ + XMLContent: testXMLContent, + StepInfo: testStepInfo, + ImagePaths: testAssetPaths, + }, + } + + go func() { + router := mux.NewRouter() + + router.HandleFunc("/test/apps/{app_slug}/builds/{build_slug}/test_reports/{accessToken}", func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + if _, ok := vars["app_slug"]; !ok { + t.Fatal("app_slug must be specified") + } + if _, ok := vars["build_slug"]; !ok { + t.Fatal("build_slug must be specified") + } + + var uploadReq UploadRequest + if err := json.NewDecoder(r.Body).Decode(&uploadReq); err != nil { + t.Fatal("failed to execute get request, error:", err) + } + + response := UploadResponse{ + ID: testResponseID, + UploadURL: UploadURL{FileName: uploadReq.FileName, URL: "http://localhost:8893/teststorage/" + uploadReq.FileName}, + } + + for _, asset := range uploadReq.Assets { + response.Assets = append(response.Assets, UploadURL{ + FileName: asset.FileName, + URL: "http://localhost:8893/teststorage/" + asset.FileName, + }) + } + + b, err := json.Marshal(response) + if err != nil { + t.Fatal(err) + } + if _, err := w.Write(b); err != nil { + t.Fatal("Failed to write to the writer, error:", err) + } + }).Methods("POST") + + router.HandleFunc("/teststorage/{file_name}", func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + fName, ok := vars["file_name"] + if !ok { + t.Fatal("file_name must be specified") + } + + receivedData, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Fatal(err) + } + + if fName == "test_result.xml" { + if string(receivedData) == string(testXMLContent) { + w.WriteHeader(http.StatusOK) + return + } + } + + for _, assetPath := range testAssetPaths { + if filepath.Base(assetPath) == fName { + fileData, err := fileutil.ReadStringFromFile(assetPath) + if err != nil { + t.Fatal(err) + } + + if fileData != string(receivedData) { + t.Fatal("files are not the same!") + } + + w.WriteHeader(http.StatusOK) + return + } + } + + w.WriteHeader(http.StatusNotAcceptable) + }).Methods("PUT") + + router.HandleFunc("/test/apps/{app_slug}/builds/{build_slug}/test_reports/{id}/{accessToken}", func(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + if _, ok := vars["app_slug"]; !ok { + t.Fatal("app_slug must be specified") + } + if _, ok := vars["build_slug"]; !ok { + t.Fatal("build_slug must be specified") + } + id, ok := vars["id"] + if !ok { + t.Fatal("id must be specified") + } + + if id != testResponseID { + w.WriteHeader(http.StatusNotAcceptable) + } + + }).Methods("PATCH") + + t.Fatal(http.ListenAndServe(":8893", router)) + }() + + time.Sleep(time.Second) + + if err := results.Upload("access-token", "http://localhost:8893/test", "test-app-slug", "test-build-slug"); err != nil { + t.Fatalf("%v", errors.WithStack(err)) + return + } +} + +func Test_ParseTestResults(t *testing.T) { + sampleTestSummariesPlist, err := fileutil.ReadStringFromFile(filepath.Join("testdata", "ios_testsummaries_plist.golden")) + if err != nil { + t.Fatal("unable to read golden file, error:", err) + } + sampleIOSXmlOutput, err := fileutil.ReadStringFromFile(filepath.Join("testdata", "ios_xml_output.golden")) + if err != nil { + t.Fatal("unable to read golden file, error:", err) + } + + // creating test results + { + testsDir, err := pathutil.NormalizedOSTempDirPath("test") + if err != nil { + t.Fatal("failed to create temp dir, error:", err) + } + + _, err = ioutil.TempDir(testsDir, "test-result") + if err != nil { + t.Fatal("failed to create temp dir, error:", err) + } + + bundle, err := ParseTestResults(testsDir) + if err != nil { + t.Fatal("failed to get bundle, error:", err) + } + + if len(bundle) != 0 { + t.Fatal("should be 0 test asset pack") + } + } + + // creating android test results + { + testsDir, err := pathutil.NormalizedOSTempDirPath("test") + if err != nil { + t.Fatal("failed to create temp dir, error:", err) + } + + testDir, err := ioutil.TempDir(testsDir, "test-result") + if err != nil { + t.Fatal("failed to create temp dir, error:", err) + } + + phaseDir, err := ioutil.TempDir(testDir, "phase") + if err != nil { + t.Fatal("failed to create temp dir, error:", err) + } + + if err := createDummyFilesInDirWithContent(testDir, `{"title": "test title"}`, []string{"step-info.json"}); err != nil { + t.Fatal("failed to create dummy files in dir, error:", err) + } + if err := createDummyFilesInDirWithContent(phaseDir, `{"name": "test name"}`, []string{"test-info.json"}); err != nil { + t.Fatal("failed to create dummy files in dir, error:", err) + } + if err := createDummyFilesInDirWithContent(phaseDir, "test content", []string{"image.png", "image3.jpeg", "dirty.gif", "dirty.html"}); err != nil { + t.Fatal("failed to create dummy files in dir, error:", err) + } + if err := createDummyFilesInDirWithContent(phaseDir, sampleIOSXmlOutput, []string{"result.xml"}); err != nil { + t.Fatal("failed to create dummy files in dir, error:", err) + } + + bundle, err := ParseTestResults(testsDir) + if err != nil { + t.Fatal("failed to get bundle, error:", err) + } + if len(bundle) != 1 { + t.Fatalf("should be 1 test asset pack: %#v", bundle) + } + + if len(bundle[0].XMLContent) != len(sampleIOSXmlOutput) { + t.Fatal("wrong xml content") + } + } + + // creating ios test results + { + testsDir, err := pathutil.NormalizedOSTempDirPath("test") + if err != nil { + t.Fatal("failed to create temp dir, error:", err) + } + + testDir, err := ioutil.TempDir(testsDir, "test-result") + if err != nil { + t.Fatal("failed to create temp dir, error:", err) + } + + phaseDir, err := ioutil.TempDir(testDir, "phase") + if err != nil { + t.Fatal("failed to create temp dir, error:", err) + } + + if err := createDummyFilesInDirWithContent(testDir, `{"title": "test title"}`, []string{"step-info.json"}); err != nil { + t.Fatal("failed to create dummy files in dir, error:", err) + } + if err := createDummyFilesInDirWithContent(phaseDir, `{"name": "test name"}`, []string{"test-info.json"}); err != nil { + t.Fatal("failed to create dummy files in dir, error:", err) + } + if err := createDummyFilesInDirWithContent(phaseDir, sampleTestSummariesPlist, []string{"mytests.xcresult/TestSummaries.plist"}); err != nil { + t.Fatal("failed to create dummy files in dir, error:", err) + } + + bundle, err := ParseTestResults(testsDir) + if err != nil { + t.Fatal("failed to get bundle, error:", err) + } + + if len(bundle) != 1 { + t.Fatal("should be 1 test asset pack") + } + + if len(string(bundle[0].XMLContent)) != len(sampleIOSXmlOutput) { + t.Fatal("wrong xml content\n" + string(bundle[0].XMLContent) + "\n\n" + sampleIOSXmlOutput) + } + } +} diff --git a/test/testdata/ios_testsummaries_plist.golden b/test/testdata/ios_testsummaries_plist.golden new file mode 100644 index 00000000..edd70921 --- /dev/null +++ b/test/testdata/ios_testsummaries_plist.golden @@ -0,0 +1,13761 @@ + + + + + FormatVersion + 1.1 + TestableSummaries + + + DiagnosticsDirectory + BitriseAppTests-90929073-9D7B-4BA5-AA8A-9C093FF9E5EC + TargetName + BitriseAppTests + TestKind + app hosted + TestName + BitriseAppTests + TestObjectClass + IDESchemeActionTestableSummary + Tests + + + Duration + 0.00098705291748046875 + Subtests + + + Duration + 0.00019907951354980469 + Subtests + + TestIdentifier + BitriseAppTests.xctest + TestName + BitriseAppTests.xctest + TestObjectClass + IDESchemeActionTestSummaryGroup + + + TestIdentifier + All tests + TestName + All tests + TestObjectClass + IDESchemeActionTestSummaryGroup + + + + + DiagnosticsDirectory + BitriseAppUITests-0FB54876-9167-4BA7-93DC-CEBB2F34911E + TargetName + BitriseAppUITests + TestKind + UI + TestName + BitriseAppUITests + TestObjectClass + IDESchemeActionTestableSummary + Tests + + + Duration + 413.45300400257111 + Subtests + + + Duration + 413.45093405246735 + Subtests + + + Duration + 77.063832998275757 + Subtests + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708329.76741004 + StartTimeInterval + 570708329.62536299 + Title + Start Test at 2019-02-01 05:05:29.625 + UUID + E76C208C-B8D9-4378-B04F-ADDC5773136F + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708329.62536299 + StartTimeInterval + 570708329.62536299 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + E9F87604-3D7A-4DFA-A4A6-075B25F94623 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708329.77992904 + StartTimeInterval + 570708329.76825404 + Title + Set Up + UUID + 9D12B0A3-5723-49F3-879E-5E45625491A0 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708332.82244802 + StartTimeInterval + 570708329.79624498 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708332.821082 + StartTimeInterval + 570708329.81115305 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708331.76625204 + StartTimeInterval + 570708331.76179004 + Title + Wait for accessibility to load + UUID + 72ECE8B4-80C5-40C0-97F8-20F2B3BB9B35 + + + Title + Launch tv.Bitrise.BitriseApp + UUID + 62B56FF9-17E9-48B7-91CC-CA2C3AB999D4 + + + Title + Open tv.Bitrise.BitriseApp + UUID + B64890EA-59A7-46F6-9A75-6556D7B5A01B + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708336.07405603 + StartTimeInterval + 570708332.825611 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708333.92865896 + StartTimeInterval + 570708333.84516001 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + AB8D38F2-2DB5-4149-94F4-7992BE834CA7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708333.956321 + StartTimeInterval + 570708333.93289995 + Title + Find the "pidTextField" TextField + UUID + 034D5F69-FD30-4E51-B96C-539304670AF6 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708333.97793996 + StartTimeInterval + 570708333.96007395 + Title + Find the "pidTextField" TextField + UUID + 60EDF5A7-053A-4FAD-A525-A9ADB575A031 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708334.14007998 + StartTimeInterval + 570708333.98072898 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708334.00557494 + StartTimeInterval + 570708333.981547 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708334.00458598 + StartTimeInterval + 570708333.99821699 + Title + Check for interrupting elements affecting "pidTextField" TextField + UUID + 413AF114-BF7E-4AC2-8A38-49DB2B30B11C + + + Title + Find the "pidTextField" TextField + UUID + 48447A0E-62CB-40C2-A3D2-707C980914A5 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708334.13800704 + StartTimeInterval + 570708334.00673604 + Title + Synthesize event + UUID + C2E31B16-A56E-47FC-8D8A-75BE03D49D29 + + + Title + Tap "pidTextField" TextField + UUID + 2C2FF2DB-9772-41E1-B58A-8CA664384388 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708334.45091498 + StartTimeInterval + 570708334.14161301 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708334.30041897 + StartTimeInterval + 570708334.14270794 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708334.29947698 + StartTimeInterval + 570708334.29039395 + Title + Check for interrupting elements affecting "pidTextField" TextField + UUID + 0A2605A9-7D47-42DD-B449-B586D96C5100 + + + Title + Find the "pidTextField" TextField + UUID + 000E68A8-BAB9-4C94-BDDC-816916F4DEC1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708334.45032096 + StartTimeInterval + 570708334.30120301 + Title + Synthesize event + UUID + 002B2301-6EA6-4391-AE3E-1A95B96554BB + + + Title + Type '' into "pidTextField" TextField + UUID + A772242B-E011-48A0-AE70-8ADBC5749D37 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708334.61664796 + StartTimeInterval + 570708334.45126295 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708334.48784101 + StartTimeInterval + 570708334.45155895 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708334.48737204 + StartTimeInterval + 570708334.48126101 + Title + Check for interrupting elements affecting "pidTextField" TextField + UUID + 4A224725-C365-4C8B-82B9-593F6CBAA036 + + + Title + Find the "pidTextField" TextField + UUID + D600D049-9EC7-4FB3-8219-6BA0711DD240 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708334.61618102 + StartTimeInterval + 570708334.48826003 + Title + Synthesize event + UUID + F522F478-2229-45D3-A59C-D30FA399EA02 + + + Title + Type '12345' into "pidTextField" TextField + UUID + 9908930E-5ADF-4114-B95A-9FFDD42BF6FF + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708335.69353199 + StartTimeInterval + 570708335.645136 + Title + Checking Expect predicate exists == 1 for object "pid-keyboard-done-button" Button + UUID + 01416799-8722-49AC-B85C-3A61E6807413 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708335.84019399 + StartTimeInterval + 570708335.69508505 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708335.74184299 + StartTimeInterval + 570708335.69584894 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708335.74097002 + StartTimeInterval + 570708335.734326 + Title + Check for interrupting elements affecting "pid-keyboard-done-button" Button + UUID + CCF62D45-3A9D-48C3-9141-DC144A6E5BF4 + + + Title + Find the "pid-keyboard-done-button" Button + UUID + B20FDD28-081A-4105-BFF2-4E52AEBF6289 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708335.83857501 + StartTimeInterval + 570708335.742733 + Title + Synthesize event + UUID + 11EFEE3B-6C92-44FE-9185-0873A6C26B85 + + + Title + Tap "pid-keyboard-done-button" Button + UUID + 3587246E-0F3F-4142-8970-5C544DB98B7F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708335.94312799 + StartTimeInterval + 570708335.84148896 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708335.90115201 + StartTimeInterval + 570708335.84273601 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708335.90041304 + StartTimeInterval + 570708335.88992703 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + 2AF010A6-2920-4D45-B9C6-5CCB4B200923 + + + Title + Find the PickerWheel + UUID + 8F7AA276-7D46-4C6C-93D4-22F3148C352F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708335.94172895 + StartTimeInterval + 570708335.90190101 + Title + Synthesize event + UUID + 99145634-DB78-4D25-9A62-27C55F740359 + + + Title + Set value of PickerWheel to CollectionViewController + UUID + 76B7D6AF-212A-491F-971C-490198DEE5EF + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708336.07316601 + StartTimeInterval + 570708335.94375503 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708335.99216604 + StartTimeInterval + 570708335.944224 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708335.99185705 + StartTimeInterval + 570708335.98773396 + Title + Check for interrupting elements affecting "Load" Button + UUID + 320F8EDB-3564-4944-91E2-ED7129E292BD + + + Title + Find the "Load" Button + UUID + 2F025DE7-1F3A-44F1-80E1-C565AAF1A45E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708336.07177401 + StartTimeInterval + 570708335.99259698 + Title + Synthesize event + UUID + F21FE523-A01C-40D1-BB45-BB49B0AECE88 + + + Title + Tap "Load" Button + UUID + FB0728CF-CF09-4B3D-BC89-50CC07A06C61 + + + Title + I change the PID and tap on Load + UUID + 53CE1628-EDEF-40C1-8831-3794A760359D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708337.15897095 + StartTimeInterval + 570708337.10809004 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + 3C5E206C-DC0D-4460-82C8-9D660256677B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708337.30030501 + StartTimeInterval + 570708337.16025805 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708337.20939696 + StartTimeInterval + 570708337.16088104 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708337.20873594 + StartTimeInterval + 570708337.20328701 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + AE7AE9D5-EF12-42E2-BF4F-1DE2677FCA04 + + + Title + Find the "go-to-ad-button" Button + UUID + 1C3A7A0A-41F9-4C50-9F63-1187F2E5043F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708337.29907703 + StartTimeInterval + 570708337.21009803 + Title + Synthesize event + UUID + 61204D78-371C-42D9-B4C5-FD94841F5F53 + + + Title + Tap "go-to-ad-button" Button + UUID + 719363C3-F983-42E9-95BE-931006C0BA4B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708338.39726603 + StartTimeInterval + 570708337.30152595 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708338.39595497 + StartTimeInterval + 570708338.33475006 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + D3D84424-07F9-40C0-98BA-2319CDD290F2 + + + Title + Waiting 10.0s for "Bitrise-player" Other to exist + UUID + 0AA9C1B5-37FF-4497-B8D8-6CDC8D6DE500 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708344.97373199 + StartTimeInterval + 570708338.39845097 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708339.499596 + StartTimeInterval + 570708339.42855704 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 9255CCCF-9DF9-4FBD-BCBA-A7B3450D5D14 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708340.59819806 + StartTimeInterval + 570708340.52853405 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + C671D191-D96B-4516-BCED-3353C33E5908 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708341.69943798 + StartTimeInterval + 570708341.62859094 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 6511200D-56B8-4307-968F-215FCB7FA9A7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708342.78877199 + StartTimeInterval + 570708342.72598803 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + F757F17A-24A1-4419-B7BE-AC5A6DD56BC3 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708343.88654006 + StartTimeInterval + 570708343.81805801 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + B03EE03B-C5C1-4AF3-9FFA-960798A30779 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708344.97235703 + StartTimeInterval + 570708344.89212501 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + C0ED3D76-34DF-46C9-81BE-1575B08340DE + + + Title + Waiting 20.0s for "Bitrise-endScreenReplay" Other to exist + UUID + 7B023B3A-D610-444B-9297-46FFEEA16D87 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708345.120031 + StartTimeInterval + 570708344.97490001 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708345.02493203 + StartTimeInterval + 570708344.97579706 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708345.02403605 + StartTimeInterval + 570708345.01827705 + Title + Check for interrupting elements affecting "Bitrise App" Button + UUID + F94E02F2-E10D-45C7-8850-6C397E0900EB + + + Title + Find the "Bitrise App" Button + UUID + 4F8F3205-8BC7-4B05-8233-27E576C25276 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708345.11883998 + StartTimeInterval + 570708345.02686203 + Title + Synthesize event + UUID + 5202A21E-01CF-4699-9F29-4379F1CB7F45 + + + Title + Tap "Bitrise App" Button + UUID + D16326BE-50EF-437A-93EC-9CD3424BEFA2 + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708346.42460096 + StartTimeInterval + 570708345.12121296 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708346.22113299 + StartTimeInterval + 570708346.16156006 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + D96DFF28-7949-4A26-9533-2070B61F7C35 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708346.243402 + StartTimeInterval + 570708346.22246301 + Title + Find the "pidTextField" TextField + UUID + 61B486BF-F0DE-4D7F-A413-4402DE78385A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708346.30986905 + StartTimeInterval + 570708346.24427295 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708346.27693403 + StartTimeInterval + 570708346.24505603 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708346.27559495 + StartTimeInterval + 570708346.268785 + Title + Check for interrupting elements affecting "CollectionViewController" PickerWheel + UUID + A2CED6E0-3B66-4D65-A540-CACFDD2A581E + + + Title + Find the PickerWheel + UUID + 5B629624-37E8-49F1-823A-AFE063B32CCC + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708346.30837595 + StartTimeInterval + 570708346.27780795 + Title + Synthesize event + UUID + F58F0A39-C150-4855-9AAC-39B52A749CA3 + + + Title + Set value of PickerWheel to CollectionViewController + UUID + D6CA7BE5-C5FD-4E2D-B774-01E4E43C4228 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708346.42345703 + StartTimeInterval + 570708346.31069803 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708346.34314799 + StartTimeInterval + 570708346.31140697 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708346.34272897 + StartTimeInterval + 570708346.338153 + Title + Check for interrupting elements affecting "Load" Button + UUID + 0A46F647-1BB4-427F-B3BB-465AF780DD20 + + + Title + Find the "Load" Button + UUID + 6A6A77C3-9787-46C0-BB0D-FB8054BA4F09 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708346.42177606 + StartTimeInterval + 570708346.34356999 + Title + Synthesize event + UUID + 4D022FF2-010B-47F3-B984-3A608E2D9007 + + + Title + Tap "Load" Button + UUID + 436EE6C6-4F1D-45BD-A3C5-7A05375DEC21 + + + Title + I change the PID and tap on Load + UUID + 42B1DECC-9F73-4B98-BCD3-5440161D5572 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708347.53192604 + StartTimeInterval + 570708347.462677 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + 2FF9F68C-90D0-47F1-A871-ABF65B74CDC6 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708347.66673303 + StartTimeInterval + 570708347.53343296 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708347.57951295 + StartTimeInterval + 570708347.53407097 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708347.57876205 + StartTimeInterval + 570708347.57129502 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + 6573780D-4FA4-4651-9D08-D214149A3BAF + + + Title + Find the "go-to-ad-button" Button + UUID + 3704BBC0-B79C-40FD-A25E-2203B03DB182 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708347.66572106 + StartTimeInterval + 570708347.58027101 + Title + Synthesize event + UUID + C54DA501-57ED-4076-AA4E-DADFE96963AA + + + Title + Tap "go-to-ad-button" Button + UUID + 61B84D73-9571-4D3C-9616-B47BA1A2CC34 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708348.75053203 + StartTimeInterval + 570708347.66752899 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708348.74934995 + StartTimeInterval + 570708348.70939803 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + DE03B309-D02F-4FD4-A36D-2828A54A8032 + + + Title + Waiting 10.0s for "Bitrise-player" Other to exist + UUID + 4DE2D1DD-EA49-4241-A7F2-749322D3FD15 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708349.846421 + StartTimeInterval + 570708349.77562296 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + 612D822F-F6F3-4BAE-BCB1-90524B6FAA35 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708350.01258898 + StartTimeInterval + 570708349.84770501 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708349.89609396 + StartTimeInterval + 570708349.84837699 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708349.89534795 + StartTimeInterval + 570708349.88991404 + Title + Check for interrupting elements affecting "Bitrise-player" Other + UUID + 38B7E0B7-A363-4CA7-B368-803F640FA155 + + + Title + Find the "Bitrise-player" Other + UUID + 339A7F13-9B69-456E-9CDE-6C49AFEC50E0 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708350.01127803 + StartTimeInterval + 570708349.89677203 + Title + Synthesize event + UUID + FAAF9542-917B-428E-A89F-DB834B95AB19 + + + Title + Tap "Bitrise-player" Other + UUID + 8324D382-0A82-477F-B839-3E42894AE526 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708351.06672895 + StartTimeInterval + 570708351.05427206 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + 4D2305F8-0B2C-446C-BFE0-F5AA2BC2E92E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708351.179093 + StartTimeInterval + 570708351.06904697 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708351.09047902 + StartTimeInterval + 570708351.06983399 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708351.08965397 + StartTimeInterval + 570708351.08346403 + Title + Check for interrupting elements affecting "Bitrise-player" Other + UUID + 31DEF2DD-15AB-4B67-8EF2-28DD63CF2123 + + + Title + Find the "Bitrise-player" Other + UUID + C7537FC0-ADC2-4BB1-9BB9-58CBF8ABF040 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708351.17686403 + StartTimeInterval + 570708351.09123504 + Title + Synthesize event + UUID + E9591816-3C78-44A1-B49B-1A80437C2F02 + + + Title + Tap "Bitrise-player" Other + UUID + 4883893E-83D6-413A-BF3D-72D6D695B584 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708352.318578 + StartTimeInterval + 570708352.22577202 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708352.31308305 + StartTimeInterval + 570708352.28379905 + Title + Snapshot accessibility hierarchy for app with pid 3238 + UUID + 7CC968CA-83B9-4A61-A639-30C297D44A84 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708352.31599605 + StartTimeInterval + 570708352.31444299 + Title + Find: Descendants matching type Other + UUID + C8B3ADC6-5266-43F8-80E7-328779C5EDFC + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708352.31763995 + StartTimeInterval + 570708352.31673098 + Title + Find: Elements matching predicate '"safari-view" IN identifiers' + UUID + 4B87F087-B14B-4B54-8B2D-6AB83CE4C7E8 + + + Title + Checking Expect predicate exists == 1 for object "safari-view" Other + UUID + 1CB365AF-8D23-465D-AE07-1D55453B3BDE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708353.40032196 + StartTimeInterval + 570708352.32051003 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708353.39385998 + StartTimeInterval + 570708352.32380605 + Title + Terminate tv.Bitrise.BitriseApp:3238 + UUID + 377FFD89-E2DC-4505-8727-8C73C5EE901C + + + Title + Tear Down + UUID + 31C81E52-5EE1-424A-9385-E2799F01F536 + + + Duration + 23.776288986206055 + TestIdentifier + BitriseBasicUITest/testCollectionView() + TestName + testCollectionView() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + 9BAFD6A6-698B-4C6C-89BB-D76C9EC039A3 + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708353.433707 + StartTimeInterval + 570708353.40304196 + Title + Start Test at 2019-02-01 05:05:53.403 + UUID + 4B6EEFE4-8F98-4E89-9FE7-4CF37B4A186F + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708353.40304196 + StartTimeInterval + 570708353.40304196 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + 68A0D149-8C89-490C-A949-670527CD0411 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708353.43811095 + StartTimeInterval + 570708353.43591595 + Title + Set Up + UUID + 9B4318CA-C1EE-48F2-8053-70ED5D6BCEC9 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708356.61483002 + StartTimeInterval + 570708353.44396901 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708356.61345994 + StartTimeInterval + 570708353.47074604 + Title + Launch tv.Bitrise.BitriseApp + UUID + 999B4102-EAF4-417F-99DA-83961A8BDD6C + + + Title + Open tv.Bitrise.BitriseApp + UUID + 213A62D8-510D-4E63-A45B-8B5273DF772A + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708357.93597901 + StartTimeInterval + 570708356.61617506 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708357.70084298 + StartTimeInterval + 570708357.62485802 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 859B1BB2-3C46-4E4E-9159-71534CED3F87 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708357.728706 + StartTimeInterval + 570708357.70459402 + Title + Find the "pidTextField" TextField + UUID + 2EC097B0-522E-4E2B-8704-89003728891F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708357.80539 + StartTimeInterval + 570708357.72958803 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708357.75785398 + StartTimeInterval + 570708357.73038495 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708357.75711298 + StartTimeInterval + 570708357.75131202 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + 84C7DC7A-AC7C-44EB-B358-C38A431BA3DE + + + Title + Find the PickerWheel + UUID + DF410BE4-7D40-4A65-99C2-F3534EE42158 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708357.80467999 + StartTimeInterval + 570708357.76025498 + Title + Synthesize event + UUID + FCF3C948-B35D-4186-AB54-ADB513E69030 + + + Title + Set value of PickerWheel to InReadViewController + UUID + 066F2F67-F171-46D9-A740-2F1F429CD9F0 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708357.93526995 + StartTimeInterval + 570708357.80594504 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708357.84363103 + StartTimeInterval + 570708357.80637395 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708357.84304905 + StartTimeInterval + 570708357.83845305 + Title + Check for interrupting elements affecting "Load" Button + UUID + 9E0076A4-2390-481C-BDC2-949C75BCAF8B + + + Title + Find the "Load" Button + UUID + CF74EE1B-5B8A-498C-82F9-3E3C3A704EEE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708357.934026 + StartTimeInterval + 570708357.84414101 + Title + Synthesize event + UUID + 904ABDB0-58F9-4E03-9486-AD330F33AFBF + + + Title + Tap "Load" Button + UUID + E34117EA-9C14-4606-A24B-60C59E465C48 + + + Title + I change the PID and tap on Load + UUID + 2A2F06BE-7A3D-42D9-A94B-3859BD650268 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708358.98377299 + StartTimeInterval + 570708357.93685901 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708358.982602 + StartTimeInterval + 570708358.94347501 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + C1D14ADD-BC12-4078-9985-F78B9999CB88 + + + Title + Waiting 10.0s for "Bitrise-player" Other to exist + UUID + F60631FB-4342-484F-8C9E-72BA81C5FAA2 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708381.31224096 + StartTimeInterval + 570708358.98451304 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708360.04780495 + StartTimeInterval + 570708360.01695204 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 1304AC99-CE37-4D5F-9464-905161FE7D95 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708361.122015 + StartTimeInterval + 570708361.07738197 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 294694FB-1483-4881-BA3B-5624C410B23E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708362.20536697 + StartTimeInterval + 570708362.15821099 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 65C0E5ED-DFE6-4C86-A34F-E51EB4E726F2 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708363.287655 + StartTimeInterval + 570708363.24207401 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 33AA58BB-E814-42D1-A828-6B5C05F4C0C8 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708364.32922101 + StartTimeInterval + 570708364.30980897 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 4EB4B426-15B5-4DB2-A8EE-26188935C243 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708365.39537394 + StartTimeInterval + 570708365.35996497 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 96FAD73F-D984-4E81-87A1-F6EDA27238DB + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708366.44246495 + StartTimeInterval + 570708366.40999496 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 79F5CD36-D69F-4056-8D26-03AB04EB2402 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708367.49694896 + StartTimeInterval + 570708367.46011603 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + A8E0AA6C-FBF7-4DBE-9DA0-A9B9836EA5D5 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708368.54222095 + StartTimeInterval + 570708368.51004505 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + A0DEC257-0E3C-4965-8443-6E92618ED8A7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708369.61378598 + StartTimeInterval + 570708369.57794094 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + A3BD1C9C-529B-49B3-8766-6BA0CC900896 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708370.66214204 + StartTimeInterval + 570708370.62681794 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 7B5714E3-DAE4-447E-9AA7-6538C1924DFA + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708371.72923195 + StartTimeInterval + 570708371.69424903 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 18137ED8-4CAB-4A23-8F83-B5CCD5E35F7A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708372.77631199 + StartTimeInterval + 570708372.74362803 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 78F23DF1-E73E-4D1E-9256-AEB823876261 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708373.84542298 + StartTimeInterval + 570708373.803514 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 25E07F15-EB41-4205-9C95-2D1D4A9DC816 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708374.90442097 + StartTimeInterval + 570708374.86192405 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + C53D2360-73F0-4E35-A7C8-3CA3E167A770 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708375.97230506 + StartTimeInterval + 570708375.92728996 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + C080EDB9-C088-4BFE-888B-61117A80B08E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708377.03473997 + StartTimeInterval + 570708376.98575306 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 3BE671DE-B34C-408D-9C2B-9B7530FB8FC5 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708378.10255098 + StartTimeInterval + 570708378.05812895 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + EB11E01A-E051-42C8-977F-9B872A90722B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708379.17255604 + StartTimeInterval + 570708379.12748003 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 499AFEC9-A6D9-439C-A2EF-BBC5A185ABFE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708380.24250603 + StartTimeInterval + 570708380.19816697 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 44956587-3DB9-425C-8B01-683DD7171603 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708381.31039798 + StartTimeInterval + 570708381.26111495 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 52B765A0-6AC6-4B12-AD70-6CE446577DEB + + + Title + Waiting 50.0s for "Bitrise-endScreenReplay" Other to exist + UUID + 450B9259-0081-432C-B89B-CF6BE9C4D93F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708381.45106697 + StartTimeInterval + 570708381.31401706 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708381.35555601 + StartTimeInterval + 570708381.31502402 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708381.35477102 + StartTimeInterval + 570708381.34837401 + Title + Check for interrupting elements affecting "Bitrise App" Button + UUID + B19E4AF7-3941-4824-8022-9ACD0EC6C208 + + + Title + Find the "Bitrise App" Button + UUID + B32C3E9C-D4BE-4B65-B267-77712894BC3F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708381.44976604 + StartTimeInterval + 570708381.356516 + Title + Synthesize event + UUID + 0B2BF36D-B965-4C74-8739-B0973A64406C + + + Title + Tap "Bitrise App" Button + UUID + 24CDAC6D-84DB-46EA-B17B-7CEEBB2FB67C + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708382.73342597 + StartTimeInterval + 570708381.45220006 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708382.524032 + StartTimeInterval + 570708382.47267497 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 28B2EA40-431D-4DEE-9726-559A11DF122B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708382.54771304 + StartTimeInterval + 570708382.52586102 + Title + Find the "pidTextField" TextField + UUID + 3B0FCD6E-1861-4742-AE88-21B13B114FC2 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708382.61609805 + StartTimeInterval + 570708382.54876101 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708382.58462298 + StartTimeInterval + 570708382.54946697 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708382.583534 + StartTimeInterval + 570708382.57603002 + Title + Check for interrupting elements affecting "InReadViewController" PickerWheel + UUID + 70B58EBD-A9B2-437C-9E0A-A54C086CFC3E + + + Title + Find the PickerWheel + UUID + E40FE67E-2E34-4F3E-9C0C-2B8708EE48E4 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708382.61531699 + StartTimeInterval + 570708382.585549 + Title + Synthesize event + UUID + F8ADBB47-8416-4823-9267-FBFDD0F70BE6 + + + Title + Set value of PickerWheel to InReadViewController + UUID + 9CD94794-67A8-4656-8F90-3E75B1446C5F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708382.73192596 + StartTimeInterval + 570708382.61700797 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708382.64859903 + StartTimeInterval + 570708382.61767602 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708382.64818704 + StartTimeInterval + 570708382.64385295 + Title + Check for interrupting elements affecting "Load" Button + UUID + 17A8C4EC-8230-4B55-B6E7-4A63A3044D94 + + + Title + Find the "Load" Button + UUID + A4AB3338-367B-43F4-87A0-EFA4F569D534 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708382.72855103 + StartTimeInterval + 570708382.64909601 + Title + Synthesize event + UUID + 13F2D453-DE68-47A9-8D9A-65BD57CEF484 + + + Title + Tap "Load" Button + UUID + 620AF8C4-F195-4954-87DD-4E28412A57BC + + + Title + I change the PID and tap on Load + UUID + CDFF481B-2E46-4FBA-8E98-D23BD9EB8161 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708383.78185105 + StartTimeInterval + 570708382.734671 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708383.78001595 + StartTimeInterval + 570708383.76228797 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + B8E08CFA-38B8-4135-ACC5-6A7005FADE22 + + + Title + Waiting 10.0s for "Bitrise-player" Other to exist + UUID + F666ECCA-ACE5-4E18-AFB1-6B0EF7BFDDB1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708384.85601401 + StartTimeInterval + 570708384.81262803 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + EC5ADB24-6D3E-4E77-BFCA-BC85142BAB6E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708384.99089599 + StartTimeInterval + 570708384.85743499 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708384.89260101 + StartTimeInterval + 570708384.85823905 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708384.89183497 + StartTimeInterval + 570708384.88574195 + Title + Check for interrupting elements affecting "Bitrise-player" Other + UUID + 1DDEC853-3493-4B9F-BCFC-CCC85649577B + + + Title + Find the "Bitrise-player" Other + UUID + 048A4228-B16C-473D-B7CF-324D65949243 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708384.98902404 + StartTimeInterval + 570708384.89336503 + Title + Synthesize event + UUID + D0E3193A-08C7-4550-BEA1-0BF846F44F4B + + + Title + Tap "Bitrise-player" Other + UUID + 9EB0FF84-DA3E-472E-A96A-C4422D344913 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708386.04250598 + StartTimeInterval + 570708386.02770102 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + C4C540E1-2448-48DB-9E88-0742B9896415 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708386.156739 + StartTimeInterval + 570708386.04403496 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708386.07026803 + StartTimeInterval + 570708386.04643297 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708386.06952596 + StartTimeInterval + 570708386.06271398 + Title + Check for interrupting elements affecting "Bitrise-player" Other + UUID + 79F312B8-3E0B-44F1-B26A-5280F8A839DF + + + Title + Find the "Bitrise-player" Other + UUID + B61A9633-C1B3-4E41-98E5-D2FD3A8F5D79 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708386.15458095 + StartTimeInterval + 570708386.07103801 + Title + Synthesize event + UUID + 8DB2BCD8-F2A0-4D2E-8EE5-9FA3C8FF4DE3 + + + Title + Tap "Bitrise-player" Other + UUID + E165A614-3A77-46D1-BFDE-8F54131D4C8C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708387.34019697 + StartTimeInterval + 570708387.20628905 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708387.33446598 + StartTimeInterval + 570708387.293769 + Title + Snapshot accessibility hierarchy for app with pid 3365 + UUID + F2AB8854-2D11-4792-8211-3416FFAA8B1D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708387.33687603 + StartTimeInterval + 570708387.33594704 + Title + Find: Descendants matching type Other + UUID + FE254160-8FC8-4522-96EF-6EF98630A75B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708387.33912206 + StartTimeInterval + 570708387.33819997 + Title + Find: Elements matching predicate '"safari-view" IN identifiers' + UUID + 64464152-5A60-43D8-A0AA-11CF0C35BE8B + + + Title + Checking Expect predicate exists == 1 for object "safari-view" Other + UUID + 775788C5-F4ED-425C-A326-B83163B30726 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708388.37741101 + StartTimeInterval + 570708387.34290898 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708388.37558103 + StartTimeInterval + 570708387.34380901 + Title + Terminate tv.Bitrise.BitriseApp:3365 + UUID + DC3C797F-2B35-4D76-B910-5F9E245ECC7E + + + Title + Tear Down + UUID + BCE19C8F-C41B-4AA8-AA21-06B1440B1588 + + + Duration + 34.976288914680481 + TestIdentifier + BitriseBasicUITest/testInReadTopView() + TestName + testInReadTopView() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + 0F781816-86A1-45D2-902E-6C2467B0E287 + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708388.41039801 + StartTimeInterval + 570708388.37965405 + Title + Start Test at 2019-02-01 05:06:28.380 + UUID + CD4FE42D-21F5-4687-9FC8-647AD1DE581F + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708388.37965405 + StartTimeInterval + 570708388.37965405 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + 33B62218-04ED-4EE9-84CF-32F515C46243 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708388.41460598 + StartTimeInterval + 570708388.41245103 + Title + Set Up + UUID + 019A9B7F-61B0-4F8E-BD61-3ED2F84AAA93 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708391.57298505 + StartTimeInterval + 570708388.42003405 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708391.56965995 + StartTimeInterval + 570708388.44546402 + Title + Launch tv.Bitrise.BitriseApp + UUID + 24EE31CF-38EC-4E43-93A8-627B713264D7 + + + Title + Open tv.Bitrise.BitriseApp + UUID + A1C350B7-55D3-4E3B-A729-7D83C3848478 + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708392.90139699 + StartTimeInterval + 570708391.57635796 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708392.66622603 + StartTimeInterval + 570708392.59572196 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 22BEAF67-C287-4368-A06B-F7E68A2CD649 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708392.68776703 + StartTimeInterval + 570708392.66781795 + Title + Find the "pidTextField" TextField + UUID + 5CD58253-B6A5-4274-B7F2-6C6DC8F456E7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708392.76396406 + StartTimeInterval + 570708392.68905103 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708392.720281 + StartTimeInterval + 570708392.68978202 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708392.71833503 + StartTimeInterval + 570708392.71139896 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + 899EBF67-1DF6-4CB3-AAD1-890DA4E55896 + + + Title + Find the PickerWheel + UUID + 7AC983C9-6425-4373-B868-D07DD5424487 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708392.76284599 + StartTimeInterval + 570708392.72202599 + Title + Synthesize event + UUID + B2AB2307-7EFA-48EF-B389-91FB92DC0E9F + + + Title + Set value of PickerWheel to InterstitialViewController + UUID + 0717D8FD-83C5-459D-AE41-349545646CA3 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708392.90050197 + StartTimeInterval + 570708392.764938 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708392.80794096 + StartTimeInterval + 570708392.76545894 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708392.80723798 + StartTimeInterval + 570708392.80142105 + Title + Check for interrupting elements affecting "Load" Button + UUID + 0BE60D05-9604-4F14-90EA-E95AFF7A5CA2 + + + Title + Find the "Load" Button + UUID + E37D08F2-028E-4DAC-8B39-FD68C069BBAF + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708392.89895797 + StartTimeInterval + 570708392.80869699 + Title + Synthesize event + UUID + 18F464A7-04FF-4888-A72C-53D5FC2FDE90 + + + Title + Tap "Load" Button + UUID + BD9BFC5C-5CAC-4725-9634-39CF19ACE68E + + + Title + I change the PID and tap on Load + UUID + FD7CCBB6-B26D-4B31-B2A3-7D8B2EE24B0A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708393.97291195 + StartTimeInterval + 570708393.93050504 + Title + Checking Expect predicate exists == 1 for object "interstitial-show" Button + UUID + 25F7973E-8E2A-4F3C-8163-C1AFE0F9E16C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708394.10966396 + StartTimeInterval + 570708393.97814202 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708394.01325595 + StartTimeInterval + 570708393.98011994 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708394.01185 + StartTimeInterval + 570708394.00175798 + Title + Check for interrupting elements affecting "interstitial-show" Button + UUID + 709B3E4E-0316-4C4C-B2BB-0D47C66171FF + + + Title + Find the "interstitial-show" Button + UUID + 5ED8A15A-3E04-4EF9-862D-FE45FC21B2E7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708394.10687602 + StartTimeInterval + 570708394.01451898 + Title + Synthesize event + UUID + 80E8FC2A-EBA6-4F57-AE40-7C284DBA7B4A + + + Title + Tap "interstitial-show" Button + UUID + B4220FF0-0637-45B9-A6C0-880439EB95D3 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708395.17686296 + StartTimeInterval + 570708394.11149895 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708395.17544496 + StartTimeInterval + 570708395.13061297 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + E88BDC14-FC50-4E3B-A19F-2150AED6C675 + + + Title + Waiting 10.0s for "Bitrise-player" Other to exist + UUID + 4331A4E9-B281-4AB1-A9E2-D2CDE32061E0 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708396.23254001 + StartTimeInterval + 570708396.20053101 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + BB8FF6A5-ABE9-48CD-912D-1FFBD9890ED7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708396.37337196 + StartTimeInterval + 570708396.23561704 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708396.27825606 + StartTimeInterval + 570708396.23644197 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708396.27667296 + StartTimeInterval + 570708396.26671803 + Title + Check for interrupting elements affecting "Bitrise-player" Other + UUID + D54D211B-7700-437F-8308-25A6B5C2723F + + + Title + Find the "Bitrise-player" Other + UUID + 2A59DCF8-05EC-421D-BDF5-0B5A1BA5DE4F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708396.37103999 + StartTimeInterval + 570708396.28004396 + Title + Synthesize event + UUID + 933C2821-6CAB-488D-8DB8-88CA0AD56C92 + + + Title + Tap "Bitrise-player" Other + UUID + C3A1A57B-A267-498C-89C5-0AFE11842334 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708397.52970195 + StartTimeInterval + 570708397.40118206 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708397.52150095 + StartTimeInterval + 570708397.485497 + Title + Snapshot accessibility hierarchy for app with pid 3473 + UUID + BD8EEDFD-1A84-450D-893C-D620EDDA6EAB + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708397.52313697 + StartTimeInterval + 570708397.52237797 + Title + Find: Descendants matching type Other + UUID + CEC999D0-D3A5-4A34-80AF-5F6994804A65 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708397.52755797 + StartTimeInterval + 570708397.52393603 + Title + Find: Elements matching predicate '"safari-view" IN identifiers' + UUID + 6C62C308-1228-449A-9C44-4147555D08EE + + + Title + Checking Expect predicate exists == 1 for object "safari-view" Other + UUID + 631AE4A1-342F-4AFB-AAC2-0FC9FA01781F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708398.64847505 + StartTimeInterval + 570708397.53431702 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708398.64621198 + StartTimeInterval + 570708397.53530204 + Title + Terminate tv.Bitrise.BitriseApp:3473 + UUID + A074426A-0C5C-40FA-9EF6-8315EDA459B9 + + + Title + Tear Down + UUID + 8037F101-76B1-4EEC-80FF-E341DABE0F38 + + + Duration + 10.270301938056946 + TestIdentifier + BitriseBasicUITest/testInterstitialView() + TestName + testInterstitialView() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + F6537461-5098-4B6B-B1FD-C10AF399A262 + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708398.68026602 + StartTimeInterval + 570708398.65065706 + Title + Start Test at 2019-02-01 05:06:38.651 + UUID + 3A0FEFAB-237F-4E3D-B805-DBAE29C961AA + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708398.65065706 + StartTimeInterval + 570708398.65065706 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + 815A6D7E-05C5-4AC3-B7CB-1A0DB9A75317 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708398.68415403 + StartTimeInterval + 570708398.68218899 + Title + Set Up + UUID + 699393AA-3E80-42BA-A2E2-11DC63A05354 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708402.06018102 + StartTimeInterval + 570708398.68864202 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708402.05657494 + StartTimeInterval + 570708398.71793902 + Title + Launch tv.Bitrise.BitriseApp + UUID + E8F0C729-35BB-45C8-9949-C2810C61A0D3 + + + Title + Open tv.Bitrise.BitriseApp + UUID + 95C281AF-265E-4800-BBB5-B3334F97D00E + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708403.35460198 + StartTimeInterval + 570708402.06359398 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708403.160905 + StartTimeInterval + 570708403.08392298 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 837431A5-5CEA-43E3-8E81-0477CF656565 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708403.18482804 + StartTimeInterval + 570708403.16744101 + Title + Find the "pidTextField" TextField + UUID + C57B2782-90FE-4EC4-BF3B-8605AF441992 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708403.24811697 + StartTimeInterval + 570708403.18576002 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708403.21130204 + StartTimeInterval + 570708403.18644905 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708403.21000302 + StartTimeInterval + 570708403.20436502 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + 98A0FE33-B66E-422C-912B-879E121AE1EE + + + Title + Find the PickerWheel + UUID + 708BAE18-7EAC-4455-B6E6-16686396A453 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708403.24759996 + StartTimeInterval + 570708403.21246195 + Title + Synthesize event + UUID + B00F7738-B073-41D2-9008-B4D551BBD19D + + + Title + Set value of PickerWheel to RewardedViewController + UUID + E11F32AE-498B-480C-AC51-9D878D4EB8E2 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708403.35368097 + StartTimeInterval + 570708403.24856496 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708403.27055597 + StartTimeInterval + 570708403.24887097 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708403.27028596 + StartTimeInterval + 570708403.26676595 + Title + Check for interrupting elements affecting "Load" Button + UUID + 6DFEF2B5-28A3-41AA-896E-ADF01AD1096F + + + Title + Find the "Load" Button + UUID + 31EA11B1-4D27-4C0F-AC80-4012E136DF93 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708403.35152304 + StartTimeInterval + 570708403.27086306 + Title + Synthesize event + UUID + 2187C2CE-9C12-403B-9FA1-7D553ACF40DE + + + Title + Tap "Load" Button + UUID + 50D2CB4A-5D42-46F6-AB76-1A438779EDEA + + + Title + I change the PID and tap on Load + UUID + 0D4B71B4-C363-40A0-BB86-4FC3A27E8213 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708404.41108406 + StartTimeInterval + 570708404.38383698 + Title + Checking Expect predicate exists == 1 for object "rewarded-show" Button + UUID + 980E876A-7F4C-4A17-A66F-615FE0797725 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708404.52816999 + StartTimeInterval + 570708404.41306901 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708404.43869901 + StartTimeInterval + 570708404.41416895 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708404.43809199 + StartTimeInterval + 570708404.43114805 + Title + Check for interrupting elements affecting "rewarded-show" Button + UUID + 83B2B064-66E5-4763-8F97-E2FC79CB195A + + + Title + Find the "rewarded-show" Button + UUID + 55351140-35AF-4459-883B-5869DBBFBFD1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708404.525738 + StartTimeInterval + 570708404.43975103 + Title + Synthesize event + UUID + E656EDDF-2B68-48D0-B3A4-367992E65124 + + + Title + Tap "rewarded-show" Button + UUID + 9A1068D0-4920-4514-B31B-15B2873A6FEE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708405.58990395 + StartTimeInterval + 570708404.53006303 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708405.58727503 + StartTimeInterval + 570708405.55151498 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + 1AECB40E-299A-4482-B5CB-DD9D9291E887 + + + Title + Waiting 10.0s for "Bitrise-player" Other to exist + UUID + 5D1A009A-3DDC-4EA5-8D48-D33BB7B95130 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708406.68713105 + StartTimeInterval + 570708405.59175599 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708406.68522298 + StartTimeInterval + 570708405.59282601 + Title + Terminate tv.Bitrise.BitriseApp:3498 + UUID + 345029A3-E1A3-4BAA-965A-2D61926E4562 + + + Title + Tear Down + UUID + 00151481-8B0A-49BA-A3A2-DDAC03C61805 + + + Duration + 8.0379880666732788 + TestIdentifier + BitriseBasicUITest/testRewardView() + TestName + testRewardView() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + 09773AC2-07A0-46F5-B8BC-F53EEAAA7AC8 + + + TestIdentifier + BitriseBasicUITest + TestName + BitriseBasicUITest + TestObjectClass + IDESchemeActionTestSummaryGroup + + + Duration + 40.588476061820984 + Subtests + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708406.72200894 + StartTimeInterval + 570708406.69154799 + Title + Start Test at 2019-02-01 05:06:46.691 + UUID + B6947BA2-E1B1-4797-AB37-9347002EAB73 + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708406.69154799 + StartTimeInterval + 570708406.69154799 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + FB5EFAD2-FBD5-4BE6-97A1-6BFE6C3F0627 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708406.75537801 + StartTimeInterval + 570708406.723809 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708406.75449705 + StartTimeInterval + 570708406.72670698 + Title + Terminate tv.Bitrise.BitriseApp:0 + UUID + A4B02EA0-D609-4126-8CD5-75C63316C971 + + + Title + Set Up + UUID + 0960E635-55E8-4ED3-B1C7-53F5F35A1385 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708410.26361406 + StartTimeInterval + 570708406.75956202 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708410.261235 + StartTimeInterval + 570708406.77951097 + Title + Launch tv.Bitrise.BitriseApp + UUID + 03BD0512-DFBF-4A82-ABA8-E1517BC7507D + + + Title + Open tv.Bitrise.BitriseApp + UUID + CEFE99CE-B1FB-4D0D-977A-1992FE2C1F76 + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708411.564502 + StartTimeInterval + 570708410.26534104 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708411.36080897 + StartTimeInterval + 570708411.28387105 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 44313FF4-73A1-4615-99CB-A8AEDE26D71C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708411.38145995 + StartTimeInterval + 570708411.36211503 + Title + Find the "pidTextField" TextField + UUID + 5DBEB41A-D526-4ACC-89DF-653652094BD0 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708411.44484103 + StartTimeInterval + 570708411.38277698 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708411.414132 + StartTimeInterval + 570708411.38370705 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708411.41226995 + StartTimeInterval + 570708411.40535402 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + 1D9125CA-14B8-4FDD-B779-85D0D80A181C + + + Title + Find the PickerWheel + UUID + 830EB531-AA78-4FAF-8ADE-278E8B998444 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708411.44423199 + StartTimeInterval + 570708411.41518199 + Title + Synthesize event + UUID + 8A4B48C2-DE84-40AC-98AE-BC3EC54E6CB8 + + + Title + Set value of PickerWheel to ScrollViewController + UUID + 88F4A897-B005-4BDA-82C2-6456AFCBF7D4 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708411.56363106 + StartTimeInterval + 570708411.44535995 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708411.47372305 + StartTimeInterval + 570708411.44576001 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708411.47319305 + StartTimeInterval + 570708411.46892703 + Title + Check for interrupting elements affecting "Load" Button + UUID + 298323E1-591A-4818-B730-A2E2C4EE9041 + + + Title + Find the "Load" Button + UUID + AE0ED95D-32BC-4CEF-BCFC-9FCA191746FB + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708411.56164396 + StartTimeInterval + 570708411.47417104 + Title + Synthesize event + UUID + 04CE2168-FE95-40CE-B28B-AEF3F9700A10 + + + Title + Tap "Load" Button + UUID + 2D7E6130-F277-47BA-B9DF-649D6CA9A8AD + + + Title + I change the PID and tap on Load + UUID + 738F5E6B-876A-44C1-9753-8F4948995008 + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708416.57517004 + StartTimeInterval + 570708413.57064199 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708414.65593398 + StartTimeInterval + 570708414.63346195 + Title + Find the "Bitrise-player" Other + UUID + 754BDDB8-4FD2-43B1-9282-BEC5312AADBF + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708414.67449903 + StartTimeInterval + 570708414.65936995 + Title + Find the Window + UUID + 89846544-9D1E-4E7F-A53E-FA0D4565C6AF + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708414.69940305 + StartTimeInterval + 570708414.68112504 + Title + Find the "Bitrise-player" Other + UUID + A5085884-6EE0-4A21-AE61-7115C9718670 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708414.99889803 + StartTimeInterval + 570708414.70360196 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708414.73788702 + StartTimeInterval + 570708414.70427299 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708414.73680902 + StartTimeInterval + 570708414.72698998 + Title + Check for interrupting elements affecting ScrollView + UUID + 55819DA6-2944-4689-8514-31F9C27542AF + + + Title + Find the ScrollView + UUID + CD4F17C0-514C-43EA-ACEF-17558646FF42 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708414.99340606 + StartTimeInterval + 570708414.73904896 + Title + Synthesize event + UUID + 953B79E1-6158-403B-B3EA-6A705AB8389A + + + Title + Swipe up ScrollView + UUID + BFEE80D9-76AB-4053-978C-C6BDF0494386 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708415.07562697 + StartTimeInterval + 570708415.05033696 + Title + Find the "Bitrise-player" Other + UUID + 68BBD286-88BC-4879-B6E3-A33F9DF3037C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708415.09715295 + StartTimeInterval + 570708415.07939601 + Title + Find the Window + UUID + 778335FE-A787-4067-BF0E-B89AFFF3DF09 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708415.12526095 + StartTimeInterval + 570708415.10391605 + Title + Find the "Bitrise-player" Other + UUID + EE9C206F-C9BD-4DC1-9BAA-625A2B74EF88 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708415.41403794 + StartTimeInterval + 570708415.12803602 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708415.16154695 + StartTimeInterval + 570708415.12890995 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708415.16095102 + StartTimeInterval + 570708415.15469003 + Title + Check for interrupting elements affecting ScrollView + UUID + 1242B600-3775-492E-98F2-1823D11E86ED + + + Title + Find the ScrollView at {{0.0, 44.0}, {375.0, 623.0}} + UUID + E25CB72C-7F6B-41DF-AE76-D9BBE7855CC0 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708415.41021204 + StartTimeInterval + 570708415.16260898 + Title + Synthesize event + UUID + 9DF242CA-1B76-4D54-82AB-EC7A7493F8E5 + + + Title + Swipe up ScrollView at {{0.0, 44.0}, {375.0, 623.0}} + UUID + 0327F7C9-1D91-4586-9D0A-64339BCD3DAD + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708415.47753894 + StartTimeInterval + 570708415.45353198 + Title + Find the "Bitrise-player" Other + UUID + A94FA416-3540-4CBE-9DE5-F9E5682F43E4 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708415.49829102 + StartTimeInterval + 570708415.48117995 + Title + Find the Window + UUID + 9ABFC607-B846-4711-AC34-4E42E89E1C9F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708415.52570796 + StartTimeInterval + 570708415.50432205 + Title + Find the "Bitrise-player" Other + UUID + 75F13643-C247-408F-9199-D4538341C690 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708416.57439101 + StartTimeInterval + 570708415.52855504 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708416.57241201 + StartTimeInterval + 570708416.53400505 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + 7CF818C5-6887-4D9F-87D3-CCE29445FAE9 + + + Title + Waiting 10.0s for "Bitrise-player" Other to exist + UUID + F347A688-325A-48B4-88A6-6B6CEC7CFECF + + + Title + I scroll demo page and wait for player to be displayed + UUID + 740A63A8-E299-4F7F-B3F9-B3148D1E89F4 + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708421.73509896 + StartTimeInterval + 570708416.57694495 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708416.72861695 + StartTimeInterval + 570708416.579633 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708416.62574995 + StartTimeInterval + 570708416.58045304 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708416.624946 + StartTimeInterval + 570708416.61757898 + Title + Check for interrupting elements affecting "Bitrise App" Button + UUID + 9BE73C9D-21D7-4A5F-9544-E6F4D71FCF46 + + + Title + Find the "Bitrise App" Button + UUID + 8D74850E-D283-44B6-979F-2C0AEF4BCF0F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708416.726125 + StartTimeInterval + 570708416.626495 + Title + Synthesize event + UUID + 8562D9FA-589D-4363-995C-A8F008A49B91 + + + Title + Tap "Bitrise App" Button + UUID + AA5E5A0D-4CC0-4A11-BB04-8D4996CC5E02 + + + Title + I go back to main screen and wait 5 seconds + UUID + 98E76050-2217-4562-BFDC-6B5674BA16F3 + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708435.73321497 + StartTimeInterval + 570708421.74355698 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708421.84691 + StartTimeInterval + 570708421.74616396 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708421.80897498 + StartTimeInterval + 570708421.74835205 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708421.80778301 + StartTimeInterval + 570708421.80044103 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + 7F836742-EAAD-4D32-8762-40326C3EB879 + + + Title + Find the PickerWheel + UUID + BB29F6FA-2BD8-4F88-8305-691373E977ED + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708421.84577096 + StartTimeInterval + 570708421.81023705 + Title + Synthesize event + UUID + B39CCD68-2194-4DB6-B9EE-2C14CB9A09A5 + + + Title + Set value of PickerWheel to ScrollViewController + UUID + BC232F8A-9E1A-4742-806B-7B33132AABC0 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708421.98562503 + StartTimeInterval + 570708421.84773695 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708421.89536202 + StartTimeInterval + 570708421.84833205 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708421.89431906 + StartTimeInterval + 570708421.88728201 + Title + Check for interrupting elements affecting "Load" Button + UUID + 669189F0-608A-43BC-9AD9-820AFDADAE31 + + + Title + Find the "Load" Button + UUID + 128F81AE-2B2E-4751-BFB7-4F1ABF1C548B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708421.98368096 + StartTimeInterval + 570708421.89652896 + Title + Synthesize event + UUID + C85AE593-A3B4-442F-8A9A-21BDD49A0EBB + + + Title + Tap "Load" Button + UUID + C60CF70F-625D-4E0D-8831-51DBEDC3F897 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708424.33052194 + StartTimeInterval + 570708424.02776897 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708424.067554 + StartTimeInterval + 570708424.02895105 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708424.06648803 + StartTimeInterval + 570708424.05816805 + Title + Check for interrupting elements affecting ScrollView + UUID + 12D8BECB-20E0-414D-ADA4-20F93B611864 + + + Title + Find the ScrollView + UUID + C14AFA5F-D4F6-44EB-A376-C1DBC57B65F8 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708424.32657301 + StartTimeInterval + 570708424.06845999 + Title + Synthesize event + UUID + 3402AE6F-5010-4F70-846F-06987D569B77 + + + Title + Swipe up ScrollView + UUID + 392830B9-5B07-47F0-8EE9-41498EBF9078 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708424.671978 + StartTimeInterval + 570708424.366642 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708424.40920603 + StartTimeInterval + 570708424.36823702 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708424.40840995 + StartTimeInterval + 570708424.40125597 + Title + Check for interrupting elements affecting ScrollView + UUID + FDFEC6B6-FE8D-4397-A118-D681492E8670 + + + Title + Find the ScrollView at {{0.0, 44.0}, {375.0, 623.0}} + UUID + 261510F0-6AA6-4B31-A817-5D0BC652DA1A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708424.66940498 + StartTimeInterval + 570708424.40995002 + Title + Synthesize event + UUID + 6FEAA938-1358-46C5-A576-05FDB0DB7E05 + + + Title + Swipe up ScrollView at {{0.0, 44.0}, {375.0, 623.0}} + UUID + 1488FE74-7108-4373-84A2-43327B79C94A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708425.00366402 + StartTimeInterval + 570708424.697173 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708424.74485803 + StartTimeInterval + 570708424.69803905 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708424.74408495 + StartTimeInterval + 570708424.73649204 + Title + Check for interrupting elements affecting ScrollView + UUID + 9CD72143-C5D3-44D8-881F-F35AD2D3D52E + + + Title + Find the ScrollView at {{0.0, 44.0}, {375.0, 623.0}} + UUID + E66C7093-4C79-43B6-A7F0-6D126BDF4815 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708425.00029695 + StartTimeInterval + 570708424.74574006 + Title + Synthesize event + UUID + 2A82369F-FEA7-4C18-B3F7-31A8C52AB415 + + + Title + Swipe up ScrollView at {{0.0, 44.0}, {375.0, 623.0}} + UUID + A725859D-1326-4A23-B708-89F3BD6E8B94 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708425.34060705 + StartTimeInterval + 570708425.04018605 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708425.07618701 + StartTimeInterval + 570708425.04119301 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708425.07513201 + StartTimeInterval + 570708425.06857896 + Title + Check for interrupting elements affecting ScrollView + UUID + DA699871-A4B6-4D95-9FA5-73D62DE9D26E + + + Title + Find the ScrollView at {{0.0, 44.0}, {375.0, 623.0}} + UUID + 9314B5F6-2A38-44CC-905B-74C2BD8F4CE9 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708425.33757496 + StartTimeInterval + 570708425.07713795 + Title + Synthesize event + UUID + 882BF6F6-5CEC-4579-B794-B8BE5056CF6E + + + Title + Swipe up ScrollView at {{0.0, 44.0}, {375.0, 623.0}} + UUID + 2B64DD14-F35B-435B-AA67-8048BB6F3C08 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708425.67300296 + StartTimeInterval + 570708425.36825502 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708425.41856301 + StartTimeInterval + 570708425.36934602 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708425.41736305 + StartTimeInterval + 570708425.40703499 + Title + Check for interrupting elements affecting ScrollView + UUID + 1A88F7AD-153F-445D-809E-70BB5AE47473 + + + Title + Find the ScrollView at {{0.0, 44.0}, {375.0, 623.0}} + UUID + 83DF8E9E-958D-4799-B3F4-DDCA9581309E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708425.670331 + StartTimeInterval + 570708425.41955101 + Title + Synthesize event + UUID + 882EBD58-C8BF-4100-B6DA-469345FD10AA + + + Title + Swipe up ScrollView at {{0.0, 44.0}, {375.0, 623.0}} + UUID + D7A4A712-9976-4D21-BCA8-8896C2D7EF31 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708435.70741796 + StartTimeInterval + 570708425.70039296 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708426.75972402 + StartTimeInterval + 570708426.73014498 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + 94FFE596-81D7-4B62-BC20-E244AE81925B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708427.80295801 + StartTimeInterval + 570708427.76232398 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + 5F0BC823-594C-4E1A-8E63-88D8D6CC3C3F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708428.85055602 + StartTimeInterval + 570708428.81138206 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + 51B0E599-E04E-4BAF-AA80-40177860CBD1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708429.90297306 + StartTimeInterval + 570708429.86229599 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + E3CCD830-1440-411F-A630-DEEBD90C801E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708430.95087898 + StartTimeInterval + 570708430.91228902 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + 46E9E9E3-DF87-4566-B799-C6BB0F0EFB42 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708432.00147796 + StartTimeInterval + 570708431.96230495 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + 48E5B4A2-EEB3-41E7-AD3F-52B211D3DBCF + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708433.05204701 + StartTimeInterval + 570708433.01231205 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + B5B2AA80-B16B-465F-8823-F48F258CBF0C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708434.10095 + StartTimeInterval + 570708434.06228399 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + 709155D2-321B-4B28-A466-0FCA628E0617 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708435.15085101 + StartTimeInterval + 570708435.11229002 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + BBD2BD62-3990-4E3A-8BFD-259D916BE7D8 + + + Title + Waiting 10.0s for "Bitrise-player" Other to exist + UUID + FA035182-D1FE-491B-8131-5A666A13E746 + + + Title + I go again to demo page and expect NO player + UUID + A431C014-204C-4C75-9E04-DFB553DABB78 + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708440.89873004 + StartTimeInterval + 570708435.73544502 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708435.89207995 + StartTimeInterval + 570708435.73837304 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708435.78655696 + StartTimeInterval + 570708435.73958194 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708435.78536701 + StartTimeInterval + 570708435.77823305 + Title + Check for interrupting elements affecting "Bitrise App" Button + UUID + D85DC277-1C89-45C5-AD3B-23304862133D + + + Title + Find the "Bitrise App" Button + UUID + 9088D5E3-15FB-4ED2-80F9-587B1F1C18BF + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708435.88869596 + StartTimeInterval + 570708435.78763795 + Title + Synthesize event + UUID + D594945C-40C1-47EF-970D-F614822F7B97 + + + Title + Tap "Bitrise App" Button + UUID + A4F9BBEB-4BD4-43E3-BC44-6C5193362DE5 + + + Title + I go back to main screen and wait 5 seconds + UUID + 83AA2536-1755-4518-95D4-E1468639D11D + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708446.18685102 + StartTimeInterval + 570708440.90150797 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708441.00659204 + StartTimeInterval + 570708440.90439606 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708440.96850097 + StartTimeInterval + 570708440.90680802 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708440.96758103 + StartTimeInterval + 570708440.959988 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + ADB4E8FB-63FC-4C66-B7BE-B27B35A538E8 + + + Title + Find the PickerWheel + UUID + 31D9E92E-9803-4461-B032-54F86E2B13D8 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708441.00567806 + StartTimeInterval + 570708440.96966505 + Title + Synthesize event + UUID + 592888BA-F8CE-4BBC-BC15-89929B446347 + + + Title + Set value of PickerWheel to ScrollViewController + UUID + FAB98307-BE0F-4DFF-BF22-EAF4743345BF + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708441.14149296 + StartTimeInterval + 570708441.00738502 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708441.05641401 + StartTimeInterval + 570708441.00806606 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708441.05541003 + StartTimeInterval + 570708441.04852605 + Title + Check for interrupting elements affecting "Load" Button + UUID + 6121F50A-A9EE-4AC5-92CF-853B21E7FBBD + + + Title + Find the "Load" Button + UUID + CCF6D3E7-1233-4D45-B1F3-E0965221A780 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708441.13838696 + StartTimeInterval + 570708441.05715501 + Title + Synthesize event + UUID + D5CB4116-10FF-43B0-942F-F170C59AA035 + + + Title + Tap "Load" Button + UUID + FBE0E7F8-94AB-4D68-9EA6-A8918BD2E74A + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708446.18530703 + StartTimeInterval + 570708443.14816201 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708444.23013496 + StartTimeInterval + 570708444.20645797 + Title + Find the "Bitrise-player" Other + UUID + 045528DC-F32D-44C2-9DC4-B618A4A51FBA + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708444.25275397 + StartTimeInterval + 570708444.23633695 + Title + Find the Window + UUID + F08C20AD-EA9D-4049-B26B-A2D81BC685B9 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708444.28402305 + StartTimeInterval + 570708444.26084697 + Title + Find the "Bitrise-player" Other + UUID + 0EEC5321-48C4-4C32-91F9-F90A51E32CE7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708444.57352102 + StartTimeInterval + 570708444.28719902 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708444.32234001 + StartTimeInterval + 570708444.28831804 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708444.32172406 + StartTimeInterval + 570708444.31431901 + Title + Check for interrupting elements affecting ScrollView + UUID + AEE71661-0383-4FFE-9D24-891FABAA01CA + + + Title + Find the ScrollView + UUID + 66D1C121-BA05-4C42-B712-F9DA2DAA6C53 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708444.57114804 + StartTimeInterval + 570708444.32325101 + Title + Synthesize event + UUID + D987A310-22D3-4B84-9A2A-1A87141B154B + + + Title + Swipe up ScrollView + UUID + CEA38543-1DA1-4217-A21A-3B3FF00B38C5 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708444.64780498 + StartTimeInterval + 570708444.61758995 + Title + Find the "Bitrise-player" Other + UUID + 0728489A-2F04-40B4-91E3-2264DD58EB00 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708444.669999 + StartTimeInterval + 570708444.65300202 + Title + Find the Window + UUID + D9C2B1D3-7D59-4050-B9A1-71BE683146DC + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708444.69511294 + StartTimeInterval + 570708444.68020594 + Title + Find the "Bitrise-player" Other + UUID + 73ABC344-4AC7-4553-B590-944B3B6F48E4 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708444.98077595 + StartTimeInterval + 570708444.69731903 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708444.72511995 + StartTimeInterval + 570708444.69810402 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708444.724383 + StartTimeInterval + 570708444.71831501 + Title + Check for interrupting elements affecting ScrollView + UUID + 9A03E5D2-5EE9-4A12-92E7-57BA7FCECBBB + + + Title + Find the ScrollView at {{0.0, 44.0}, {375.0, 623.0}} + UUID + D9C32749-8560-4A32-ACC5-16BCBBFB1705 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708444.97658598 + StartTimeInterval + 570708444.72609794 + Title + Synthesize event + UUID + 96E27341-BABB-4ADD-A587-245AA549AC31 + + + Title + Swipe up ScrollView at {{0.0, 44.0}, {375.0, 623.0}} + UUID + 2280B348-41C7-4A3B-91BA-4FC039C8B52F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708445.057477 + StartTimeInterval + 570708445.02418697 + Title + Find the "Bitrise-player" Other + UUID + 25D3F55B-965D-4DF6-85E6-30B520DD217A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708445.08045006 + StartTimeInterval + 570708445.06274402 + Title + Find the Window + UUID + 61A98896-11E7-47A9-921A-67C8A6D0BDC8 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708445.10805798 + StartTimeInterval + 570708445.08927095 + Title + Find the "Bitrise-player" Other + UUID + 11F13FDB-D77C-4DFE-8F23-BB46C3B3C000 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708446.18440104 + StartTimeInterval + 570708445.11205304 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708446.182863 + StartTimeInterval + 570708446.13166404 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + 76F364B9-4A5E-4CDE-985E-D0C362885B63 + + + Title + Waiting 10.0s for "Bitrise-player" Other to exist + UUID + 3795A680-FD00-4E1F-BF7D-DEC1C7E30824 + + + Title + I scroll demo page and wait for player to be displayed + UUID + EE5ED41B-F4DF-48B4-A700-4C6F3492A383 + + + Title + I go to demo page and expect player to be displayed + UUID + 82EAC99B-80AC-4EA5-95FC-4D711CC196C9 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708447.27660596 + StartTimeInterval + 570708446.18773603 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708447.24116695 + StartTimeInterval + 570708446.18846297 + Title + Terminate tv.Bitrise.BitriseApp:3516 + UUID + FCD5043E-83D6-462E-BAB6-4C6ABB32DBAE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708447.27501905 + StartTimeInterval + 570708447.24452198 + Title + Terminate tv.Bitrise.BitriseApp:0 + UUID + 633F5B77-A76F-41FB-83D0-A3C681A35E80 + + + Title + Tear Down + UUID + E95907AC-B790-4685-9C0F-C5F7F98F0F4C + + + Duration + 40.586909055709839 + TestIdentifier + BitriseCommanderUITests/testCommanderUpdate() + TestName + testCommanderUpdate() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + 564D74F8-E1D7-41EA-A629-0ED0B79E6A39 + + + TestIdentifier + BitriseCommanderUITests + TestName + BitriseCommanderUITests + TestObjectClass + IDESchemeActionTestSummaryGroup + + + Duration + 33.922913074493408 + Subtests + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708447.30854797 + StartTimeInterval + 570708447.28122902 + Title + Start Test at 2019-02-01 05:07:27.281 + UUID + 345BCC1A-3258-4FA2-818B-A4C4933837CB + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708447.28122902 + StartTimeInterval + 570708447.28122902 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + BB183530-AEF0-47BE-B38A-CBC41A6F5D7D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708450.39718604 + StartTimeInterval + 570708447.30931604 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708450.39576805 + StartTimeInterval + 570708447.31074095 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708450.39425099 + StartTimeInterval + 570708447.33110702 + Title + Launch tv.Bitrise.BitriseApp + UUID + 7BAE9975-6051-4B7A-949D-38EDEDDB612E + + + Title + Open tv.Bitrise.BitriseApp + UUID + 69C9FF39-2BB3-4218-95B2-E2D2DF5A4826 + + + Title + Set Up + UUID + ACA789CA-0654-4162-97F2-C243BA3FBB33 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708454.50586295 + StartTimeInterval + 570708450.40318894 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708454.50430095 + StartTimeInterval + 570708450.42785001 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708451.51651096 + StartTimeInterval + 570708450.42938602 + Title + Terminate tv.Bitrise.BitriseApp:3610 + UUID + 7B9734E0-1C91-4545-B6DB-5E70733B178E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708453.47424304 + StartTimeInterval + 570708453.46922004 + Title + Wait for accessibility to load + UUID + D36716BD-443C-4BBC-AA47-5B66BED8E118 + + + Title + Launch tv.Bitrise.BitriseApp + UUID + 685232ED-14CD-4898-B2A9-243E63B39F7E + + + Title + Open tv.Bitrise.BitriseApp + UUID + 3FEB1B35-09EA-4FBA-8BE9-113F756BD652 + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708455.79388499 + StartTimeInterval + 570708454.50706697 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708455.58810198 + StartTimeInterval + 570708455.52113402 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 9A09DEEE-43A0-4C4D-97F8-D14127AC89CC + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708455.60906506 + StartTimeInterval + 570708455.58983302 + Title + Find the "pidTextField" TextField + UUID + BA41952D-5AE4-425E-817B-3BEE9891F608 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708455.670892 + StartTimeInterval + 570708455.610008 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708455.64036906 + StartTimeInterval + 570708455.61074495 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708455.63943994 + StartTimeInterval + 570708455.63252497 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + CCD0FE06-AA10-4317-B10C-64F515CA0C4C + + + Title + Find the PickerWheel + UUID + 884D081E-3C4C-40FA-B7B3-D8CD3DF0C225 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708455.67029905 + StartTimeInterval + 570708455.64127898 + Title + Synthesize event + UUID + 495E1023-03E3-4729-8B99-50D183B5122B + + + Title + Set value of PickerWheel to ScrollViewController + UUID + F3E509EB-FC9F-4224-8EDC-79C7CF14B361 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708455.79309797 + StartTimeInterval + 570708455.67143095 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708455.70382404 + StartTimeInterval + 570708455.671821 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708455.70348406 + StartTimeInterval + 570708455.69911003 + Title + Check for interrupting elements affecting "Load" Button + UUID + 3B67E177-EAD8-4F30-AF91-94470670EDD6 + + + Title + Find the "Load" Button + UUID + A550B279-21E3-40B5-B180-F8331D5672C9 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708455.79172206 + StartTimeInterval + 570708455.70415604 + Title + Synthesize event + UUID + 7487A736-6DFD-440C-BD74-9D6A576CAB28 + + + Title + Tap "Load" Button + UUID + 8AB1BC3F-B50E-4046-B7FD-97D89241985A + + + Title + I change the PID and tap on Load + UUID + 88A4219B-A55D-49F2-AB0E-63C56DB30349 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708456.84634399 + StartTimeInterval + 570708456.82114804 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + 287A7657-EA8F-4112-946E-D39D034D0622 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708456.97291696 + StartTimeInterval + 570708456.84741998 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708456.87994397 + StartTimeInterval + 570708456.84814703 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708456.87921703 + StartTimeInterval + 570708456.87393904 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + 092DA39B-4786-428C-A9F4-E7D0C0F1E401 + + + Title + Find the "go-to-ad-button" Button + UUID + 157083D4-759B-45B9-A07B-DF56E5239E39 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708456.97138405 + StartTimeInterval + 570708456.88070297 + Title + Synthesize event + UUID + 13951ACD-8F85-4806-96D2-2DC4F8EE949C + + + Title + Tap "go-to-ad-button" Button + UUID + 8DC42F8F-B38B-4EE3-8E55-E1ABC975A3F0 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708458.059062 + StartTimeInterval + 570708457.99886501 + Title + Checking Expect predicate exists == 1 for object "Bitrise-adchoices" Other + UUID + 0346E05F-22E5-40D8-A26F-24B6361B3011 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708459.13184905 + StartTimeInterval + 570708459.08222401 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + E0B8E2AC-6423-4DB0-B050-3B1949CB5544 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708459.27862799 + StartTimeInterval + 570708459.13341999 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708459.17195201 + StartTimeInterval + 570708459.13454294 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708459.17054403 + StartTimeInterval + 570708459.16342795 + Title + Check for interrupting elements affecting "Bitrise-player" Other + UUID + 4385E2D9-F30B-43CB-985C-7E9D51152A21 + + + Title + Find the "Bitrise-player" Other + UUID + A38442D2-6AD4-418B-9C62-64F1B8E47B56 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708459.27626705 + StartTimeInterval + 570708459.17346597 + Title + Synthesize event + UUID + 172BEA5B-4B85-45AF-8729-C8264D1627EE + + + Title + Tap "Bitrise-player" Other + UUID + B76D5D27-22FC-4CDA-A0B3-3BC203CA90F8 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708460.31709898 + StartTimeInterval + 570708460.30451596 + Title + Checking Expect predicate exists == 1 for object "Bitrise-fullscreenSoundButton" Other + UUID + DC2D0867-2ADB-4DC7-899B-32C3D46F7E81 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708461.369627 + StartTimeInterval + 570708461.33707297 + Title + Checking Expect predicate exists == 1 for object "Bitrise-adchoices" Other + UUID + 658B5AAA-00B3-43D4-9DD8-C3B22ED895B5 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708462.40789402 + StartTimeInterval + 570708461.37144601 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708462.40589905 + StartTimeInterval + 570708461.37244296 + Title + Terminate tv.Bitrise.BitriseApp:3615 + UUID + 49C52028-F319-4F07-B777-2A458066476D + + + Title + Tear Down + UUID + 9C888E1D-89B7-47CA-9FFF-7D4BF7710A3F + + + Duration + 15.128860950469971 + TestIdentifier + BitriseComponentUITest/testAdChoiceIcon() + TestName + testAdChoiceIcon() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + CFF59CDE-841F-446A-A633-F338FBD92CAB + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708462.44088602 + StartTimeInterval + 570708462.41016102 + Title + Start Test at 2019-02-01 05:07:42.410 + UUID + 8D607DE2-591D-4A81-B48C-98FD103C83BB + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708462.41016102 + StartTimeInterval + 570708462.41016102 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + BC3C161A-7043-44DF-9F10-2AE8EBE1C49B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708465.61778998 + StartTimeInterval + 570708462.44282603 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708465.61617601 + StartTimeInterval + 570708462.44554698 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708465.614905 + StartTimeInterval + 570708462.47210705 + Title + Launch tv.Bitrise.BitriseApp + UUID + 8493DF1C-DE2C-408E-93B8-35A8905A44FD + + + Title + Open tv.Bitrise.BitriseApp + UUID + C8B9CF76-2C8F-4ECB-872F-3CCBDD874D2C + + + Title + Set Up + UUID + AF36AB0E-C3F4-4515-AEBB-74D8C8320004 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708470.08586597 + StartTimeInterval + 570708465.62372899 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708470.082201 + StartTimeInterval + 570708465.65573001 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708466.73884201 + StartTimeInterval + 570708465.65662801 + Title + Terminate tv.Bitrise.BitriseApp:3666 + UUID + C65D551B-E234-4279-8CD9-E618D119DE68 + + + Title + Launch tv.Bitrise.BitriseApp + UUID + C9036BC9-FE83-4BB9-8725-DD0EF54518F0 + + + Title + Open tv.Bitrise.BitriseApp + UUID + 392B3F85-4913-4926-ACF5-11E881E8ADEC + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708471.391294 + StartTimeInterval + 570708470.08880496 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708471.18218899 + StartTimeInterval + 570708471.10465598 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + EA6AD93D-8FBE-400D-9C04-AD0A2E719CBE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708471.21059096 + StartTimeInterval + 570708471.188254 + Title + Find the "pidTextField" TextField + UUID + 1E31F5CF-B329-48AF-9C21-21F8BD090857 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708471.27265298 + StartTimeInterval + 570708471.21152103 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708471.24065697 + StartTimeInterval + 570708471.21223295 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708471.239694 + StartTimeInterval + 570708471.23292696 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + C8B608EA-4989-4793-9832-B9B1BCBE41BC + + + Title + Find the PickerWheel + UUID + 16D15DEA-C659-4E93-B73F-6ED996D4A269 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708471.27194905 + StartTimeInterval + 570708471.24174702 + Title + Synthesize event + UUID + 74F05BC8-794B-4952-B8E7-953A9700D668 + + + Title + Set value of PickerWheel to ScrollViewController + UUID + 7C92E80A-0515-453A-BAD0-104F3F41A228 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708471.39034498 + StartTimeInterval + 570708471.27319098 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708471.30063701 + StartTimeInterval + 570708471.27362394 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708471.300246 + StartTimeInterval + 570708471.29604006 + Title + Check for interrupting elements affecting "Load" Button + UUID + A98A40B8-B521-4BFB-83A9-0935D875699D + + + Title + Find the "Load" Button + UUID + 44035ED3-30B5-4168-8A10-F941BBCEA837 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708471.38873696 + StartTimeInterval + 570708471.30114996 + Title + Synthesize event + UUID + 07E62917-1A8A-4698-8301-06B92EDA2C1F + + + Title + Tap "Load" Button + UUID + CAD8BCFF-A1AC-43AC-83C1-DB166F5B2D4B + + + Title + I change the PID and tap on Load + UUID + 6614D55A-6525-483F-9912-CDB3E34D5347 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708472.44706297 + StartTimeInterval + 570708472.421121 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + 0F546446-C8C7-428E-89F7-8E0832A83DA1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708472.57449102 + StartTimeInterval + 570708472.44847298 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708472.47974598 + StartTimeInterval + 570708472.44915104 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708472.47885096 + StartTimeInterval + 570708472.47218394 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + B47FAE57-703F-4305-B287-802EB6572525 + + + Title + Find the "go-to-ad-button" Button + UUID + 136790BE-04FC-4CF0-8D6C-DA6701097A90 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708472.57240999 + StartTimeInterval + 570708472.48078704 + Title + Synthesize event + UUID + A3529B2E-0EBC-4578-BA14-EE4DA3594136 + + + Title + Tap "go-to-ad-button" Button + UUID + EE887354-609A-4626-9FB0-5C358EF29B83 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708473.65810394 + StartTimeInterval + 570708473.60650504 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + 5C9583B5-D6BD-4112-9C41-E9FC99020381 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708473.799945 + StartTimeInterval + 570708473.65959895 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708473.69866097 + StartTimeInterval + 570708473.66051698 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708473.69750702 + StartTimeInterval + 570708473.69021404 + Title + Check for interrupting elements affecting "Bitrise-player" Other + UUID + 7D775F42-2DF1-437D-9D49-FBDC83930828 + + + Title + Find the "Bitrise-player" Other + UUID + A98D07AD-F815-485F-8F35-25F3BC1BCA78 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708473.79727101 + StartTimeInterval + 570708473.699772 + Title + Synthesize event + UUID + 80FCF2DD-47BB-4EE6-9CA9-877BD664DD64 + + + Title + Tap "Bitrise-player" Other + UUID + 4C4EC972-064F-4B04-AE0A-32D70776D3CB + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708480.14072001 + StartTimeInterval + 570708473.80301404 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708474.84398603 + StartTimeInterval + 570708474.83312094 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 91F6FEF0-AA86-4A06-BEB7-F95FEA6C7C47 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708475.88829505 + StartTimeInterval + 570708475.85396099 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 0F95E328-A730-4313-8DB1-45691AE297DE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708476.94317698 + StartTimeInterval + 570708476.91160703 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 8412A743-8325-481A-928B-F346B7994B4F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708477.99458897 + StartTimeInterval + 570708477.97123206 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 6EFCD553-DDB0-4745-919F-C31C13ED72ED + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708479.06548405 + StartTimeInterval + 570708479.03340006 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 66831CC4-F331-480E-BCEE-36F71B10ADEC + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708480.13859296 + StartTimeInterval + 570708480.100227 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 04951C86-CFAE-40AF-AED4-90AEA6CFA7EE + + + Title + Waiting 20.0s for "Bitrise-endScreenReplay" Other to exist + UUID + 5D2E20E8-655A-41B9-A776-00CD503E9F56 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708481.19825006 + StartTimeInterval + 570708480.14177704 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708481.19367301 + StartTimeInterval + 570708480.14290404 + Title + Terminate tv.Bitrise.BitriseApp:3671 + UUID + 3AAD0075-BFCC-48E2-B262-05E8E31CE2F1 + + + Title + Tear Down + UUID + B99A4058-69EB-4969-9DDE-7C2BDC1C0FC0 + + + Duration + 18.791437983512878 + TestIdentifier + BitriseComponentUITest/testFullScreenReplay() + TestName + testFullScreenReplay() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + F4F3F803-4586-41D0-9C96-B668D373D1F3 + + + TestIdentifier + BitriseComponentUITest + TestName + BitriseComponentUITest + TestObjectClass + IDESchemeActionTestSummaryGroup + + + Duration + 80.691501975059509 + Subtests + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + Attachments + + + Filename + Screenshot_98956000-CC9C-4DD4-A0CB-708DD862587C.jpg + HasPayload + + InActivityIdentifier + 1 + Lifetime + 1 + Name + kXCTAttachmentLegacyScreenImageData + Timestamp + 570708481.242751 + UniformTypeIdentifier + public.jpeg + + + FinishTimeInterval + 570708481.24281502 + HasScreenshotData + + StartTimeInterval + 570708481.20802402 + Title + Start Test at 2019-02-01 05:08:01.208 + UUID + 98956000-CC9C-4DD4-A0CB-708DD862587C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708481.24715495 + StartTimeInterval + 570708481.24412501 + Title + Set Up + UUID + 53C35012-F471-4759-9FC6-879680C0BD61 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + Attachments + + + Filename + Screenshot_773F89BE-F4EF-4499-9CEA-89C767CBFE1E.jpg + HasPayload + + InActivityIdentifier + 1 + Lifetime + 1 + Name + kXCTAttachmentLegacyScreenImageData + Timestamp + 570708481.26916099 + UniformTypeIdentifier + public.jpeg + + + FinishTimeInterval + 570708484.41001797 + HasScreenshotData + + StartTimeInterval + 570708481.24847698 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708484.40842402 + StartTimeInterval + 570708481.26921701 + Title + Launch tv.Bitrise.BitriseApp + UUID + D3EA0973-DBEC-40DE-8576-FF470F61BC8E + + + Title + Open tv.Bitrise.BitriseApp + UUID + 773F89BE-F4EF-4499-9CEA-89C767CBFE1E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708485.51006901 + StartTimeInterval + 570708485.42086601 + Title + Checking Expect predicate exists == 1 for object "IAB Tech Lab" Button + UUID + 3F9E29CA-AD70-4667-9B9C-6A596BD9BE3B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708485.65966296 + StartTimeInterval + 570708485.51119995 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708485.550488 + StartTimeInterval + 570708485.51238799 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708485.54925799 + StartTimeInterval + 570708485.54280305 + Title + Check for interrupting elements affecting "IAB Tech Lab" Button + UUID + D23C3CD3-645B-4D64-BF03-0C4D6B345C71 + + + Title + Find the "IAB Tech Lab" Button + UUID + 9DD298F7-F467-4474-8126-FE07FCC5F4C1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + Attachments + + + Filename + Screenshot_E2D55A84-1DDC-4653-9DEC-3EF5931F7F8B.jpg + HasPayload + + InActivityIdentifier + 1 + Lifetime + 1 + Name + kXCTAttachmentLegacyScreenImageData + Timestamp + 570708485.58831894 + UniformTypeIdentifier + public.jpeg + + + FinishTimeInterval + 570708485.65823102 + HasScreenshotData + + StartTimeInterval + 570708485.55121803 + Title + Synthesize event + UUID + E2D55A84-1DDC-4653-9DEC-3EF5931F7F8B + + + Title + Tap "IAB Tech Lab" Button + UUID + 15FF9975-F341-4907-B94B-238AEBBFC555 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708486.74421299 + StartTimeInterval + 570708486.67135298 + Title + Checking Expect predicate exists == 1 for object "Banner Video" StaticText + UUID + BFE85FAE-B18B-4880-8376-E831CC37CCFE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708486.89594197 + StartTimeInterval + 570708486.74543297 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708486.80369604 + StartTimeInterval + 570708486.74784505 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708486.80248404 + StartTimeInterval + 570708486.78922904 + Title + Check for interrupting elements affecting "Banner Video" StaticText + UUID + 3E6403DD-E99A-4B8C-84D9-E4A4B2A337CC + + + Title + Find the "Banner Video" StaticText + UUID + 431B1917-A69C-4A1E-A2B8-7A3CA619E8B0 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + Attachments + + + Filename + Screenshot_400CE2CC-6061-46B8-8045-19FB379CE4A0.jpg + HasPayload + + InActivityIdentifier + 1 + Lifetime + 1 + Name + kXCTAttachmentLegacyScreenImageData + Timestamp + 570708486.83100605 + UniformTypeIdentifier + public.jpeg + + + FinishTimeInterval + 570708486.89403403 + HasScreenshotData + + StartTimeInterval + 570708486.80585504 + Title + Synthesize event + UUID + 400CE2CC-6061-46B8-8045-19FB379CE4A0 + + + Title + Tap "Banner Video" StaticText + UUID + 0F2C4781-2383-4666-A891-36410549BD38 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708487.04840505 + StartTimeInterval + 570708486.89685297 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708486.95138502 + StartTimeInterval + 570708486.89754999 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708486.95045805 + StartTimeInterval + 570708486.94428802 + Title + Check for interrupting elements affecting "Load" Button + UUID + C3C8A761-9E23-4D7D-89BE-826511868F52 + + + Title + Find the "Load" Button + UUID + 94C384B8-3DE2-43DF-BB4D-C3F8C100B4AC + + + ActivityType + com.apple.dt.xctest.activity-type.internal + Attachments + + + Filename + Screenshot_E0462990-907E-40AD-A9C5-A32396CEF7AD.jpg + HasPayload + + InActivityIdentifier + 1 + Lifetime + 1 + Name + kXCTAttachmentLegacyScreenImageData + Timestamp + 570708486.981933 + UniformTypeIdentifier + public.jpeg + + + FinishTimeInterval + 570708487.04668403 + HasScreenshotData + + StartTimeInterval + 570708486.95261705 + Title + Synthesize event + UUID + E0462990-907E-40AD-A9C5-A32396CEF7AD + + + Title + Tap "Load" Button + UUID + 29EEAD19-BB3B-4492-AA6B-06BBF2B9DF1F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708488.11250603 + StartTimeInterval + 570708487.04953504 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708488.11128795 + StartTimeInterval + 570708488.08371603 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + AA935C72-A259-42C4-8D94-212E06C47A5C + + + Title + Waiting 10.0s for "Bitrise-player" Other to exist + UUID + 32E48309-94BE-47EB-90B5-EC6DC071C96C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708495.54033697 + StartTimeInterval + 570708488.11331904 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708489.18906105 + StartTimeInterval + 570708489.13742697 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 16D3D13F-55BE-49AA-9103-7C351E2DA479 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708490.24573004 + StartTimeInterval + 570708490.20408905 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 53EB9A8E-AA2D-4C11-8672-171E9ACFC90B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708491.29339898 + StartTimeInterval + 570708491.25406098 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + FB60FF89-E69F-4FBF-B382-FAC4B3A7F9D1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708492.35302699 + StartTimeInterval + 570708492.31994903 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 29F0A42A-BFE0-4645-BE46-7852AC5CB3E5 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708493.40697801 + StartTimeInterval + 570708493.38733399 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 0ECC524B-1926-45D6-990C-1E264C544887 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708494.47274101 + StartTimeInterval + 570708494.43736899 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 04D590D9-A386-46C1-BC1D-9B576C81D4E4 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708495.53889501 + StartTimeInterval + 570708495.50098705 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 67598D81-46B7-48CE-B74D-7CF97C269BE4 + + + Title + Waiting 50.0s for "Bitrise-endScreenReplay" Other to exist + UUID + 11A92930-1D49-4E70-8D9D-F36059EEBAE2 + + + ActivityType + com.apple.dt.xctest.activity-type.testAssertionFailure + Attachments + + + Filename + Screenshot_28D6E001-62F1-4B96-AB90-608C0F8E5810.jpg + HasPayload + + InActivityIdentifier + 1 + Lifetime + 1 + Name + kXCTAttachmentLegacyScreenImageData + Timestamp + 570708495.56789804 + UniformTypeIdentifier + public.jpeg + + + FinishTimeInterval + 570708495.56801295 + HasScreenshotData + + StartTimeInterval + 570708495.54386306 + Title + Assertion Failure: BitriseOMUITests.swift:70: XCTAssertTrue failed - No session found + UUID + 28D6E001-62F1-4B96-AB90-608C0F8E5810 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708495.70906901 + StartTimeInterval + 570708495.57191706 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708495.62063503 + StartTimeInterval + 570708495.572734 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708495.61959696 + StartTimeInterval + 570708495.61255002 + Title + Check for interrupting elements affecting "Bitrise App" Button + UUID + 1891F964-5CC5-49B6-B29C-8DC5FE99F74C + + + Title + Find the "Bitrise App" Button + UUID + AFF8DE25-FC5C-4B80-A85B-B3165F6CC170 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + Attachments + + + Filename + Screenshot_A8EE6B44-D7D2-49DE-BEC0-EC88E41D98FD.jpg + HasPayload + + InActivityIdentifier + 1 + Lifetime + 1 + Name + kXCTAttachmentLegacyScreenImageData + Timestamp + 570708495.63947701 + UniformTypeIdentifier + public.jpeg + + + FinishTimeInterval + 570708495.70703304 + HasScreenshotData + + StartTimeInterval + 570708495.62157297 + Title + Synthesize event + UUID + A8EE6B44-D7D2-49DE-BEC0-EC88E41D98FD + + + Title + Tap "Bitrise App" Button + UUID + FE37EAEA-49FB-4EB2-9470-CFA6CBFA7D6C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708496.75664604 + StartTimeInterval + 570708495.71043897 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + Attachments + + + Filename + Screenshot_1811AD79-1693-4D7D-A71B-5AA3BC593343.jpg + HasPayload + + InActivityIdentifier + 1 + Lifetime + 1 + Name + kXCTAttachmentLegacyScreenImageData + Timestamp + 570708495.73658705 + UniformTypeIdentifier + public.jpeg + + + FinishTimeInterval + 570708496.75492704 + HasScreenshotData + + StartTimeInterval + 570708495.71208096 + Title + Terminate tv.Bitrise.BitriseApp:3729 + UUID + 1811AD79-1693-4D7D-A71B-5AA3BC593343 + + + Title + Tear Down + UUID + BF57D3E1-6772-4299-A99E-DA40816A141F + + + Duration + 15.550718903541565 + FailureSummaries + + + FileName + /Users/vagrant/git/BitriseApp/BitriseAppUITests/BitriseOMUITests.swift + LineNumber + 70 + Message + XCTAssertTrue failed - No session found + PerformanceFailure + + + + TestIdentifier + BitriseOMUITests/testOMBanner() + TestName + testOMBanner() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Failure + TestSummaryGUID + E262F745-5086-42BE-9943-5C6D5EFC5ACE + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708496.78916502 + StartTimeInterval + 570708496.75895 + Title + Start Test at 2019-02-01 05:08:16.759 + UUID + 7B7ADC37-3D5B-4DA4-8F9D-1526C314E3E2 + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708496.75895 + StartTimeInterval + 570708496.75895 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + BDE4DD82-01FE-43AC-AB1A-EBFA74AE420E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708496.79511702 + StartTimeInterval + 570708496.79111898 + Title + Set Up + UUID + 930A0847-BFA5-4570-B836-2D217528ECF2 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708500.16324103 + StartTimeInterval + 570708496.79724705 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708500.16029096 + StartTimeInterval + 570708496.82593501 + Title + Launch tv.Bitrise.BitriseApp + UUID + C2797725-264B-4B63-8B6E-4AE45B833099 + + + Title + Open tv.Bitrise.BitriseApp + UUID + BD80500D-8BA5-4A47-B292-5B2E7BB34823 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708501.28583503 + StartTimeInterval + 570708501.19445395 + Title + Checking Expect predicate exists == 1 for object "IAB Tech Lab" Button + UUID + ED74284B-FEF7-461E-8817-ED30325DB28A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708501.432495 + StartTimeInterval + 570708501.28813303 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708501.33051097 + StartTimeInterval + 570708501.289325 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708501.32928896 + StartTimeInterval + 570708501.32102895 + Title + Check for interrupting elements affecting "IAB Tech Lab" Button + UUID + C7BAC04E-F1A1-4366-BAC6-F45F1E78A934 + + + Title + Find the "IAB Tech Lab" Button + UUID + F4E77148-3F22-4687-8A97-4830284E14FF + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708501.43063295 + StartTimeInterval + 570708501.33144403 + Title + Synthesize event + UUID + 7D489726-AD2C-4611-8556-68C804580C81 + + + Title + Tap "IAB Tech Lab" Button + UUID + E0587DF4-16D8-4F47-9D6F-CE45FBC2BB6B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708502.50238705 + StartTimeInterval + 570708502.44429696 + Title + Checking Expect predicate exists == 1 for object "Interstitial Ad" StaticText + UUID + EBD4916E-6FF1-4B90-B1A3-4F8DAF7265C3 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708502.64398599 + StartTimeInterval + 570708502.503775 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708502.55291605 + StartTimeInterval + 570708502.50486398 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708502.55227697 + StartTimeInterval + 570708502.54468405 + Title + Check for interrupting elements affecting "Interstitial Ad" StaticText + UUID + DB0ACB0A-5B62-4DC6-9410-A7786A37BFAF + + + Title + Find the "Interstitial Ad" StaticText + UUID + 4165C842-66CA-4F79-8ECD-3895B3FAE6B3 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708502.64134002 + StartTimeInterval + 570708502.55391002 + Title + Synthesize event + UUID + 8134BCAB-5FBB-4058-9F5F-338FEB15773A + + + Title + Tap "Interstitial Ad" StaticText + UUID + 094171A9-2E75-45B6-8448-9F5DAFDB5622 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708502.80527401 + StartTimeInterval + 570708502.64618301 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708502.70367205 + StartTimeInterval + 570708502.64725399 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708502.70269895 + StartTimeInterval + 570708502.69627297 + Title + Check for interrupting elements affecting "Load" Button + UUID + A65BB068-C818-4040-B8AD-0C8939312104 + + + Title + Find the "Load" Button + UUID + 5AB2C0EB-75C1-4B0B-95B3-9F65213FE847 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708502.80315101 + StartTimeInterval + 570708502.70455205 + Title + Synthesize event + UUID + CA9C9FD2-DFC5-4F3B-BF48-4A7FE00402D0 + + + Title + Tap "Load" Button + UUID + ABC3784F-A12E-4A1C-B051-F1D7C441547C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708503.87665796 + StartTimeInterval + 570708503.84434402 + Title + Checking Expect predicate exists == 1 for object "interstitial-show" Button + UUID + 095B708B-D48B-4A7A-8A79-10497B048B5F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708504.00752401 + StartTimeInterval + 570708503.88100898 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708503.91245699 + StartTimeInterval + 570708503.88354599 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708503.91125298 + StartTimeInterval + 570708503.90231204 + Title + Check for interrupting elements affecting "interstitial-show" Button + UUID + C999F3D3-A1C5-4469-9808-3CE74785DDC6 + + + Title + Find the "interstitial-show" Button + UUID + CB65EB83-0829-4850-8F7F-0E9442A65741 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708504.00571895 + StartTimeInterval + 570708503.91386402 + Title + Synthesize event + UUID + 53AC8009-EBD8-4D24-9F09-0E98E4C36149 + + + Title + Tap "interstitial-show" Button + UUID + 60438E6B-8C27-411E-865F-0FC02C4D44CC + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708505.08522296 + StartTimeInterval + 570708504.00898302 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708505.08363998 + StartTimeInterval + 570708505.03504896 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + 0637A526-FB26-4793-8EB4-AF51436EC0A9 + + + Title + Waiting 10.0s for "Bitrise-player" Other to exist + UUID + 41B94E55-51BF-4AAC-A97F-FEEE3B8A63AE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708506.12992704 + StartTimeInterval + 570708506.11820996 + Title + Checking Expect predicate exists == 1 for object "interstitial-show" Button + UUID + A78E28ED-5A5C-4BE4-9964-CFE89B559387 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708506.15252805 + StartTimeInterval + 570708506.13123906 + Title + Snapshot accessibility hierarchy for app with pid 3773 + UUID + 874AD1D4-605E-4050-8065-E85D46214599 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708506.15476203 + StartTimeInterval + 570708506.15382397 + Title + Find: Descendants matching type Button + UUID + 0637F195-7280-4FEA-BF85-579992E4F4D1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708506.15698504 + StartTimeInterval + 570708506.15600097 + Title + Snapshot accessibility hierarchy for app with pid 3773 + UUID + D582A09D-DDA7-4819-8528-DD726BE9C672 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708506.15856397 + StartTimeInterval + 570708506.15783501 + Title + Find: Descendants matching type Button + UUID + BC927617-BC89-4245-8F00-EF359DF3C053 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708506.16056097 + StartTimeInterval + 570708506.159603 + Title + Snapshot accessibility hierarchy for app with pid 3773 + UUID + 2C36274E-2A80-4F49-A7E7-FF51A8E33B8E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708507.21987796 + StartTimeInterval + 570708507.18507802 + Title + Checking Expect predicate exists == 1 for object "interstitial-show" Button + UUID + C03A1D79-4B17-4B7F-88B7-63DF5335CD25 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708507.25245202 + StartTimeInterval + 570708507.22173095 + Title + Snapshot accessibility hierarchy for app with pid 3773 + UUID + 9C9C586E-1C1B-4719-B48F-49071E193402 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708507.25450504 + StartTimeInterval + 570708507.25376904 + Title + Find: Descendants matching type Button + UUID + 9377D7D3-199F-4F67-BB09-7CFF9614B788 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708507.25695205 + StartTimeInterval + 570708507.255422 + Title + Snapshot accessibility hierarchy for app with pid 3773 + UUID + 27B1E90B-A228-4E02-B21D-D005110EC50E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708507.25839806 + StartTimeInterval + 570708507.25775599 + Title + Find: Descendants matching type Button + UUID + 2D0D15FF-E1E4-444E-9F8F-37BCC02AECCE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708507.26032996 + StartTimeInterval + 570708507.25937796 + Title + Snapshot accessibility hierarchy for app with pid 3773 + UUID + 5017FE22-1E2D-4808-97B1-3BFE882E02A4 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708508.30326605 + StartTimeInterval + 570708508.278602 + Title + Checking Expect predicate exists == 1 for object "interstitial-show" Button + UUID + F2EC7C2D-DFCA-45AC-8D81-19895BCA824F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708508.33384097 + StartTimeInterval + 570708508.30458295 + Title + Snapshot accessibility hierarchy for app with pid 3773 + UUID + 2723DB1E-B0DE-46C1-B1E4-EBB5AC66C93D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708508.33926594 + StartTimeInterval + 570708508.33694303 + Title + Find: Descendants matching type Button + UUID + A41FB7E9-C1F1-45D8-ACE4-53AB490091E6 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708508.34178996 + StartTimeInterval + 570708508.34079301 + Title + Snapshot accessibility hierarchy for app with pid 3773 + UUID + E64AE9BE-E79B-44D7-92B5-B0DE9B24A984 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708508.34456801 + StartTimeInterval + 570708508.34304595 + Title + Find: Descendants matching type Button + UUID + FC1C8903-D979-49E4-8965-69691EF30CF0 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708508.34781003 + StartTimeInterval + 570708508.34647906 + Title + Snapshot accessibility hierarchy for app with pid 3773 + UUID + 2F195C19-8D10-4B27-B100-202744F9CE52 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708509.38430905 + StartTimeInterval + 570708509.372563 + Title + Checking Expect predicate exists == 1 for object "interstitial-show" Button + UUID + F6F930F3-BA2E-41AC-8A9F-97B85483EAB3 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708509.40693796 + StartTimeInterval + 570708509.386572 + Title + Snapshot accessibility hierarchy for app with pid 3773 + UUID + 2DB53F70-5738-4AA7-87B0-66ACE3972FD8 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708509.40945804 + StartTimeInterval + 570708509.40838206 + Title + Find: Descendants matching type Button + UUID + F1C063FA-6C28-4EA4-82FF-C5B7AA1D240D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708509.41276896 + StartTimeInterval + 570708509.41084599 + Title + Snapshot accessibility hierarchy for app with pid 3773 + UUID + 6395C018-D7FF-4FFE-9671-1FEB375F496B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708509.41512406 + StartTimeInterval + 570708509.41366804 + Title + Find: Descendants matching type Button + UUID + 19AB02FC-C4B2-430C-9163-CD7665092670 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708509.41719604 + StartTimeInterval + 570708509.41645503 + Title + Snapshot accessibility hierarchy for app with pid 3773 + UUID + 5201CF4E-0675-4364-B4EC-28E0D451ADA1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708510.46493697 + StartTimeInterval + 570708510.44432402 + Title + Checking Expect predicate exists == 1 for object "interstitial-show" Button + UUID + 97D20F01-E7F3-4A51-926F-25A045AAA06B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708510.49666297 + StartTimeInterval + 570708510.46687198 + Title + Snapshot accessibility hierarchy for app with pid 3773 + UUID + 5CBC2326-B6FC-43C5-A090-2ADA88D98990 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708510.49961495 + StartTimeInterval + 570708510.49871397 + Title + Find: Descendants matching type Button + UUID + A04EAB8F-2B78-42CF-B70D-A2FD186EBF30 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708510.50380194 + StartTimeInterval + 570708510.50263906 + Title + Snapshot accessibility hierarchy for app with pid 3773 + UUID + 62A8C835-173C-4DF2-9579-856318A28599 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708510.50696301 + StartTimeInterval + 570708510.50529897 + Title + Find: Descendants matching type Button + UUID + BE526506-39A5-42EF-BBC6-5A951CA90EB1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708510.51026595 + StartTimeInterval + 570708510.50902998 + Title + Snapshot accessibility hierarchy for app with pid 3773 + UUID + 88C52FB1-DBC4-4F00-BB59-DDA4FF8DB1ED + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708511.54211605 + StartTimeInterval + 570708511.52769601 + Title + Checking Expect predicate exists == 1 for object "interstitial-show" Button + UUID + 4BEBD0C6-D768-4FBA-9723-3D6FE2490BBC + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708511.66797495 + StartTimeInterval + 570708511.54422605 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708511.58072305 + StartTimeInterval + 570708511.54482901 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708511.57869899 + StartTimeInterval + 570708511.567554 + Title + Check for interrupting elements affecting "Bitrise App" Button + UUID + 847D44D4-CA5D-48FB-9658-C5FC37F43993 + + + Title + Find the "Bitrise App" Button + UUID + 3A9D766E-D796-409E-9D78-EA20F282B5C3 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708511.66689897 + StartTimeInterval + 570708511.58311105 + Title + Synthesize event + UUID + 2F1E7867-87A4-411D-867F-E76D8BFCC8E9 + + + Title + Tap "Bitrise App" Button + UUID + 8F236F8F-2739-4D61-868A-A3BE3873349A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708512.73541701 + StartTimeInterval + 570708512.677598 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + AECC9829-E0E5-4DB2-91FB-B4BC7722A458 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708513.80582595 + StartTimeInterval + 570708513.74446297 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 68EA1EB4-D8DA-4754-9D76-2B1406174EE2 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708514.87490797 + StartTimeInterval + 570708514.81112003 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + B2B3DC66-A3B1-4783-8E0C-2153A412A313 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708515.95783401 + StartTimeInterval + 570708515.89447403 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 92CBAC9C-AE9B-4BA3-86B3-39F465824728 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708517.02154696 + StartTimeInterval + 570708516.96117306 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 985EB55C-D062-456B-AB40-283D21220A35 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708518.08976996 + StartTimeInterval + 570708518.027794 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + EA86D5A4-5F19-4931-9F02-225942FC9C6D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708519.15860999 + StartTimeInterval + 570708519.09446299 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 15A74EE2-AEEE-4671-8E43-8B82AD6EA996 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708520.224213 + StartTimeInterval + 570708520.16112101 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 0598542F-C4A1-4037-AC1A-A52B54BF7DAE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708521.28977799 + StartTimeInterval + 570708521.22779095 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + A07C9143-1B4B-496D-814D-26EF5612AB32 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708522.78899395 + StartTimeInterval + 570708521.67565799 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708522.78693497 + StartTimeInterval + 570708521.67706203 + Title + Terminate tv.Bitrise.BitriseApp:3773 + UUID + 42AD1F00-2F30-439D-B46A-C5C90F545827 + + + Title + Tear Down + UUID + CD499678-7B31-49B4-8116-22EA3AB051A9 + + + Duration + 26.031643033027649 + TestIdentifier + BitriseOMUITests/testOMInterstitial() + TestName + testOMInterstitial() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + BDFB2C1B-9658-4877-BE31-8803610F0089 + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708522.82171094 + StartTimeInterval + 570708522.79111099 + Title + Start Test at 2019-02-01 05:08:42.791 + UUID + A0277239-5967-4151-9AD1-1AA729A244D9 + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708522.79111099 + StartTimeInterval + 570708522.79111099 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + 9B6AF412-681A-4D31-AA0F-92FE0C71836B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708522.82734501 + StartTimeInterval + 570708522.82345295 + Title + Set Up + UUID + 4C15C976-5AB4-49F6-BA96-340932F851EB + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708526.32121599 + StartTimeInterval + 570708522.83030105 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708526.31953394 + StartTimeInterval + 570708522.85374105 + Title + Launch tv.Bitrise.BitriseApp + UUID + C7F53E2F-FD4C-4116-8772-C45FA172F3CF + + + Title + Open tv.Bitrise.BitriseApp + UUID + F31C6347-26E5-44EB-A4B3-7399FF3754FA + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708527.41445005 + StartTimeInterval + 570708527.32774305 + Title + Checking Expect predicate exists == 1 for object "IAB Tech Lab" Button + UUID + D66D666F-7CA1-4EE5-9485-64497DD1D213 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708527.55415297 + StartTimeInterval + 570708527.41587102 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708527.45553005 + StartTimeInterval + 570708527.41650295 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708527.45477295 + StartTimeInterval + 570708527.44790006 + Title + Check for interrupting elements affecting "IAB Tech Lab" Button + UUID + FFA3BDDF-151D-40A2-A5E2-7F45A7380EE5 + + + Title + Find the "IAB Tech Lab" Button + UUID + 6EBE4568-9140-46FA-8347-5D593FF948D6 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708527.55233097 + StartTimeInterval + 570708527.45670497 + Title + Synthesize event + UUID + 74712804-77C3-4664-BCB2-A3F76175AE62 + + + Title + Tap "IAB Tech Lab" Button + UUID + A88F3EA6-429E-4D94-8540-44284267231D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708528.63413596 + StartTimeInterval + 570708528.57772195 + Title + Checking Expect predicate exists == 1 for object "inRead" StaticText + UUID + 86C20248-2648-4FD6-BDDB-4444E93EBE8E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708528.77710295 + StartTimeInterval + 570708528.63572001 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708528.68491495 + StartTimeInterval + 570708528.63690495 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708528.68417501 + StartTimeInterval + 570708528.67754602 + Title + Check for interrupting elements affecting "inRead" StaticText + UUID + 98F2D8C8-9047-4ED7-B5E9-84DDB25EAB46 + + + Title + Find the "inRead" StaticText + UUID + 1FA80347-6B0D-462D-91E6-717CA1B47741 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708528.77543604 + StartTimeInterval + 570708528.68628299 + Title + Synthesize event + UUID + 13B67A5D-3725-4295-A66A-2CDABCE53067 + + + Title + Tap "inRead" StaticText + UUID + 0F7175D0-166A-4DB3-A218-B064CD782EB1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708528.93790495 + StartTimeInterval + 570708528.77908802 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708528.84101796 + StartTimeInterval + 570708528.77981901 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708528.83904004 + StartTimeInterval + 570708528.83065104 + Title + Check for interrupting elements affecting "Load" Button + UUID + 19561490-6391-483F-91EC-EEDECE3FC4BE + + + Title + Find the "Load" Button + UUID + E653C2F8-C9FC-482D-B959-DA416C7148BF + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708528.93554294 + StartTimeInterval + 570708528.84316802 + Title + Synthesize event + UUID + 029A6D03-95C3-4E91-941D-1E08ABFCBB0F + + + Title + Tap "Load" Button + UUID + 2A746755-78A5-43E7-B11F-259710F140E3 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708529.99973702 + StartTimeInterval + 570708529.96979904 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + F08307A4-C030-405A-B634-586CA21A8E2D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708530.12200296 + StartTimeInterval + 570708530.00109398 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708530.02788496 + StartTimeInterval + 570708530.00178099 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708530.02712905 + StartTimeInterval + 570708530.02056897 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + 886AEFED-04C3-4618-BF17-28E671DA1920 + + + Title + Find the "go-to-ad-button" Button + UUID + 82358437-727B-408D-B05A-7234027AEA7C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708530.120731 + StartTimeInterval + 570708530.02895296 + Title + Synthesize event + UUID + 86CB0272-DA1A-42DB-BB6D-D154D29A354B + + + Title + Tap "go-to-ad-button" Button + UUID + 9ACB8009-E2E4-4A2C-AA09-7D8F5D8FABD3 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708531.20979095 + StartTimeInterval + 570708530.122859 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708531.20853901 + StartTimeInterval + 570708531.153198 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + 6BD664AE-F192-4735-8DA8-D75706F8B5D0 + + + Title + Waiting 10.0s for "Bitrise-player" Other to exist + UUID + C570C009-9416-436F-937E-4FC9E3EC1323 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708537.28952396 + StartTimeInterval + 570708536.21610296 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708537.28777504 + StartTimeInterval + 570708537.23692298 + Title + Checking Expect predicate exists == 1 for object "Bitrise-soundButton" Other + UUID + 4B75AFAB-109D-42D8-A005-A4977C1EC6F7 + + + Title + Waiting 10.0s for "Bitrise-soundButton" Other to exist + UUID + 718D1D62-D2C3-4DFA-8A31-D2E0E30799A6 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708537.43631196 + StartTimeInterval + 570708537.29023898 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708537.33138204 + StartTimeInterval + 570708537.29133701 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708537.33047795 + StartTimeInterval + 570708537.32226706 + Title + Check for interrupting elements affecting "Bitrise-soundButton" Other + UUID + A3C834D0-6E14-4F98-B0D6-DEDDF802D159 + + + Title + Find the "Bitrise-soundButton" Other + UUID + B0C117DB-18C9-4570-83BF-8E82D68CCA9D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708537.43210495 + StartTimeInterval + 570708537.33349299 + Title + Synthesize event + UUID + 275CAAB9-5358-4968-959C-012A3AAE85C9 + + + Title + Tap "Bitrise-soundButton" Other + UUID + EFEF4014-BF86-4D4D-B762-4BB180A90A0D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708538.60933995 + StartTimeInterval + 570708538.44298601 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708538.50576603 + StartTimeInterval + 570708538.44407499 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708538.50379395 + StartTimeInterval + 570708538.49422705 + Title + Check for interrupting elements affecting "Bitrise-soundButton" Other + UUID + AA2CD091-E27F-4687-A5B2-A132720F7A3B + + + Title + Find the "Bitrise-soundButton" Other + UUID + D51905E7-747A-46FD-B5FF-2D5602A873B5 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708538.60709906 + StartTimeInterval + 570708538.50694501 + Title + Synthesize event + UUID + 908275F5-F527-4BD3-9E91-6930450FBB65 + + + Title + Tap "Bitrise-soundButton" Other + UUID + 22EF8D9C-EEFB-465C-B445-94508E47BA9E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708538.86224997 + StartTimeInterval + 570708538.61005497 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708538.63215804 + StartTimeInterval + 570708538.61220503 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708538.63191199 + StartTimeInterval + 570708538.62871897 + Title + Check for interrupting elements affecting "BitriseApp" Application + UUID + FFC4F878-B4B5-4860-B6BF-1741E5028E7D + + + Title + Find the Target Application 'tv.Bitrise.BitriseApp' + UUID + C6EF8A9D-A963-4173-AE27-6F7DCFC20001 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708538.86037397 + StartTimeInterval + 570708538.63240194 + Title + Synthesize event + UUID + FB523DD7-0229-4E43-9033-30071BC6A093 + + + Title + Swipe down Target Application 'tv.Bitrise.BitriseApp' + UUID + FAD4286B-2F61-44C4-B9DB-3A5B87F4DE93 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708539.16141295 + StartTimeInterval + 570708538.86307502 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708538.90300405 + StartTimeInterval + 570708538.863855 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708538.90225697 + StartTimeInterval + 570708538.89590502 + Title + Check for interrupting elements affecting "BitriseApp" Application + UUID + BA05BE0E-5DF7-4C07-B0CC-A38F648C6307 + + + Title + Find the Target Application 'tv.Bitrise.BitriseApp' + UUID + 483FE001-F120-4414-ACE1-D863DF907478 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708539.15712094 + StartTimeInterval + 570708538.90458 + Title + Synthesize event + UUID + EF2DC990-8AD5-48D1-A68D-20D291384E5D + + + Title + Swipe down Target Application 'tv.Bitrise.BitriseApp' + UUID + E50AFA61-0B7B-4907-B562-6BDF73D4536D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708539.47897506 + StartTimeInterval + 570708539.16317296 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708539.22467804 + StartTimeInterval + 570708539.164639 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708539.22362304 + StartTimeInterval + 570708539.21546304 + Title + Check for interrupting elements affecting "BitriseApp" Application + UUID + 33234FA8-15BB-4CF5-8449-03078B011E75 + + + Title + Find the Target Application 'tv.Bitrise.BitriseApp' + UUID + E0AF57CC-7159-41D0-802F-4045DF96CA01 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708539.47643805 + StartTimeInterval + 570708539.22574496 + Title + Synthesize event + UUID + 0B367C34-7E41-4713-B237-4FB9F60250EE + + + Title + Swipe down Target Application 'tv.Bitrise.BitriseApp' + UUID + 7BE3BCCE-ADA5-4872-BBCB-AA459739F137 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708540.65238297 + StartTimeInterval + 570708540.48498595 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708540.54246402 + StartTimeInterval + 570708540.48641396 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708540.54103601 + StartTimeInterval + 570708540.531129 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + 3CAC3D17-0911-40D9-8321-8FE2E2E9FA71 + + + Title + Find the "go-to-ad-button" Button + UUID + D0823C96-EEA2-4E7E-B51F-F601E7BE810B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708540.64773703 + StartTimeInterval + 570708540.54337704 + Title + Synthesize event + UUID + 8A8ED71D-FFFE-47E9-9160-FB948E0BB139 + + + Title + Tap "go-to-ad-button" Button + UUID + 41DC1563-3D93-4735-B19D-EFC10BD7D295 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708541.73052204 + StartTimeInterval + 570708540.65441406 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708541.727633 + StartTimeInterval + 570708541.68698597 + Title + Checking Expect predicate exists == 1 for object "Bitrise-callButton" Other + UUID + DF77E5D1-EC2A-4A7D-A915-AD89B1C48460 + + + Title + Waiting 10.0s for "Bitrise-callButton" Other to exist + UUID + 24009324-1EBA-47A7-9D89-A8704B8BE441 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708541.87492001 + StartTimeInterval + 570708541.73170698 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708541.76796198 + StartTimeInterval + 570708541.73275006 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708541.76733601 + StartTimeInterval + 570708541.76158202 + Title + Check for interrupting elements affecting "Bitrise-callButton" Other + UUID + 096B09EA-91ED-4D93-8E02-3827443E8372 + + + Title + Find the "Bitrise-callButton" Other + UUID + FCF41118-67C4-49A7-A952-9A777560C7EE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708541.87112105 + StartTimeInterval + 570708541.76869297 + Title + Synthesize event + UUID + CC26A405-2F0B-464B-BE62-8B7151ACDC2E + + + Title + Tap "Bitrise-callButton" Other + UUID + 4AB07C6C-C246-448E-8088-69D607478566 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708544.06986296 + StartTimeInterval + 570708541.87630701 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708542.98693204 + StartTimeInterval + 570708542.89992297 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708542.98115098 + StartTimeInterval + 570708542.94779694 + Title + Snapshot accessibility hierarchy for app with pid 3815 + UUID + C58A1FEB-F560-4D0C-B2DA-EB39B1A7C7FD + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708542.98537195 + StartTimeInterval + 570708542.98338699 + Title + Find: Descendants matching type Button + UUID + B59F0D4B-541F-4171-AA51-C6DE8E19FD02 + + + Title + Checking Expect predicate exists == 1 for object "overlay-toggle-button" Button + UUID + 7E744FA6-89B3-4489-B2A9-182EF045B487 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708544.06838906 + StartTimeInterval + 570708544.01673102 + Title + Checking Expect predicate exists == 1 for object "overlay-toggle-button" Button + UUID + 150BD567-EA9D-4288-99C9-2481E29F3897 + + + Title + Waiting 10.0s for "overlay-toggle-button" Button to exist + UUID + 6DA87479-4116-43B4-BC28-8B099FDCC5E7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708544.20905101 + StartTimeInterval + 570708544.07097197 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708544.10955 + StartTimeInterval + 570708544.07196105 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708544.10875499 + StartTimeInterval + 570708544.10137701 + Title + Check for interrupting elements affecting "overlay-toggle-button" Button + UUID + 77AB23B9-D99A-4666-9E29-6CDAF3370A06 + + + Title + Find the "overlay-toggle-button" Button + UUID + 42461910-8714-4047-AE0B-2AE04013BDF1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708544.20522904 + StartTimeInterval + 570708544.11050296 + Title + Synthesize event + UUID + 8CD942E2-0E12-4772-B235-EE49F250900F + + + Title + Tap "overlay-toggle-button" Button + UUID + FFBE28C3-5FDF-4844-93A4-BBE6CB972D46 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708545.37725604 + StartTimeInterval + 570708545.21551299 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708545.27868295 + StartTimeInterval + 570708545.21719003 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708545.27789497 + StartTimeInterval + 570708545.26849401 + Title + Check for interrupting elements affecting "overlay-toggle-button" Button + UUID + 82A46680-3329-4B28-AC1C-8670FC0358D3 + + + Title + Find the "overlay-toggle-button" Button + UUID + DEA4A935-D530-4CE9-A72B-242F8510036C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708545.37498903 + StartTimeInterval + 570708545.28050005 + Title + Synthesize event + UUID + EF45E167-9E26-476F-9EA2-B87E83ED968C + + + Title + Tap "overlay-toggle-button" Button + UUID + F3F54A45-8151-4379-B5CA-08487278981F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708545.53421795 + StartTimeInterval + 570708545.37853599 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708545.43674302 + StartTimeInterval + 570708545.37931204 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708545.43574595 + StartTimeInterval + 570708545.42676497 + Title + Check for interrupting elements affecting "Bitrise-player" Other + UUID + 5B5DFF0D-C753-4A92-9336-349CA4D831EB + + + Title + Find the "Bitrise-player" Other + UUID + 7280C164-C493-43A0-9E51-9FCF3BC9311A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708545.53240395 + StartTimeInterval + 570708545.43908501 + Title + Synthesize event + UUID + 13F70B5A-5A62-4729-B431-B14FFE91ECA4 + + + Title + Tap "Bitrise-player" Other + UUID + 7242F37A-EC70-4628-8F41-03B467BEDB0C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708546.57945001 + StartTimeInterval + 570708545.53516102 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708546.57814801 + StartTimeInterval + 570708546.55920899 + Title + Checking Expect predicate exists == 1 for object "Bitrise-fullscreenCloseButton" Other + UUID + E5ED5E00-6BFE-4FBD-995B-640771B28D8B + + + Title + Waiting 10.0s for "Bitrise-fullscreenCloseButton" Other to exist + UUID + 308533C8-1948-4530-88DC-5DDADAF732C7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708546.69095898 + StartTimeInterval + 570708546.58014095 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708546.60506999 + StartTimeInterval + 570708546.58085704 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708546.604182 + StartTimeInterval + 570708546.59820497 + Title + Check for interrupting elements affecting "Bitrise-fullscreenCloseButton" Other + UUID + 118676ED-D7F5-4681-95C5-FC5E9172D75E + + + Title + Find the "Bitrise-fullscreenCloseButton" Other + UUID + 1443F509-3F2F-44C5-82FF-E205F521E6E0 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708546.69002295 + StartTimeInterval + 570708546.60627306 + Title + Synthesize event + UUID + 44FC8256-B8E8-4D7F-9E93-50772E817ACA + + + Title + Tap "Bitrise-fullscreenCloseButton" Other + UUID + 8E10F342-90BE-4A3E-8672-582E1027E272 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708547.74537694 + StartTimeInterval + 570708547.71108103 + Title + Checking Expect predicate exists == 1 for object "scroll-to-half-button" Button + UUID + 3C7EBC52-EA02-48BD-A9AC-878636B98A18 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708547.87537706 + StartTimeInterval + 570708547.74686098 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708547.77797997 + StartTimeInterval + 570708547.748294 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708547.77702701 + StartTimeInterval + 570708547.77058899 + Title + Check for interrupting elements affecting "scroll-to-half-button" Button + UUID + C12E4549-08E7-43B5-B6E0-B919A6A02FE9 + + + Title + Find the "scroll-to-half-button" Button + UUID + D6588E1F-3C8F-4EE4-A44B-66494C43B3C9 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708547.87401998 + StartTimeInterval + 570708547.77887797 + Title + Synthesize event + UUID + 17BB8E81-4F39-4866-9C18-130E21FCEE98 + + + Title + Tap "scroll-to-half-button" Button + UUID + A16C7EAA-D888-45E3-8333-E56CE0AE1AC1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708551.06182098 + StartTimeInterval + 570708550.881832 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708550.94917095 + StartTimeInterval + 570708550.88520503 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708550.94804001 + StartTimeInterval + 570708550.94082296 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + 5573ECF6-141A-4C65-A8E6-75BBF7602597 + + + Title + Find the "go-to-ad-button" Button + UUID + 651F34A4-BCEB-4719-98C0-4FEB3D198502 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708551.05744302 + StartTimeInterval + 570708550.950207 + Title + Synthesize event + UUID + 51905F7B-64A5-44A9-9167-297BBDB9EA2B + + + Title + Tap "go-to-ad-button" Button + UUID + AB05A3C9-C570-4D3E-A1A4-929DCB309F58 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708559.57810605 + StartTimeInterval + 570708551.06401706 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708552.14109004 + StartTimeInterval + 570708552.09083796 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 737D39E2-FA97-4BA6-8515-5C910865D157 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708553.202932 + StartTimeInterval + 570708553.15450299 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + CF1DB52A-DE47-4E35-B015-B414BD5CB4F7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708554.28246999 + StartTimeInterval + 570708554.24037397 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 7A5D669C-2B18-4043-9F47-7090E8937727 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708555.36308205 + StartTimeInterval + 570708555.32116997 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + BE35FE1A-A3BF-4108-9361-0088A8C8E1F9 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708556.429021 + StartTimeInterval + 570708556.38792896 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 7A6E4AAE-AD3E-4241-A8F7-A316D4366B01 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708557.49628603 + StartTimeInterval + 570708557.45478797 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 6693CF62-C4E5-405D-8BC8-B49F27157636 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708558.54973304 + StartTimeInterval + 570708558.50857794 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 7FCB4A77-7DB1-4240-8323-715C9CD434B8 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708559.57672095 + StartTimeInterval + 570708559.55468297 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + E258C18F-FA9C-4B62-8FA3-85023443BEC4 + + + Title + Waiting 35.0s for "Bitrise-endScreenReplay" Other to exist + UUID + 3204827C-45E7-489F-844A-B0CAC6F0A78A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708559.70789099 + StartTimeInterval + 570708559.57937098 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708559.61468303 + StartTimeInterval + 570708559.58014596 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708559.61381102 + StartTimeInterval + 570708559.60631704 + Title + Check for interrupting elements affecting "Bitrise App" Button + UUID + EAFADBB8-7321-4249-A7E9-A2B47D8D3FCF + + + Title + Find the "Bitrise App" Button + UUID + FDAD3D6C-6FCC-495D-B332-D05A8D496412 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708559.70466805 + StartTimeInterval + 570708559.61564803 + Title + Synthesize event + UUID + 2BB9847A-AF44-4447-B708-C17EA78BF0BC + + + Title + Tap "Bitrise App" Button + UUID + 162A9D80-F9D9-4E34-9AD0-E29FCD1C0016 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708560.79143202 + StartTimeInterval + 570708559.70888102 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708560.79003 + StartTimeInterval + 570708560.72850502 + Title + Checking Expect predicate exists == 1 for object "Load" Button + UUID + 1C0D258A-FF27-41C1-A2E5-0AA334577337 + + + Title + Waiting 5.0s for "Load" Button to exist + UUID + F86FEE1D-9B11-4470-A818-D2356009326D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708561.89532697 + StartTimeInterval + 570708560.79889905 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708561.89393497 + StartTimeInterval + 570708560.800318 + Title + Terminate tv.Bitrise.BitriseApp:3815 + UUID + 9ABAB48D-73C9-49E7-8A3B-CB96C8A0CE20 + + + Title + Tear Down + UUID + 3704E9BC-B30E-48CF-9D17-BC114C28FBA3 + + + Duration + 39.105541944503784 + TestIdentifier + BitriseOMUITests/testOMScrollView() + TestName + testOMScrollView() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + 97BCE686-3F55-482D-9EBD-3F9F6FAB0CA7 + + + TestIdentifier + BitriseOMUITests + TestName + BitriseOMUITests + TestObjectClass + IDESchemeActionTestSummaryGroup + + + Duration + 28.363937973976135 + Subtests + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708561.92838001 + StartTimeInterval + 570708561.89883995 + Title + Start Test at 2019-02-01 05:09:21.899 + UUID + F3AE40C9-710B-4C4F-87B1-CD1304D74857 + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708561.89883995 + StartTimeInterval + 570708561.89883995 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + CDF01A51-C082-4CC6-9BAE-1F7086E51218 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708561.97923803 + StartTimeInterval + 570708561.92974496 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708561.95673597 + StartTimeInterval + 570708561.93217504 + Title + Terminate tv.Bitrise.BitriseApp:0 + UUID + E3A12126-5BB7-4952-8D15-837C346219DF + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708561.97848403 + StartTimeInterval + 570708561.95806706 + Title + Terminate tv.Bitrise.BitriseApp:0 + UUID + 02F19645-E0AB-40F4-A571-95747DCFE8FF + + + Title + Set Up + UUID + 5C2784B8-0D97-4A8F-8D6D-6148876100AA + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708565.440804 + StartTimeInterval + 570708561.98241603 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708565.43941498 + StartTimeInterval + 570708562.00144994 + Title + Launch tv.Bitrise.BitriseApp + UUID + 0F90B00A-0E23-474B-9C17-CA3606F53824 + + + Title + Open tv.Bitrise.BitriseApp + UUID + 7A5C8FE4-B5BF-4B78-A5F5-B9C696600B4A + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708568.50801504 + StartTimeInterval + 570708565.44227397 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708566.54391897 + StartTimeInterval + 570708566.47593999 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + AC16A59A-1362-4738-939C-FA2AD922C497 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708566.56423104 + StartTimeInterval + 570708566.54525101 + Title + Find the "pidTextField" TextField + UUID + E76550C2-3ED1-48A9-9835-947D2A836454 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708566.58290195 + StartTimeInterval + 570708566.56763506 + Title + Find the "pidTextField" TextField + UUID + 681074B9-FBE1-462B-AF18-8F158DDA29D7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708566.71715999 + StartTimeInterval + 570708566.585814 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708566.61224699 + StartTimeInterval + 570708566.58706605 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708566.61155903 + StartTimeInterval + 570708566.60452104 + Title + Check for interrupting elements affecting "pidTextField" TextField + UUID + 6BAB15A8-A4EC-4AAA-AD33-2AD21DA6DC6A + + + Title + Find the "pidTextField" TextField + UUID + 2928B6FD-2BB8-4A48-B7C1-9D2C50487563 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708566.71567905 + StartTimeInterval + 570708566.61291301 + Title + Synthesize event + UUID + BC79459F-C713-41DB-99C3-BD2BB5106CF4 + + + Title + Tap "pidTextField" TextField + UUID + 36F0DAE3-629F-4A94-B130-F75BA8143AD7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708566.94401801 + StartTimeInterval + 570708566.71797502 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708566.82867503 + StartTimeInterval + 570708566.71866 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708566.82778394 + StartTimeInterval + 570708566.82013297 + Title + Check for interrupting elements affecting "pidTextField" TextField + UUID + F721DC4C-1345-4E77-9FE4-9DA7005190A4 + + + Title + Find the "pidTextField" TextField + UUID + 9160FACE-1775-41C4-A97E-D251F3DE6C3B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708566.94287801 + StartTimeInterval + 570708566.82967603 + Title + Synthesize event + UUID + 8EF83E1E-5813-4067-B97A-FCA89B9F3F63 + + + Title + Type '' into "pidTextField" TextField + UUID + D6F5E5C2-BADD-4B1A-AB7E-8437E49B8C5F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708567.11089098 + StartTimeInterval + 570708566.94480598 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708566.98546898 + StartTimeInterval + 570708566.94555604 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708566.98466206 + StartTimeInterval + 570708566.979002 + Title + Check for interrupting elements affecting "pidTextField" TextField + UUID + 3FF27059-4862-4032-BBE4-A70451CAD535 + + + Title + Find the "pidTextField" TextField + UUID + 6A7456EE-CBE4-4CCB-8CE9-0DE06F0D2B4A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708567.108971 + StartTimeInterval + 570708566.98634303 + Title + Synthesize event + UUID + F1901FDA-FECD-4DF3-93FE-E1499FFB5877 + + + Title + Type '12345' into "pidTextField" TextField + UUID + 43FD51D6-200E-4704-AA40-FD29F7B3B352 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708568.18663895 + StartTimeInterval + 570708568.12604797 + Title + Checking Expect predicate exists == 1 for object "pid-keyboard-done-button" Button + UUID + C9F6AE20-9F04-42CB-9030-F4101232D25A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708568.33017695 + StartTimeInterval + 570708568.18840206 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708568.23836601 + StartTimeInterval + 570708568.19111001 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708568.23735201 + StartTimeInterval + 570708568.23014402 + Title + Check for interrupting elements affecting "pid-keyboard-done-button" Button + UUID + E15DABDB-F2FC-488F-B90A-5C2493F2554A + + + Title + Find the "pid-keyboard-done-button" Button + UUID + D1FBE55A-730B-4AA5-9FCB-EB219B9FEF38 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708568.32851005 + StartTimeInterval + 570708568.23916495 + Title + Synthesize event + UUID + C6D79841-5EB1-4161-85A2-62F91337505F + + + Title + Tap "pid-keyboard-done-button" Button + UUID + B1AD4AE2-16B1-4162-A1C5-24AF5E2502B7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708568.39972603 + StartTimeInterval + 570708568.33154905 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708568.38013101 + StartTimeInterval + 570708568.33269095 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708568.37970495 + StartTimeInterval + 570708568.37568796 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + 642533D8-3916-44CF-A44A-6FD4B90D4015 + + + Title + Find the PickerWheel + UUID + 372C5344-514D-4805-A4DD-2D7545A8B917 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708568.39927101 + StartTimeInterval + 570708568.38057697 + Title + Synthesize event + UUID + F4BD9E87-6F4E-49CD-9A8E-49524FD2CA30 + + + Title + Set value of PickerWheel to ScrollViewController + UUID + 33122D24-F665-4AA9-9E07-31FAFA0F13D7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708568.50742805 + StartTimeInterval + 570708568.40009499 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708568.43180394 + StartTimeInterval + 570708568.40037894 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708568.43136895 + StartTimeInterval + 570708568.42717099 + Title + Check for interrupting elements affecting "Load" Button + UUID + 22A3E3D9-EEEF-47B4-BA1A-8EA5C32851DF + + + Title + Find the "Load" Button + UUID + CB4BA2C9-DBFB-4A65-AEC5-3FD9EFC6B51C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708568.50656903 + StartTimeInterval + 570708568.43223703 + Title + Synthesize event + UUID + D4B8A14C-1D03-40FC-9258-C370181C3267 + + + Title + Tap "Load" Button + UUID + 571BAF68-A60B-4452-A070-F8D5259B7EB0 + + + Title + I change the PID and tap on Load + UUID + C109FDA3-4D72-4601-88B4-4CD73B2662CB + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708569.60545897 + StartTimeInterval + 570708569.57790399 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + B4D8C512-C506-4E23-BDA9-F6036D838A0B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708569.74579501 + StartTimeInterval + 570708569.60661197 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708569.64914095 + StartTimeInterval + 570708569.60724401 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708569.64846802 + StartTimeInterval + 570708569.640118 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + 49197228-6493-4B2A-948F-FC98F13E9D3F + + + Title + Find the "go-to-ad-button" Button + UUID + 2B92AD84-75E9-4279-9D8E-DADBE0E87315 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708569.74389505 + StartTimeInterval + 570708569.65010798 + Title + Synthesize event + UUID + 2252360E-C894-44ED-B5D5-CEFB9A219678 + + + Title + Tap "go-to-ad-button" Button + UUID + E41E95D8-A154-41A5-A31B-978C982C8516 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708570.83117294 + StartTimeInterval + 570708569.74662197 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708570.830163 + StartTimeInterval + 570708570.77718496 + Title + Checking Expect predicate exists == 1 for object "Bitrise-player" Other + UUID + 35AF5225-34FE-4064-ADC2-1E5093590327 + + + Title + Waiting 10.0s for "Bitrise-player" Other to exist + UUID + C1282B75-96C7-41C7-815C-EE79083476C4 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708577.33095503 + StartTimeInterval + 570708570.83203101 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708571.95379996 + StartTimeInterval + 570708571.90565002 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 5DA64080-71B3-4D0D-9BAB-63AD8D77B23C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708573.053406 + StartTimeInterval + 570708573.00457394 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 6AA9DD1C-3186-4B79-AC43-F9082FFF6F4D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708574.10367298 + StartTimeInterval + 570708574.055848 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 2EC4E15F-542A-47F8-84EA-744380DEC348 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708575.14103198 + StartTimeInterval + 570708575.11445701 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 8BF07C47-7C6D-471D-9FEF-A87F49146F1F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708576.24021602 + StartTimeInterval + 570708576.197649 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + EA9549EC-E291-400A-8748-B43487B26083 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708577.32913303 + StartTimeInterval + 570708577.27273095 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 1E0FD038-7DC0-4622-8DF9-C297B5165AA9 + + + Title + Waiting 20.0s for "Bitrise-endScreenReplay" Other to exist + UUID + C076CC3D-8E32-4164-9794-74DFAF294D30 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708578.45830095 + StartTimeInterval + 570708577.33443201 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708578.42363799 + StartTimeInterval + 570708577.33699799 + Title + Terminate tv.Bitrise.BitriseApp:3900 + UUID + A4DA5FA4-CCDF-4B2E-8170-68D5B6855A11 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708578.45645297 + StartTimeInterval + 570708578.42581499 + Title + Terminate tv.Bitrise.BitriseApp:0 + UUID + 0C6400B3-A2F0-49B7-94F3-78E67EF6EB97 + + + Title + Tear Down + UUID + BCAAB402-52FB-4890-94D1-DDC952C529AB + + + Duration + 16.561162948608398 + TestIdentifier + BitriseTrackingsUITest/testTrackingsWithAd() + TestName + testTrackingsWithAd() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + 608DEBC3-00E1-41FE-9B41-6F23735DDF55 + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708578.49080396 + StartTimeInterval + 570708578.46076596 + Title + Start Test at 2019-02-01 05:09:38.461 + UUID + FA64E1E2-0442-4974-8DE1-FCB3D88335D6 + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708578.46076596 + StartTimeInterval + 570708578.46076596 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + 244F8E45-F25A-41A8-B437-334A817AC0B9 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708578.53146303 + StartTimeInterval + 570708578.49157906 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708578.51321805 + StartTimeInterval + 570708578.49283099 + Title + Terminate tv.Bitrise.BitriseApp:0 + UUID + EB40B26E-87CB-42C9-8E66-44736A00A445 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708578.53101206 + StartTimeInterval + 570708578.51423204 + Title + Terminate tv.Bitrise.BitriseApp:0 + UUID + C71E87E0-4C47-4EC1-9DCD-C484442B25DC + + + Title + Set Up + UUID + D1DB7177-8FB9-40BC-8EA2-B33603D6F0A1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708581.66572905 + StartTimeInterval + 570708578.53303695 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708581.66439605 + StartTimeInterval + 570708578.549438 + Title + Launch tv.Bitrise.BitriseApp + UUID + 2F6C54AF-8804-4FD3-B29F-75EDC28822A8 + + + Title + Open tv.Bitrise.BitriseApp + UUID + 93CEA3B9-32AE-4917-AFD9-74DD7B0592C1 + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708582.97683501 + StartTimeInterval + 570708581.66736805 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708582.761482 + StartTimeInterval + 570708582.686113 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 588F5B8D-A885-4886-9B12-E974289F42C4 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708582.78750896 + StartTimeInterval + 570708582.76513398 + Title + Find the "pidTextField" TextField + UUID + BA84023F-8977-4DFA-8447-DC47F3FBF5F9 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708582.85089004 + StartTimeInterval + 570708582.78837204 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708582.81502903 + StartTimeInterval + 570708582.78915405 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708582.81413805 + StartTimeInterval + 570708582.80825496 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + BACDDC1F-8069-4BB1-A206-5E203B68380D + + + Title + Find the PickerWheel + UUID + 33A4F319-32BC-41F8-845F-3E35A5EA99D9 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708582.850196 + StartTimeInterval + 570708582.81646502 + Title + Synthesize event + UUID + 167B77A5-C9E9-4221-B2F5-AC5008EDB050 + + + Title + Set value of PickerWheel to ScrollViewController + UUID + 5E66A21B-FA5F-4A1E-8A39-401CBA569225 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708582.97610104 + StartTimeInterval + 570708582.85158098 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708582.88554597 + StartTimeInterval + 570708582.85198903 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708582.88510299 + StartTimeInterval + 570708582.880023 + Title + Check for interrupting elements affecting "Load" Button + UUID + 4764CD44-73A9-4870-A662-7781DDCD3F89 + + + Title + Find the "Load" Button + UUID + 2F37827E-75F7-4B6F-9544-F3E594BF111E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708582.97462904 + StartTimeInterval + 570708582.88596904 + Title + Synthesize event + UUID + 5EE2C6A4-EB22-429C-8C68-87E4EA47CFE1 + + + Title + Tap "Load" Button + UUID + 585328EE-10EA-455C-86E7-D74807356320 + + + Title + I change the PID and tap on Load + UUID + AE0A3A22-0F6A-41EF-8D6E-361C1D0903F3 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708584.01254106 + StartTimeInterval + 570708583.98731697 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + 3E0CF4FD-E1BA-4A2F-A434-C183CAC35978 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708584.145239 + StartTimeInterval + 570708584.01396 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708584.03955805 + StartTimeInterval + 570708584.01479304 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708584.03843904 + StartTimeInterval + 570708584.03209901 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + E8AD92F6-79D7-4150-91F3-64A16133051A + + + Title + Find the "go-to-ad-button" Button + UUID + F8DEAE12-D138-48DF-895E-08C2AC107FCF + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708584.14279401 + StartTimeInterval + 570708584.040681 + Title + Synthesize event + UUID + E6ACB237-0577-404B-88F3-33841F785B79 + + + Title + Tap "go-to-ad-button" Button + UUID + 55442FA6-A9D1-47AC-98F8-AA5D1FFB978F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708589.15328896 + StartTimeInterval + 570708584.14713001 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708585.27065301 + StartTimeInterval + 570708585.22058403 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + FF17E688-3BDB-4FC0-918A-925B38AFD8F4 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708586.31870306 + StartTimeInterval + 570708586.28702199 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 8CABC273-7823-47C1-A9A0-292F3478A6DD + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708587.38328004 + StartTimeInterval + 570708587.35384095 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 2A95C4E5-4106-4FA9-8028-3E9EB09D2C6B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708588.406371 + StartTimeInterval + 570708588.38709903 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + EF602752-C8C2-430B-8775-3721EB1C5DD7 + + + Title + Waiting 5.0s for "Bitrise-endScreenReplay" Other to exist + UUID + 02C9A7AF-7312-4399-8A65-EB2440AB5DCF + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708590.26035905 + StartTimeInterval + 570708589.17011702 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708590.20886803 + StartTimeInterval + 570708589.17208695 + Title + Terminate tv.Bitrise.BitriseApp:3945 + UUID + 24DED21C-F012-4B0D-89F1-F3CCA26BB6EB + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708590.25913298 + StartTimeInterval + 570708590.21322405 + Title + Terminate tv.Bitrise.BitriseApp:0 + UUID + 1EDBBB59-3CFF-4522-905E-CE25B4B7C82C + + + Title + Tear Down + UUID + B5920124-06B5-4370-B9F2-CA0C67237707 + + + Duration + 11.800962090492249 + TestIdentifier + BitriseTrackingsUITest/testTrackingsWithNoAd() + TestName + testTrackingsWithNoAd() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + 99739FA7-D47E-48E2-9CD4-A5E88CE9ACBF + + + TestIdentifier + BitriseTrackingsUITest + TestName + BitriseTrackingsUITest + TestObjectClass + IDESchemeActionTestSummaryGroup + + + Duration + 152.81191599369049 + Subtests + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708590.28506601 + StartTimeInterval + 570708590.26337004 + Title + Start Test at 2019-02-01 05:09:50.263 + UUID + 4D0D67A4-C888-4801-B8A9-7F8961A2575C + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708590.26337004 + StartTimeInterval + 570708590.26337004 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + CF74EF8E-D1EC-41FB-AD1C-344B857D3EAD + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708593.45126104 + StartTimeInterval + 570708590.28575695 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708593.45007598 + StartTimeInterval + 570708590.28715599 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708593.44867003 + StartTimeInterval + 570708590.30535901 + Title + Launch tv.Bitrise.BitriseApp + UUID + F4F7959E-4CDA-4CFA-8A00-F0946D4A9F52 + + + Title + Open tv.Bitrise.BitriseApp + UUID + 9BD4F489-DD10-4DE1-B804-5594476F6F8F + + + Title + Set Up + UUID + 871700D1-CABC-4742-A019-6CD0E4FE4FB6 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708597.68303597 + StartTimeInterval + 570708593.45661402 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708597.68176401 + StartTimeInterval + 570708593.48140597 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708594.59163594 + StartTimeInterval + 570708593.48269701 + Title + Terminate tv.Bitrise.BitriseApp:3963 + UUID + 26C45240-335D-488B-8C46-0FDED09B87BA + + + Title + Launch tv.Bitrise.BitriseApp + UUID + 148140CF-5A6A-4AC6-A3A9-F87FE9936EDE + + + Title + Open tv.Bitrise.BitriseApp + UUID + 20DA2A03-AA48-4E6C-AD7E-82757007B1E6 + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708598.98473704 + StartTimeInterval + 570708597.68389595 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708598.76348603 + StartTimeInterval + 570708598.68730998 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 74CEAE9A-0684-4BD5-9CA3-DC10C060B551 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708598.78930795 + StartTimeInterval + 570708598.76624703 + Title + Find the "pidTextField" TextField + UUID + E23B4595-9A0B-4696-A14F-66FE3C30FC54 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708598.85527503 + StartTimeInterval + 570708598.79042006 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708598.81698799 + StartTimeInterval + 570708598.79114401 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708598.81583798 + StartTimeInterval + 570708598.80990899 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + 5B807F6E-9FFD-4C1B-85C3-1A5CA9B72973 + + + Title + Find the PickerWheel + UUID + 8C8AA299-BCBE-4514-99F9-91551FCD08DB + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708598.854182 + StartTimeInterval + 570708598.81787598 + Title + Synthesize event + UUID + 9760CFDF-11FB-4D13-9BB9-4A0EFA026121 + + + Title + Set value of PickerWheel to ScrollViewController + UUID + AFA81BE4-6BB6-46C1-922B-502EA3BF2A21 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708598.98411798 + StartTimeInterval + 570708598.85623395 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708598.89133501 + StartTimeInterval + 570708598.85688198 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708598.89083505 + StartTimeInterval + 570708598.88582206 + Title + Check for interrupting elements affecting "Load" Button + UUID + 405DC40C-CF91-4E84-9EE0-B6D88B9DFD6C + + + Title + Find the "Load" Button + UUID + B204FB87-FFD3-4DEC-8DBD-4CC5B14AACDF + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708598.98263597 + StartTimeInterval + 570708598.89188194 + Title + Synthesize event + UUID + 49583B09-2924-4E37-BD22-461F34717A32 + + + Title + Tap "Load" Button + UUID + 2BE92357-194A-4E0D-AED4-11F3E5172316 + + + Title + I change the PID and tap on Load + UUID + D7DEDF9C-CE50-4118-AF27-9344E659227F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708600.08303595 + StartTimeInterval + 570708600.02996802 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + 53C6318D-19C1-4CDA-8719-F1CE8DF196A5 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708600.22021103 + StartTimeInterval + 570708600.084782 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708600.11332798 + StartTimeInterval + 570708600.08578396 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708600.11248195 + StartTimeInterval + 570708600.10620403 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + 51E18D4A-2231-4B4A-B019-FFAB8500EF7A + + + Title + Find the "go-to-ad-button" Button + UUID + E258D8E1-8A64-4E77-AEAC-922AC0E05422 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708600.21724403 + StartTimeInterval + 570708600.11414599 + Title + Synthesize event + UUID + 766EEFA1-999F-4F57-B086-71947505681A + + + Title + Tap "go-to-ad-button" Button + UUID + F9E93D72-819D-46B7-A259-493D1366CF92 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708605.22467005 + StartTimeInterval + 570708600.22147596 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708601.28526497 + StartTimeInterval + 570708601.23361003 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 3C7408BF-4709-4335-AD96-3C01821B6380 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708602.34661198 + StartTimeInterval + 570708602.31970298 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 1A4B6EF8-C20F-48EB-A131-44E09414AACC + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708603.37917805 + StartTimeInterval + 570708603.35374904 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 4CB8AED7-A8EB-4837-AA1C-27952250F255 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708604.41151905 + StartTimeInterval + 570708604.38707602 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 5AAF38EA-9595-4435-8CF5-EBD4C0C8FF9D + + + Title + Waiting 5.0s for "Bitrise-endScreenReplay" Other to exist + UUID + FF0AB3E1-8E01-480D-84CA-950DC7DE172F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708606.32383299 + StartTimeInterval + 570708605.24000001 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708606.32140803 + StartTimeInterval + 570708605.24105299 + Title + Terminate tv.Bitrise.BitriseApp:3969 + UUID + 0325573C-6920-4A6B-86E2-0987420C70F0 + + + Title + Tear Down + UUID + C4EACA6C-F9E0-4B46-95C8-ECA95EA0CD49 + + + Duration + 16.062182068824768 + TestIdentifier + bitrErrorUITest/testbitrError403() + TestName + testbitrError403() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + A7751CF4-F785-446E-B7B3-9B17486396FE + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708606.36616397 + StartTimeInterval + 570708606.326774 + Title + Start Test at 2019-02-01 05:10:06.327 + UUID + 5A31E9C3-4865-4159-9976-35E228C71AF3 + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708606.326774 + StartTimeInterval + 570708606.326774 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + 2DBE1E05-2C1A-49FC-9CB5-42431C33E7E8 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708609.46335697 + StartTimeInterval + 570708606.36797094 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708609.46215403 + StartTimeInterval + 570708606.37050402 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708609.460917 + StartTimeInterval + 570708606.39138496 + Title + Launch tv.Bitrise.BitriseApp + UUID + 953B0710-2DC7-4B07-854B-C3762901832A + + + Title + Open tv.Bitrise.BitriseApp + UUID + AF8D25C7-D248-4827-AA50-51BCD850B21E + + + Title + Set Up + UUID + 2C26606E-E1CA-4004-B5DF-F21B5383C1BC + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708613.71951604 + StartTimeInterval + 570708609.46748495 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708613.71784306 + StartTimeInterval + 570708609.49167204 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708610.57589197 + StartTimeInterval + 570708609.49285603 + Title + Terminate tv.Bitrise.BitriseApp:3988 + UUID + 66D5C69C-041D-41E1-B177-1DF881B8A487 + + + Title + Launch tv.Bitrise.BitriseApp + UUID + 3A7B43C4-2C18-4229-BEC4-AF44EDCC237B + + + Title + Open tv.Bitrise.BitriseApp + UUID + 343F5920-7E6F-40D9-9A00-A259F028A557 + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708615.03284001 + StartTimeInterval + 570708613.72086501 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708614.81421804 + StartTimeInterval + 570708614.73732305 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 907A6E64-F896-4B18-9A5F-27AEE2A95F46 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708614.84395301 + StartTimeInterval + 570708614.81878996 + Title + Find the "pidTextField" TextField + UUID + 5A92D759-8218-490F-AAA1-F0BCB521EEDC + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708614.90628397 + StartTimeInterval + 570708614.84485197 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708614.87256098 + StartTimeInterval + 570708614.84561205 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708614.87175596 + StartTimeInterval + 570708614.86569405 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + 1EC9FC0B-BE63-4D5D-9780-AF1782AAAF57 + + + Title + Find the PickerWheel + UUID + 76CF293E-B71A-450D-9030-E8DD6AE29655 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708614.90564597 + StartTimeInterval + 570708614.87346697 + Title + Synthesize event + UUID + 57ABC529-89D3-428F-8161-DB0ACE9F8560 + + + Title + Set value of PickerWheel to ScrollViewController + UUID + 3664F934-5447-4724-826C-09AD038FD5F5 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708615.03109002 + StartTimeInterval + 570708614.90683603 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708614.93543804 + StartTimeInterval + 570708614.90726495 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708614.93456304 + StartTimeInterval + 570708614.92922699 + Title + Check for interrupting elements affecting "Load" Button + UUID + F646BB77-E210-4D53-995F-E940CFF0BA7F + + + Title + Find the "Load" Button + UUID + 728F2A0F-66D3-40E7-90FB-A3739172AD6A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708615.02988005 + StartTimeInterval + 570708614.93632996 + Title + Synthesize event + UUID + C3590189-53E7-4EEE-B22E-0A03FF61266F + + + Title + Tap "Load" Button + UUID + 4B46E3F0-E0D0-413D-A10C-B762B009B596 + + + Title + I change the PID and tap on Load + UUID + 302BEAD0-1D55-473E-8594-EBE0EE6689E5 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708616.12509 + StartTimeInterval + 570708616.08730102 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + 6D9402B3-D1C9-43C5-A7FB-F49E8B01D0A6 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708616.25921905 + StartTimeInterval + 570708616.12664795 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708616.15800703 + StartTimeInterval + 570708616.12746704 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708616.15732503 + StartTimeInterval + 570708616.14883602 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + 2A88C25D-0F05-4B38-A90D-B7A3BE1ECD97 + + + Title + Find the "go-to-ad-button" Button + UUID + 159362BA-3E8D-4FBA-B0C3-D5F3A2F8DC9F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708616.25583994 + StartTimeInterval + 570708616.15905201 + Title + Synthesize event + UUID + A2C894C5-B264-41B7-BD89-C0624200B464 + + + Title + Tap "go-to-ad-button" Button + UUID + 6C1576EF-9578-44CE-B63E-5D35C6877C3A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708621.26441002 + StartTimeInterval + 570708616.26059997 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708617.33729398 + StartTimeInterval + 570708617.28731501 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + B0D5DB09-4178-4C5C-9071-5394A92056D7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708618.38042498 + StartTimeInterval + 570708618.35381198 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 7949D3F4-0432-4426-B580-9A5ECBD3B37B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708619.43102503 + StartTimeInterval + 570708619.40683806 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + D8691AC3-E851-409F-A5BE-7B94E4D7434A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708620.48268294 + StartTimeInterval + 570708620.45782602 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + F42A569D-EA47-44FC-9670-0F6A6F3F4FBB + + + Title + Waiting 5.0s for "Bitrise-endScreenReplay" Other to exist + UUID + FEC03322-DA1D-42E7-9071-2E78231B100F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708622.445755 + StartTimeInterval + 570708621.32302904 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708622.44305599 + StartTimeInterval + 570708621.32436502 + Title + Terminate tv.Bitrise.BitriseApp:3994 + UUID + 6C544856-4711-4E3D-8544-247F95FC5595 + + + Title + Tear Down + UUID + 803F03ED-DAFB-4730-A336-FE96C56C4706 + + + Duration + 16.120810031890869 + TestIdentifier + bitrErrorUITest/testbitrError405() + TestName + testbitrError405() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + BAA7A9E8-0DEB-442F-B9A6-71D97FAD1CA9 + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708622.47914302 + StartTimeInterval + 570708622.44786501 + Title + Start Test at 2019-02-01 05:10:22.448 + UUID + A8C22478-F628-4912-89CB-F4D0EAA58B9A + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708622.44786501 + StartTimeInterval + 570708622.44786501 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + 061446B0-D6C1-42FE-A75A-67FC48257735 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708625.65702498 + StartTimeInterval + 570708622.48078704 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708625.65575099 + StartTimeInterval + 570708622.483567 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708625.654266 + StartTimeInterval + 570708622.51001203 + Title + Launch tv.Bitrise.BitriseApp + UUID + E8FCE4AF-ED27-4834-8EC1-3CC38D9DCD83 + + + Title + Open tv.Bitrise.BitriseApp + UUID + 6DD20C24-7683-4748-BDC5-A82A5EDFF2A8 + + + Title + Set Up + UUID + E8A3E6C2-0343-4FEB-AFAC-0ED41348A154 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708630.292117 + StartTimeInterval + 570708625.66128898 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708630.29014397 + StartTimeInterval + 570708625.68974197 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708626.80482399 + StartTimeInterval + 570708625.69113505 + Title + Terminate tv.Bitrise.BitriseApp:4025 + UUID + 068EDC97-FA7A-4E2E-8402-F64903893A35 + + + Title + Launch tv.Bitrise.BitriseApp + UUID + DB9A1280-5624-4C77-B1A3-44311BF0D2F6 + + + Title + Open tv.Bitrise.BitriseApp + UUID + 5B8B91D1-2EC8-4D69-9602-082DF447942E + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708631.58804095 + StartTimeInterval + 570708630.29337394 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708631.38118804 + StartTimeInterval + 570708631.30395198 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + FBBE24D2-4341-44FC-8F9E-95E12C00CEF3 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708631.40393603 + StartTimeInterval + 570708631.38380599 + Title + Find the "pidTextField" TextField + UUID + 42834AA5-2BD6-4541-8ED4-DE20B2C8937D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708631.46630096 + StartTimeInterval + 570708631.40483296 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708631.43522894 + StartTimeInterval + 570708631.40574598 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708631.43435204 + StartTimeInterval + 570708631.42781305 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + 0641D414-2A4A-4B64-93CB-FF69B5C9EF3E + + + Title + Find the PickerWheel + UUID + 2FC3D5D7-A4D8-49A0-A45D-28480BD2E0AE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708631.465729 + StartTimeInterval + 570708631.43657601 + Title + Synthesize event + UUID + 9D81F209-C4EF-476C-BD81-F6D1FD5C2927 + + + Title + Set value of PickerWheel to ScrollViewController + UUID + 8347E40F-27F9-48F8-8361-7D7104A9AFA2 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708631.58718097 + StartTimeInterval + 570708631.46691 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708631.49788797 + StartTimeInterval + 570708631.46736896 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708631.497473 + StartTimeInterval + 570708631.49306405 + Title + Check for interrupting elements affecting "Load" Button + UUID + 873173C3-7BE4-461D-8B73-77AF34AEB08B + + + Title + Find the "Load" Button + UUID + 88CF3A11-32BC-42C9-B169-B0D126159334 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708631.58558404 + StartTimeInterval + 570708631.49832296 + Title + Synthesize event + UUID + 95A4D6E5-CE33-41B8-A908-042650D79BCC + + + Title + Tap "Load" Button + UUID + E846F577-BAAD-4F4A-8C7A-A8F049CC1736 + + + Title + I change the PID and tap on Load + UUID + 9424FC17-6D1E-4455-BFAD-E2F5F142378B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708632.66278803 + StartTimeInterval + 570708632.63705504 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + 7302BC4E-ED4A-43E1-B8FE-5A4435A17679 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708632.786327 + StartTimeInterval + 570708632.66400504 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708632.69312203 + StartTimeInterval + 570708632.66456497 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708632.69233596 + StartTimeInterval + 570708632.68585396 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + 18A65FAC-32D8-4956-8267-C909066AAFA0 + + + Title + Find the "go-to-ad-button" Button + UUID + B608026C-5D5A-46A7-B08E-EF1CA9771A90 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708632.78475404 + StartTimeInterval + 570708632.69395494 + Title + Synthesize event + UUID + 4A40AFDF-0E51-4FB4-B573-41FDE2A5B935 + + + Title + Tap "go-to-ad-button" Button + UUID + BCC0E002-89B2-4C28-92ED-4DA150A1EAA3 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708637.79358304 + StartTimeInterval + 570708632.78730094 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708633.86084294 + StartTimeInterval + 570708633.80932403 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + E7F27021-E1E2-46FF-93F6-1AC66FB53963 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708634.91071105 + StartTimeInterval + 570708634.87061799 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 363E07BC-B0CD-495C-87CC-9F280AAE6A17 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708635.96109295 + StartTimeInterval + 570708635.92066097 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + F3F3B0D6-9555-4613-ADBD-5F2E3F1CB2D1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708637.01135898 + StartTimeInterval + 570708636.97058904 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + FD6016E1-7CF4-4867-9560-3D7D7AC6BDEC + + + Title + Waiting 5.0s for "Bitrise-endScreenReplay" Other to exist + UUID + EDC0B068-26A5-448A-A2FF-851AF4343C93 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708638.91275704 + StartTimeInterval + 570708637.80700099 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708638.91034305 + StartTimeInterval + 570708637.80781996 + Title + Terminate tv.Bitrise.BitriseApp:4031 + UUID + 5EB8109C-9F4D-4043-9551-63C2C6A8C6FB + + + Title + Tear Down + UUID + FC3DC296-0501-4260-8D1D-11861C352CEF + + + Duration + 16.466439008712769 + TestIdentifier + bitrErrorUITest/testbitrError901() + TestName + testbitrError901() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + F7BDB60F-F9B6-4EAC-88CE-0DE50D80348A + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708638.94542694 + StartTimeInterval + 570708638.91499805 + Title + Start Test at 2019-02-01 05:10:38.915 + UUID + 0705E20B-D4A6-4925-88E9-952EDBE857C3 + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708638.91499805 + StartTimeInterval + 570708638.91499805 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + 3667CBEF-49CB-4F9C-A572-0C701C3C3A9B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708642.531232 + StartTimeInterval + 570708638.94730699 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708642.529863 + StartTimeInterval + 570708638.95024097 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708642.52852905 + StartTimeInterval + 570708638.97575295 + Title + Launch tv.Bitrise.BitriseApp + UUID + 1A54C95E-567B-41AF-8D29-74BABA8D5968 + + + Title + Open tv.Bitrise.BitriseApp + UUID + 39962A09-10D5-446B-983F-F84F6262C916 + + + Title + Set Up + UUID + 31236246-DA98-4751-ACC3-696299CB3CFA + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708646.75791299 + StartTimeInterval + 570708642.53536606 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708646.75394905 + StartTimeInterval + 570708642.56006706 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708643.67144501 + StartTimeInterval + 570708642.56116498 + Title + Terminate tv.Bitrise.BitriseApp:4063 + UUID + 15D49268-A023-4B98-A91B-BD2BF29EA04D + + + Title + Launch tv.Bitrise.BitriseApp + UUID + 6539EB4E-D5B6-4393-817A-1DA906922AF8 + + + Title + Open tv.Bitrise.BitriseApp + UUID + DB1AB547-6DE4-4F6D-B46D-52D07F4E176D + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708648.05799103 + StartTimeInterval + 570708646.76098204 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708647.84608495 + StartTimeInterval + 570708647.77063298 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 498FCB33-022E-4FBA-B768-91A9FB5806B4 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708647.87205696 + StartTimeInterval + 570708647.84976602 + Title + Find the "pidTextField" TextField + UUID + 427B9B73-8420-43E6-BA4C-406C78201834 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708647.93429005 + StartTimeInterval + 570708647.87308502 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708647.89978099 + StartTimeInterval + 570708647.87382305 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708647.89903104 + StartTimeInterval + 570708647.89319205 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + BDE36DB3-9062-4FFF-B48C-55223E768B97 + + + Title + Find the PickerWheel + UUID + 988636B0-6FA9-468C-945D-6F7A6DE8C32F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708647.93369102 + StartTimeInterval + 570708647.90055704 + Title + Synthesize event + UUID + 93001BC7-9ED4-4FE1-BBCE-0306F714D782 + + + Title + Set value of PickerWheel to ScrollViewController + UUID + 119D09F1-37BE-482D-A7D7-6DE85C959ED4 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708648.05732799 + StartTimeInterval + 570708647.93480301 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708647.96512699 + StartTimeInterval + 570708647.93521798 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708647.96468997 + StartTimeInterval + 570708647.95925999 + Title + Check for interrupting elements affecting "Load" Button + UUID + F74E884F-732E-4822-89FB-63515CB1550A + + + Title + Find the "Load" Button + UUID + 3D780FCA-699D-47A5-A0C0-A2CDF345CECD + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708648.05525804 + StartTimeInterval + 570708647.96556795 + Title + Synthesize event + UUID + 99E640F2-3E90-4F5E-96CB-D53D60C626A2 + + + Title + Tap "Load" Button + UUID + F0D39B87-B39F-4F0B-9D45-53EEEC9B4ED8 + + + Title + I change the PID and tap on Load + UUID + DA7E4E60-CF0C-46BF-A4E3-099035BCC3F8 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708649.14469695 + StartTimeInterval + 570708649.11070204 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + 95A59C34-4C29-4558-A651-582A162BB329 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708649.26829803 + StartTimeInterval + 570708649.14598501 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708649.17456698 + StartTimeInterval + 570708649.14661896 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708649.17383397 + StartTimeInterval + 570708649.16827905 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + D81FD27E-0F93-4DEC-97C7-85CE7CE605D0 + + + Title + Find the "go-to-ad-button" Button + UUID + A30B2CFF-982B-494B-AE62-09F83AB8BFB1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708649.26703203 + StartTimeInterval + 570708649.175282 + Title + Synthesize event + UUID + 6D6A6247-7C7C-4E36-9D4A-E4FC9D89AD97 + + + Title + Tap "go-to-ad-button" Button + UUID + 756B853F-B0D8-46BA-ABC4-5A1722821629 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708654.276178 + StartTimeInterval + 570708649.26916301 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708650.327564 + StartTimeInterval + 570708650.28707302 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + A2205487-08EC-4BD5-B4BE-B590E0C3AC91 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708651.37168396 + StartTimeInterval + 570708651.33722603 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + C2F1F0B1-FD78-4EB9-BD25-056C48BB8B39 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708652.41151798 + StartTimeInterval + 570708652.38724196 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 7D0916E4-5FD4-49E0-AE30-5A01009ACA4D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708653.44552004 + StartTimeInterval + 570708653.420506 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + CA430204-3332-4EAD-809E-50F194969DBE + + + Title + Waiting 5.0s for "Bitrise-endScreenReplay" Other to exist + UUID + 7279A58F-D3FF-469F-ABC9-1CA5F9C44644 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708655.40720904 + StartTimeInterval + 570708654.28860104 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708655.40508294 + StartTimeInterval + 570708654.289482 + Title + Terminate tv.Bitrise.BitriseApp:4069 + UUID + 4A490080-2D5C-41AB-875F-1DB51977D702 + + + Title + Tear Down + UUID + 0CB04031-90DC-43C4-B0D2-62A7E7EEEF11 + + + Duration + 16.493804097175598 + TestIdentifier + bitrErrorUITest/testbitrError901_2() + TestName + testbitrError901_2() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + 5C84F9E6-97AC-43F0-9A9A-4A5159F3A3AF + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708655.44048595 + StartTimeInterval + 570708655.40945804 + Title + Start Test at 2019-02-01 05:10:55.409 + UUID + BAE0241D-FD82-40B1-9957-97F2505017EB + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708655.40945804 + StartTimeInterval + 570708655.40945804 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + 5F07BB8C-26F8-4DEB-80AA-8DCBD91D8C51 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708658.53813195 + StartTimeInterval + 570708655.44238603 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708658.53686202 + StartTimeInterval + 570708655.44552803 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708658.53535497 + StartTimeInterval + 570708655.47278094 + Title + Launch tv.Bitrise.BitriseApp + UUID + 4D6219C3-DB34-49E2-B064-365167232070 + + + Title + Open tv.Bitrise.BitriseApp + UUID + 5B72C88E-B6C1-4CF9-9B8D-C3647BE27FA3 + + + Title + Set Up + UUID + DE3E2D6A-3269-4DDC-A410-4CFA54350A49 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708662.75462198 + StartTimeInterval + 570708658.54202402 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708662.75203598 + StartTimeInterval + 570708658.56653595 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708659.671736 + StartTimeInterval + 570708658.56756306 + Title + Terminate tv.Bitrise.BitriseApp:4100 + UUID + 82C02197-E58F-485C-B7DE-A0F4137A1F56 + + + Title + Launch tv.Bitrise.BitriseApp + UUID + B5A960BE-0C2D-4D33-B48D-02F2ABD9DFBB + + + Title + Open tv.Bitrise.BitriseApp + UUID + B68063BA-C55F-4F53-8877-60AA5B8A6402 + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708664.0596 + StartTimeInterval + 570708662.756598 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708663.84847701 + StartTimeInterval + 570708663.770648 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + ABD6BEED-C3CC-4293-A8CB-07401812C235 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708663.87381196 + StartTimeInterval + 570708663.85253596 + Title + Find the "pidTextField" TextField + UUID + E5ACA3C9-596B-4195-972C-B0CF70508C9D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708663.93678403 + StartTimeInterval + 570708663.87473702 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708663.90382898 + StartTimeInterval + 570708663.87541699 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708663.90284503 + StartTimeInterval + 570708663.89673495 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + 0FC53FA0-82B8-443E-9DCB-C8F35D989782 + + + Title + Find the PickerWheel + UUID + 0FB5E386-6AC7-4BE2-B345-752A62AC965A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708663.93617404 + StartTimeInterval + 570708663.90480697 + Title + Synthesize event + UUID + F80153F9-9AB3-4A81-8F66-3B9DC832959C + + + Title + Set value of PickerWheel to ScrollViewController + UUID + AD39EEC3-0F5E-4682-9927-1301C2D94EBE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708664.05842805 + StartTimeInterval + 570708663.93730295 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708663.97039402 + StartTimeInterval + 570708663.93771505 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708663.97007 + StartTimeInterval + 570708663.96495998 + Title + Check for interrupting elements affecting "Load" Button + UUID + B56495DE-FE24-476D-9562-084E84CC3B49 + + + Title + Find the "Load" Button + UUID + 387CF690-5031-4351-B65B-33D3B57BE0E9 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708664.05688202 + StartTimeInterval + 570708663.97070503 + Title + Synthesize event + UUID + 70D0C70D-6D9C-4231-960F-4B7410C776F8 + + + Title + Tap "Load" Button + UUID + 8DCFABBC-75DB-4B07-A3C6-89CF0124990C + + + Title + I change the PID and tap on Load + UUID + 8C96C33A-B7D1-4B08-A2E2-1BB79B99D373 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708665.15923297 + StartTimeInterval + 570708665.12050903 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + 658091DD-C1E9-498E-B3EC-2E8D14B97E06 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708665.28412294 + StartTimeInterval + 570708665.16048706 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708665.19078195 + StartTimeInterval + 570708665.161255 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708665.18990195 + StartTimeInterval + 570708665.18410397 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + 7DECB12C-99FB-4E0B-8710-A95772A37655 + + + Title + Find the "go-to-ad-button" Button + UUID + 0EB703AD-A233-4723-946A-741C95565D3D + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708665.28261697 + StartTimeInterval + 570708665.19157505 + Title + Synthesize event + UUID + 8342BE5F-FE21-48C5-B33B-484BDB361F89 + + + Title + Tap "go-to-ad-button" Button + UUID + 09B86FDF-C076-4E7C-BDEE-9847937CC03C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708670.29298604 + StartTimeInterval + 570708665.28522003 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708666.34109402 + StartTimeInterval + 570708666.28856099 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + EAE9CBD6-DE49-41FC-B3E3-A5F1DCDA56E5 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708667.38228798 + StartTimeInterval + 570708667.35382998 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + F95B6249-55B0-48B2-8FE4-25DF42BA9A70 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708668.42893302 + StartTimeInterval + 570708668.40394497 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + F68C92E5-4480-4308-8FCD-672D3133F8B4 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708669.46141696 + StartTimeInterval + 570708669.43722403 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 45123018-1FE5-4F9F-B38B-B5F3E1B54D2E + + + Title + Waiting 5.0s for "Bitrise-endScreenReplay" Other to exist + UUID + 66A051DF-2982-4505-8235-79E03C106515 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708671.43169606 + StartTimeInterval + 570708670.308936 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708671.42927897 + StartTimeInterval + 570708670.30963397 + Title + Terminate tv.Bitrise.BitriseApp:4106 + UUID + BAB0F685-C997-435E-B5DC-3039E6008ECA + + + Title + Tear Down + UUID + B1EF7E47-3291-4551-A15C-414CA5D07566 + + + Duration + 16.023802995681763 + TestIdentifier + bitrErrorUITest/testbitrError901_3() + TestName + testbitrError901_3() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + 13A8BE46-4269-4482-BB64-F030EAD5F616 + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708671.46532202 + StartTimeInterval + 570708671.43385005 + Title + Start Test at 2019-02-01 05:11:11.434 + UUID + 969BDE86-0614-480B-9CA6-1EEDCD0170A9 + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708671.43385005 + StartTimeInterval + 570708671.43385005 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + 916D7781-9E73-4069-9708-3151570026CE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708674.57275605 + StartTimeInterval + 570708671.46731198 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708674.57147002 + StartTimeInterval + 570708671.47011697 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708674.57010698 + StartTimeInterval + 570708671.49592304 + Title + Launch tv.Bitrise.BitriseApp + UUID + 518D5FC2-4B08-413B-B06E-D0C64ECD8946 + + + Title + Open tv.Bitrise.BitriseApp + UUID + 0EA30053-3B26-4490-AB50-4957CBF52854 + + + Title + Set Up + UUID + BB44FC45-045E-4480-9ED0-E6C9A4FA7864 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708678.82367897 + StartTimeInterval + 570708674.57672 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708678.81991994 + StartTimeInterval + 570708674.60159099 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708675.72150397 + StartTimeInterval + 570708674.60279095 + Title + Terminate tv.Bitrise.BitriseApp:4137 + UUID + 71DA30B8-DC33-436F-9930-2517C20CFD8E + + + Title + Launch tv.Bitrise.BitriseApp + UUID + 3E281B51-AE4F-47EB-BF53-84D122316428 + + + Title + Open tv.Bitrise.BitriseApp + UUID + 35C67F3C-F60D-4FB5-A13F-2C8B1C6F9B98 + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708680.12985396 + StartTimeInterval + 570708678.82650805 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708679.913607 + StartTimeInterval + 570708679.83731306 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + B8037429-53C3-4D79-8C4B-3B5A5C575999 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708679.93837202 + StartTimeInterval + 570708679.91700494 + Title + Find the "pidTextField" TextField + UUID + 8F626212-0908-4013-9EC4-23C7EF0AAAC1 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708680.001477 + StartTimeInterval + 570708679.93928301 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708679.97058296 + StartTimeInterval + 570708679.94019198 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708679.96921802 + StartTimeInterval + 570708679.95946801 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + 2D2D87CC-344B-47E3-8332-A8E90DA33C9D + + + Title + Find the PickerWheel + UUID + C16151D4-5A5B-43E7-A644-329449D39D61 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708680.00088501 + StartTimeInterval + 570708679.97189796 + Title + Synthesize event + UUID + E311CFAF-B24B-45E6-81FF-BBFD5468230D + + + Title + Set value of PickerWheel to ScrollViewController + UUID + 6A006BE8-5FC3-4F2F-B360-93BC8F7964DB + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708680.12908006 + StartTimeInterval + 570708680.00199103 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708680.03619897 + StartTimeInterval + 570708680.00240505 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708680.03587997 + StartTimeInterval + 570708680.03120399 + Title + Check for interrupting elements affecting "Load" Button + UUID + 32AD5047-31D5-471D-BDE0-88316F18DC4A + + + Title + Find the "Load" Button + UUID + B455B86B-DF0F-49BF-8434-269B5E083DA7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708680.12772596 + StartTimeInterval + 570708680.03650999 + Title + Synthesize event + UUID + 12526152-91F0-4387-A196-B6C083F2FF10 + + + Title + Tap "Load" Button + UUID + 2C1B49CB-75D2-4148-A5B5-4E632EE5F2CF + + + Title + I change the PID and tap on Load + UUID + 3989EB11-E912-4F8C-AACA-D44727789E12 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708681.20586097 + StartTimeInterval + 570708681.17892301 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + 592F0D41-3A20-4418-BCBE-BE881B3DB142 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708681.33526099 + StartTimeInterval + 570708681.20779204 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708681.239645 + StartTimeInterval + 570708681.20876706 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708681.23896098 + StartTimeInterval + 570708681.23287404 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + C07286FA-829A-4659-AE7C-32C6727D808F + + + Title + Find the "go-to-ad-button" Button + UUID + 66B08CB0-BAE8-473D-AF75-D89A82879950 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708681.33313704 + StartTimeInterval + 570708681.24030304 + Title + Synthesize event + UUID + DC972CFE-B95E-402E-8DC3-45590616757D + + + Title + Tap "go-to-ad-button" Button + UUID + BB01D55D-6952-42FA-BE08-615B3526A88F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708686.34415197 + StartTimeInterval + 570708681.33678401 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708682.44948804 + StartTimeInterval + 570708682.41212595 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 211F6CCD-04DB-41F0-B364-8E42A5AC3172 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708683.48048699 + StartTimeInterval + 570708683.45388603 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 20A2ACE7-AEB1-4573-9F3E-7F0F836E3261 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708684.52814198 + StartTimeInterval + 570708684.50385201 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + AB279499-27AB-4E36-818F-E215847ED551 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708685.56156003 + StartTimeInterval + 570708685.537251 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 06E8F483-69CC-445B-834E-586D7D85C50D + + + Title + Waiting 5.0s for "Bitrise-endScreenReplay" Other to exist + UUID + 31A51D8E-FCF0-43C0-B074-2A329D59816F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708687.48297501 + StartTimeInterval + 570708686.36931002 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708687.48025894 + StartTimeInterval + 570708686.37041402 + Title + Terminate tv.Bitrise.BitriseApp:4142 + UUID + BC2AC748-A54F-462E-9AAA-29378AA264D1 + + + Title + Tear Down + UUID + 2715D9E2-6242-438C-8A28-EE6C99F1B48C + + + Duration + 16.050634980201721 + TestIdentifier + bitrErrorUITest/testbitrError901_4() + TestName + testbitrError901_4() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + 57A8D1B0-0938-4412-91C3-FCF8A1AFCD6D + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708687.51622796 + StartTimeInterval + 570708687.48497403 + Title + Start Test at 2019-02-01 05:11:27.485 + UUID + 9F44F57F-E97C-4861-989B-B21FF139BAF7 + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708687.48497403 + StartTimeInterval + 570708687.48497403 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + 3084D3B4-D95A-463B-AAB0-AE4404E0CBA5 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708690.66612196 + StartTimeInterval + 570708687.51805794 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708690.66463602 + StartTimeInterval + 570708687.521065 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708690.66316199 + StartTimeInterval + 570708687.54776704 + Title + Launch tv.Bitrise.BitriseApp + UUID + F5ECFB44-10EB-4FBB-93EA-53D5FF250B44 + + + Title + Open tv.Bitrise.BitriseApp + UUID + 314B2BA9-CD34-4DFF-BAE9-D65F7A3568BB + + + Title + Set Up + UUID + 869C0129-2748-49FE-9DCB-CC227F129033 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708694.92652202 + StartTimeInterval + 570708690.67003798 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708694.92325401 + StartTimeInterval + 570708690.70708203 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708691.81354403 + StartTimeInterval + 570708690.70846796 + Title + Terminate tv.Bitrise.BitriseApp:4174 + UUID + D49E051C-D2DA-474D-BA3D-38A2A67CB938 + + + Title + Launch tv.Bitrise.BitriseApp + UUID + 6B278551-95F7-47C4-8D21-CC3CF177F69E + + + Title + Open tv.Bitrise.BitriseApp + UUID + 51535C86-3081-4C46-B4ED-A5A0EFF5B0DF + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708696.23561096 + StartTimeInterval + 570708694.92960203 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708696.02546 + StartTimeInterval + 570708695.94492304 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 17126C2A-BFDF-44BF-8080-1D180EBD746C + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708696.04894602 + StartTimeInterval + 570708696.02671194 + Title + Find the "pidTextField" TextField + UUID + CBBBBEAC-FD2A-43F5-BD07-D55584A4E8AD + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708696.11418295 + StartTimeInterval + 570708696.04993296 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708696.076105 + StartTimeInterval + 570708696.05060601 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708696.07540798 + StartTimeInterval + 570708696.06967402 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + 1890EE11-2371-466C-9C9D-34685C50503D + + + Title + Find the PickerWheel + UUID + 43D1620F-D981-45D8-AC70-032590DA4C1E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708696.11353195 + StartTimeInterval + 570708696.07697999 + Title + Synthesize event + UUID + 645531C9-F2EF-4F42-AA73-5783EC49FDDB + + + Title + Set value of PickerWheel to ScrollViewController + UUID + 758B27A2-119B-4C7C-B898-9D14284A6249 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708696.23471606 + StartTimeInterval + 570708696.11474895 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708696.144099 + StartTimeInterval + 570708696.11515903 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708696.143664 + StartTimeInterval + 570708696.13892198 + Title + Check for interrupting elements affecting "Load" Button + UUID + 7AAC091D-D181-4662-A6F5-B96F432211AD + + + Title + Find the "Load" Button + UUID + 737063C2-7F7E-4F9E-8061-79F0165847A6 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708696.23253095 + StartTimeInterval + 570708696.14463401 + Title + Synthesize event + UUID + F192C289-B97A-4D87-AD09-20DAD5FCEBD1 + + + Title + Tap "Load" Button + UUID + 26EC92CD-DCBF-47A6-8E88-2BB6F4731BD3 + + + Title + I change the PID and tap on Load + UUID + 10C9B9FA-9540-484F-8226-43E2D554E976 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708697.27176499 + StartTimeInterval + 570708697.24928904 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + F61A093D-A3DF-456B-8CBC-147B016EE327 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708697.40459895 + StartTimeInterval + 570708697.27535105 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708697.30557299 + StartTimeInterval + 570708697.27595198 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708697.30495095 + StartTimeInterval + 570708697.29867899 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + 5F183202-A0BA-4A8D-A4B7-62AD396B7037 + + + Title + Find the "go-to-ad-button" Button + UUID + 1A1DD742-3968-48FD-810F-6704B5244B2B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708697.40257001 + StartTimeInterval + 570708697.30645502 + Title + Synthesize event + UUID + C6B40CDC-C482-45CE-8850-AE324E052B00 + + + Title + Tap "go-to-ad-button" Button + UUID + 85327D58-8B95-418D-909D-B8A0EEF4811B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708702.40727794 + StartTimeInterval + 570708697.40556395 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708698.46765196 + StartTimeInterval + 570708698.42973006 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 5635EF40-FCBD-48C1-9073-116BF52AE341 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708699.49711299 + StartTimeInterval + 570708699.47060001 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 022BF2A1-50BC-4AC4-A9D4-4E2CC8AA588B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708700.52840495 + StartTimeInterval + 570708700.50382602 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + D2A4E617-AB80-489D-AEAF-10E59942342F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708701.562024 + StartTimeInterval + 570708701.53725696 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 7CDB417D-2A03-415C-9361-556E9E944C50 + + + Title + Waiting 5.0s for "Bitrise-endScreenReplay" Other to exist + UUID + 130999B8-C722-494A-82FB-3A6B064A5E93 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708703.55090797 + StartTimeInterval + 570708702.41999197 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708703.54839206 + StartTimeInterval + 570708702.42090404 + Title + Terminate tv.Bitrise.BitriseApp:4179 + UUID + B2F1BB3A-4717-4A36-8043-CBA29E741745 + + + Title + Tear Down + UUID + 290BCF34-322D-41CA-93D4-7EA578E254BA + + + Duration + 16.06726598739624 + TestIdentifier + bitrErrorUITest/testbitrError901_5() + TestName + testbitrError901_5() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + CC31D88C-0FF2-4C34-B696-CEBB90CD45DE + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708703.58338499 + StartTimeInterval + 570708703.553087 + Title + Start Test at 2019-02-01 05:11:43.553 + UUID + BFB97AEB-CD4E-4E0A-BA28-69ED5163F8F5 + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708703.553087 + StartTimeInterval + 570708703.553087 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + A84E58D9-CEC7-4311-8F6F-31734EE0BAC2 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708706.71481597 + StartTimeInterval + 570708703.58498096 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708706.71142697 + StartTimeInterval + 570708703.58780599 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708706.70784605 + StartTimeInterval + 570708703.61465204 + Title + Launch tv.Bitrise.BitriseApp + UUID + F51B6831-028A-4B00-8CA8-5063AC7884CF + + + Title + Open tv.Bitrise.BitriseApp + UUID + 8B4DCDA0-3A17-4900-88F4-82C930A1B292 + + + Title + Set Up + UUID + E0853A1B-C8FE-4B29-8ABC-8B8CE3F8ED19 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708711.20175302 + StartTimeInterval + 570708706.72209501 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708711.19768405 + StartTimeInterval + 570708706.75288403 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708707.84820604 + StartTimeInterval + 570708706.75424504 + Title + Terminate tv.Bitrise.BitriseApp:4213 + UUID + 563B7220-C447-4A03-9D1A-ABCC5710C906 + + + Title + Launch tv.Bitrise.BitriseApp + UUID + 875B28D0-A228-40C9-B875-01C17AFAD67E + + + Title + Open tv.Bitrise.BitriseApp + UUID + EA8895B5-276E-4747-AC46-AC7885D486C9 + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708712.48945904 + StartTimeInterval + 570708711.20479596 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708712.29733396 + StartTimeInterval + 570708712.22076595 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + B4B3C4FE-9702-4032-9F10-14F1A3E7C7BB + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708712.31547201 + StartTimeInterval + 570708712.29956698 + Title + Find the "pidTextField" TextField + UUID + A8FE6CB9-27B4-46FD-A314-2D5040F2CBA6 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708712.37657106 + StartTimeInterval + 570708712.31678605 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708712.34477997 + StartTimeInterval + 570708712.31760395 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708712.34393597 + StartTimeInterval + 570708712.33742905 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + 7957ABA4-78ED-4E3F-9FC9-89CDECBCA0FE + + + Title + Find the PickerWheel + UUID + BBE2A97F-E863-456D-8BD9-BB70D1F01973 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708712.37539303 + StartTimeInterval + 570708712.34591305 + Title + Synthesize event + UUID + 1D001E52-C24D-4C59-8681-C07AFCEAF8DF + + + Title + Set value of PickerWheel to ScrollViewController + UUID + 3C7EAC3E-396C-4172-A55E-40555B8DD0DE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708712.48883498 + StartTimeInterval + 570708712.37758899 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708712.40393305 + StartTimeInterval + 570708712.37832105 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708712.40357494 + StartTimeInterval + 570708712.39950502 + Title + Check for interrupting elements affecting "Load" Button + UUID + 7D566640-0C29-4D38-AE0F-256D2C849E81 + + + Title + Find the "Load" Button + UUID + CCA073D1-591F-40DD-AB98-6474E5EF102B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708712.48786199 + StartTimeInterval + 570708712.40422702 + Title + Synthesize event + UUID + 5052C8DE-76F8-4CA6-B673-F254A3F678D1 + + + Title + Tap "Load" Button + UUID + 68F16980-33A5-4D3D-B0C3-10A06DB37012 + + + Title + I change the PID and tap on Load + UUID + F15D11D7-25B9-401F-9F3E-47BA4858826F + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708713.54842699 + StartTimeInterval + 570708713.52050102 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + 2F34F91E-139E-4F42-A6F2-494669156F78 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708713.67803502 + StartTimeInterval + 570708713.55069196 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708713.58510804 + StartTimeInterval + 570708713.55176103 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708713.58445096 + StartTimeInterval + 570708713.57506895 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + 97AD492E-F8D8-43F5-BCBC-39A8AA6AC514 + + + Title + Find the "go-to-ad-button" Button + UUID + D1635B75-4487-4028-891D-826AAA384CEE + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708713.67597699 + StartTimeInterval + 570708713.58585501 + Title + Synthesize event + UUID + BC842148-E7BA-433B-A68B-311ED3938D5C + + + Title + Tap "go-to-ad-button" Button + UUID + 07AAC4B9-316F-47D9-9C75-4AEBE34C8BA8 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708725.68181503 + StartTimeInterval + 570708713.67892396 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708714.78200901 + StartTimeInterval + 570708714.72074294 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + AF9E112B-F7AF-46C1-ABE2-2F7A69231F94 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708715.86344194 + StartTimeInterval + 570708715.81440198 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 916C8B8C-D1D1-4AD0-A4CD-7EDD71EEBDC7 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708716.92976296 + StartTimeInterval + 570708716.88102806 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 4DAA2406-1DE7-4B5E-A9E7-4DB0B4BC4DFB + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708717.99528897 + StartTimeInterval + 570708717.947721 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + A0C59E0E-C81B-4A94-AA83-FBD988A1EAF0 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708719.05615902 + StartTimeInterval + 570708719.02047396 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + E77F9FFE-10BE-4D98-8F9F-EFCBFE72F0B9 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708720.13574195 + StartTimeInterval + 570708720.08739698 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 54280E6F-F22E-484C-AB6B-D209BC92A597 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708721.22802305 + StartTimeInterval + 570708721.18734205 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 5705BFFD-C1C3-4E53-82BB-8CAD0CA280AB + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708722.27641404 + StartTimeInterval + 570708722.24776304 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 72BBC321-B67A-476C-82BC-A4332E0A958E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708723.339643 + StartTimeInterval + 570708723.31458104 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 65EF7BCC-6E15-4224-8D29-FECBA93D9582 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708724.38991404 + StartTimeInterval + 570708724.36466706 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 6537AA15-56E9-47FE-A692-809BC7324FCD + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708725.44574594 + StartTimeInterval + 570708725.42056 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 74A6A5BE-CB5A-4EC9-8BD0-017B5C84A552 + + + Title + Waiting 12.0s for "Bitrise-endScreenReplay" Other to exist + UUID + 0977003F-20EA-43D4-9918-32D2828D321A + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708726.75740802 + StartTimeInterval + 570708725.70779705 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708726.75496697 + StartTimeInterval + 570708725.70887697 + Title + Terminate tv.Bitrise.BitriseApp:4218 + UUID + 56FCD040-4A23-44EE-B11D-5E56CADD8B25 + + + Title + Tear Down + UUID + 484CDE97-7D03-4C9D-8ECA-17F9A92AEFFB + + + Duration + 23.205875992774963 + TestIdentifier + bitrErrorUITest/testbitrVideoError402() + TestName + testbitrVideoError402() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + AEE7FD29-78DB-4B92-AAD0-0E385F25BF32 + + + ActivitySummaries + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708726.78916502 + StartTimeInterval + 570708726.75950396 + Title + Start Test at 2019-02-01 05:12:06.759 + UUID + BE1CC590-6273-423D-8803-B5042B11BBA1 + + + ActivityType + com.apple.dt.xctest.activity-type.deletedAttachment + FinishTimeInterval + 570708726.75950396 + StartTimeInterval + 570708726.75950396 + Title + Some screenshots were deleted because your scheme is configured to remove automatic screenshots on success. + UUID + BF592D43-CB02-44A0-8B86-98FE07EBA96E + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708729.95494604 + StartTimeInterval + 570708726.79079103 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708729.95169306 + StartTimeInterval + 570708726.79382396 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708729.94835401 + StartTimeInterval + 570708726.82253802 + Title + Launch tv.Bitrise.BitriseApp + UUID + 96AC673B-5B0C-440A-98BF-C0CFEF0F6B67 + + + Title + Open tv.Bitrise.BitriseApp + UUID + 29802686-61D3-4F02-988D-F76842354874 + + + Title + Set Up + UUID + ED195049-6E02-48F8-B781-ECD7CF26F4A9 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708734.434672 + StartTimeInterval + 570708729.96253598 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708734.43305898 + StartTimeInterval + 570708729.99442697 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708731.08971703 + StartTimeInterval + 570708729.99550903 + Title + Terminate tv.Bitrise.BitriseApp:4257 + UUID + 4938DE38-59DB-4367-A6C1-FA1072F0B7F3 + + + Title + Launch tv.Bitrise.BitriseApp + UUID + 4FC48275-9ED8-4E24-9292-3F370EAC41B4 + + + Title + Open tv.Bitrise.BitriseApp + UUID + 0F5CEE80-55A2-4FEB-B473-6B1D26F222B3 + + + ActivityType + com.apple.dt.xctest.activity-type.userCreated + FinishTimeInterval + 570708735.72575104 + StartTimeInterval + 570708734.43576002 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708735.52106905 + StartTimeInterval + 570708735.45395803 + Title + Checking Expect predicate exists == 1 for object "pidTextField" TextField + UUID + 86299540-62B6-4127-9372-2C0268103224 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708735.54228795 + StartTimeInterval + 570708735.52279794 + Title + Find the "pidTextField" TextField + UUID + 2A896C28-02A0-48B5-931A-51B56DD57741 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708735.60319495 + StartTimeInterval + 570708735.54310095 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708735.57292497 + StartTimeInterval + 570708735.54368699 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708735.572137 + StartTimeInterval + 570708735.56550896 + Title + Check for interrupting elements affecting "ScrollViewController" PickerWheel + UUID + 16DFF7CC-ECD8-44A1-962D-BA046A4FE701 + + + Title + Find the PickerWheel + UUID + F0D919BC-4D5B-4378-8D7E-4063DA03C134 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708735.60255504 + StartTimeInterval + 570708735.573892 + Title + Synthesize event + UUID + 73285DAC-4178-4280-ADEA-DDB7D170F075 + + + Title + Set value of PickerWheel to ScrollViewController + UUID + E74B82BB-BEB4-4979-9533-1BDF82446242 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708735.72504997 + StartTimeInterval + 570708735.603724 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708735.63326895 + StartTimeInterval + 570708735.604105 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708735.63286602 + StartTimeInterval + 570708735.627859 + Title + Check for interrupting elements affecting "Load" Button + UUID + 4AAFBCDB-D246-46F9-A5A0-5068DC6D9A25 + + + Title + Find the "Load" Button + UUID + 99059C25-E2C2-49DB-BB96-51197715AFDB + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708735.72363698 + StartTimeInterval + 570708735.63375199 + Title + Synthesize event + UUID + 68BFDA6E-E825-4457-BAAF-65656DD46BC7 + + + Title + Tap "Load" Button + UUID + 84D25BDE-7042-4347-B097-86F1D358D19C + + + Title + I change the PID and tap on Load + UUID + 570C97C7-32EF-455C-8F5E-08699B2DC296 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708736.82316303 + StartTimeInterval + 570708736.80388904 + Title + Checking Expect predicate exists == 1 for object "go-to-ad-button" Button + UUID + 9C783726-5D8F-48CA-8C1C-568EB4C57682 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708736.94854903 + StartTimeInterval + 570708736.82451296 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708736.84847999 + StartTimeInterval + 570708736.82572806 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708736.84781301 + StartTimeInterval + 570708736.84218001 + Title + Check for interrupting elements affecting "go-to-ad-button" Button + UUID + 4D796DC5-33B0-442A-B1E9-7580C094B1DE + + + Title + Find the "go-to-ad-button" Button + UUID + 183AA225-C1ED-49CC-A564-821F27D2CE68 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708736.94628096 + StartTimeInterval + 570708736.84921002 + Title + Synthesize event + UUID + 0F17C76B-7C9C-4234-B0FB-F0E9553D1967 + + + Title + Tap "go-to-ad-button" Button + UUID + BC4B3933-E8E4-4CDA-9697-3A9FC0B2AD28 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708741.95423996 + StartTimeInterval + 570708736.94972396 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708738.00427902 + StartTimeInterval + 570708737.95400596 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 38012EE3-3859-45A0-9CE1-DCA465017CDA + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708739.07700503 + StartTimeInterval + 570708739.03736901 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 334D544A-91D8-4F66-839E-37DE0BB9D6E2 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708740.14224005 + StartTimeInterval + 570708740.10401106 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + 5773B043-3C1F-4784-A0E7-E9EA0BC8363B + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708741.20840597 + StartTimeInterval + 570708741.17067599 + Title + Checking Expect predicate exists == 1 for object "Bitrise-endScreenReplay" Other + UUID + AF7B116D-981C-4BCF-82F1-DF24C37AE77F + + + Title + Waiting 5.0s for "Bitrise-endScreenReplay" Other to exist + UUID + E5B27B8E-EA8C-4EF8-AF26-CBDFEE3B9434 + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708743.07305396 + StartTimeInterval + 570708741.96888602 + SubActivities + + + ActivityType + com.apple.dt.xctest.activity-type.internal + FinishTimeInterval + 570708743.07129204 + StartTimeInterval + 570708741.96974194 + Title + Terminate tv.Bitrise.BitriseApp:4262 + UUID + F8EF34B6-1FE5-46D4-A1EA-DBB863CC2835 + + + Title + Tear Down + UUID + 5B35B7D0-1614-4109-A888-0C7C93C1BFCD + + + Duration + 16.315003991127014 + TestIdentifier + bitrErrorUITest/testVpaidError401() + TestName + testVpaidError401() + TestObjectClass + IDESchemeActionTestSummary + TestStatus + Success + TestSummaryGUID + 6F4BF94B-3696-4732-97BB-DEAC1A126D98 + + + TestIdentifier + bitrErrorUITest + TestName + bitrErrorUITest + TestObjectClass + IDESchemeActionTestSummaryGroup + + + TestIdentifier + BitriseAppUITests.xctest + TestName + BitriseAppUITests.xctest + TestObjectClass + IDESchemeActionTestSummaryGroup + + + TestIdentifier + Selected tests + TestName + Selected tests + TestObjectClass + IDESchemeActionTestSummaryGroup + + + + + + \ No newline at end of file diff --git a/test/testdata/ios_xml_output.golden b/test/testdata/ios_xml_output.golden new file mode 100644 index 00000000..45054c80 --- /dev/null +++ b/test/testdata/ios_xml_output.golden @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + /Users/vagrant/git/BitriseApp/BitriseAppUITests/BitriseOMUITests.swift:70 - XCTAssertTrue failed - No session found + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/uploaders/apkuploader.go b/uploaders/apkuploader.go index b8daf075..70b05379 100644 --- a/uploaders/apkuploader.go +++ b/uploaders/apkuploader.go @@ -8,9 +8,9 @@ import ( "regexp" "strings" + "github.com/bitrise-io/go-android/sdk" "github.com/bitrise-io/go-utils/command" "github.com/bitrise-io/go-utils/log" - "github.com/bitrise-tools/go-android/sdk" ) // ApkInfo ... diff --git a/uploaders/ipauploader.go b/uploaders/ipauploader.go index 92e0b4ad..bf90d5a4 100644 --- a/uploaders/ipauploader.go +++ b/uploaders/ipauploader.go @@ -5,10 +5,10 @@ import ( "fmt" "github.com/bitrise-io/go-utils/log" - "github.com/bitrise-tools/go-xcode/exportoptions" - "github.com/bitrise-tools/go-xcode/ipa" - "github.com/bitrise-tools/go-xcode/plistutil" - "github.com/bitrise-tools/go-xcode/profileutil" + "github.com/bitrise-io/go-xcode/exportoptions" + "github.com/bitrise-io/go-xcode/ipa" + "github.com/bitrise-io/go-xcode/plistutil" + "github.com/bitrise-io/go-xcode/profileutil" ) // DeployIPA ... diff --git a/vendor/github.com/bitrise-io/bitrise/LICENSE b/vendor/github.com/bitrise-io/bitrise/LICENSE new file mode 100644 index 00000000..a6a5c39a --- /dev/null +++ b/vendor/github.com/bitrise-io/bitrise/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Bitrise + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/bitrise-io/bitrise/_examples/tutorials/steps-and-workflows/steps-timestamp/LICENSE b/vendor/github.com/bitrise-io/bitrise/_examples/tutorials/steps-and-workflows/steps-timestamp/LICENSE new file mode 100644 index 00000000..a6a5c39a --- /dev/null +++ b/vendor/github.com/bitrise-io/bitrise/_examples/tutorials/steps-and-workflows/steps-timestamp/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Bitrise + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/bitrise-io/bitrise/_tests/integration/bash_toolkit_step_template/LICENSE b/vendor/github.com/bitrise-io/bitrise/_tests/integration/bash_toolkit_step_template/LICENSE new file mode 100644 index 00000000..a6a5c39a --- /dev/null +++ b/vendor/github.com/bitrise-io/bitrise/_tests/integration/bash_toolkit_step_template/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Bitrise + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/bitrise-io/bitrise/_tests/integration/go_toolkit_step_template/LICENSE b/vendor/github.com/bitrise-io/bitrise/_tests/integration/go_toolkit_step_template/LICENSE new file mode 100644 index 00000000..a6a5c39a --- /dev/null +++ b/vendor/github.com/bitrise-io/bitrise/_tests/integration/go_toolkit_step_template/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Bitrise + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/bitrise-io/bitrise/_tests/integration/step_template/LICENSE b/vendor/github.com/bitrise-io/bitrise/_tests/integration/step_template/LICENSE new file mode 100644 index 00000000..a6a5c39a --- /dev/null +++ b/vendor/github.com/bitrise-io/bitrise/_tests/integration/step_template/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Bitrise + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/bitrise-io/bitrise/models/models.go b/vendor/github.com/bitrise-io/bitrise/models/models.go new file mode 100644 index 00000000..162b573c --- /dev/null +++ b/vendor/github.com/bitrise-io/bitrise/models/models.go @@ -0,0 +1,134 @@ +package models + +import ( + "time" + + envmanModels "github.com/bitrise-io/envman/models" + stepmanModels "github.com/bitrise-io/stepman/models" +) + +const ( + // StepRunStatusCodeSuccess ... + StepRunStatusCodeSuccess = 0 + // StepRunStatusCodeFailed ... + StepRunStatusCodeFailed = 1 + // StepRunStatusCodeFailedSkippable ... + StepRunStatusCodeFailedSkippable = 2 + // StepRunStatusCodeSkipped ... + StepRunStatusCodeSkipped = 3 + // StepRunStatusCodeSkippedWithRunIf ... + StepRunStatusCodeSkippedWithRunIf = 4 + + // Version ... + Version = "8" +) + +// StepListItemModel ... +type StepListItemModel map[string]stepmanModels.StepModel + +// WorkflowModel ... +type WorkflowModel struct { + Title string `json:"title,omitempty" yaml:"title,omitempty"` + Summary string `json:"summary,omitempty" yaml:"summary,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + BeforeRun []string `json:"before_run,omitempty" yaml:"before_run,omitempty"` + AfterRun []string `json:"after_run,omitempty" yaml:"after_run,omitempty"` + Environments []envmanModels.EnvironmentItemModel `json:"envs,omitempty" yaml:"envs,omitempty"` + Steps []StepListItemModel `json:"steps,omitempty" yaml:"steps,omitempty"` + Meta map[string]interface{} `json:"meta,omitempty" yaml:"meta,omitempty"` +} + +// AppModel ... +type AppModel struct { + Title string `json:"title,omitempty" yaml:"title,omitempty"` + Summary string `json:"summary,omitempty" yaml:"summary,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + Environments []envmanModels.EnvironmentItemModel `json:"envs,omitempty" yaml:"envs,omitempty"` +} + +// TriggerEventType ... +type TriggerEventType string + +const ( + // TriggerEventTypeCodePush ... + TriggerEventTypeCodePush TriggerEventType = "code-push" + // TriggerEventTypePullRequest ... + TriggerEventTypePullRequest TriggerEventType = "pull-request" + // TriggerEventTypeTag ... + TriggerEventTypeTag TriggerEventType = "tag" + // TriggerEventTypeUnknown ... + TriggerEventTypeUnknown TriggerEventType = "unknown" +) + +// TriggerMapItemModel ... +type TriggerMapItemModel struct { + PushBranch string `json:"push_branch,omitempty" yaml:"push_branch,omitempty"` + PullRequestSourceBranch string `json:"pull_request_source_branch,omitempty" yaml:"pull_request_source_branch,omitempty"` + PullRequestTargetBranch string `json:"pull_request_target_branch,omitempty" yaml:"pull_request_target_branch,omitempty"` + Tag string `json:"tag,omitempty" yaml:"tag,omitempty"` + WorkflowID string `json:"workflow,omitempty" yaml:"workflow,omitempty"` + + // deprecated + Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"` + IsPullRequestAllowed bool `json:"is_pull_request_allowed,omitempty" yaml:"is_pull_request_allowed,omitempty"` +} + +// TriggerMapModel ... +type TriggerMapModel []TriggerMapItemModel + +// BitriseDataModel ... +type BitriseDataModel struct { + FormatVersion string `json:"format_version" yaml:"format_version"` + DefaultStepLibSource string `json:"default_step_lib_source,omitempty" yaml:"default_step_lib_source,omitempty"` + ProjectType string `json:"project_type" yaml:"project_type"` + // + Title string `json:"title,omitempty" yaml:"title,omitempty"` + Summary string `json:"summary,omitempty" yaml:"summary,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + // + App AppModel `json:"app,omitempty" yaml:"app,omitempty"` + TriggerMap TriggerMapModel `json:"trigger_map,omitempty" yaml:"trigger_map,omitempty"` + Workflows map[string]WorkflowModel `json:"workflows,omitempty" yaml:"workflows,omitempty"` +} + +// StepIDData ... +// structured representation of a composite-step-id +// a composite step id is: step-lib-source::step-id@1.0.0 +type StepIDData struct { + // SteplibSource : steplib source uri, or in case of local path just "path", and in case of direct git url just "git" + SteplibSource string + // IDOrURI : ID if steplib is provided, URI if local step or in case a direct git url provided + IDorURI string + // Version : version in the steplib, or in case of a direct git step the tag-or-branch to use + Version string +} + +// BuildRunResultsModel ... +type BuildRunResultsModel struct { + ProjectType string `json:"project_type" yaml:"project_type"` + StartTime time.Time `json:"start_time" yaml:"start_time"` + StepmanUpdates map[string]int `json:"stepman_updates" yaml:"stepman_updates"` + SuccessSteps []StepRunResultsModel `json:"success_steps" yaml:"success_steps"` + FailedSteps []StepRunResultsModel `json:"failed_steps" yaml:"failed_steps"` + FailedSkippableSteps []StepRunResultsModel `json:"failed_skippable_steps" yaml:"failed_skippable_steps"` + SkippedSteps []StepRunResultsModel `json:"skipped_steps" yaml:"skipped_steps"` +} + +// StepRunResultsModel ... +type StepRunResultsModel struct { + StepInfo stepmanModels.StepInfoModel `json:"step_info" yaml:"step_info"` + Status int `json:"status" yaml:"status"` + Idx int `json:"idx" yaml:"idx"` + RunTime time.Duration `json:"run_time" yaml:"run_time"` + StartTime time.Time `json:"start_time" yaml:"start_time"` + ErrorStr string `json:"error_str" yaml:"error_str"` + ExitCode int `json:"exit_code" yaml:"exit_code"` +} + +// TestResultStepInfo ... +type TestResultStepInfo struct { + ID string `json:"id" yaml:"id"` + Version string `json:"version" yaml:"version"` + Title string `json:"title" yaml:"title"` + Number int `json:"number" yaml:"number"` +} diff --git a/vendor/github.com/bitrise-io/bitrise/models/models_methods.go b/vendor/github.com/bitrise-io/bitrise/models/models_methods.go new file mode 100644 index 00000000..c07834f5 --- /dev/null +++ b/vendor/github.com/bitrise-io/bitrise/models/models_methods.go @@ -0,0 +1,1013 @@ +package models + +import ( + "errors" + "fmt" + "regexp" + "strings" + + envmanModels "github.com/bitrise-io/envman/models" + "github.com/bitrise-io/go-utils/pointers" + stepmanModels "github.com/bitrise-io/stepman/models" + "github.com/ryanuber/go-glob" +) + +func (triggerItem TriggerMapItemModel) String(printWorkflow bool) string { + str := "" + + if triggerItem.PushBranch != "" { + str = fmt.Sprintf("push_branch: %s", triggerItem.PushBranch) + } + + if triggerItem.PullRequestSourceBranch != "" || triggerItem.PullRequestTargetBranch != "" { + if str != "" { + str += " " + } + + if triggerItem.PullRequestSourceBranch != "" { + str += fmt.Sprintf("pull_request_source_branch: %s", triggerItem.PullRequestSourceBranch) + } + if triggerItem.PullRequestTargetBranch != "" { + if triggerItem.PullRequestSourceBranch != "" { + str += " && " + } + + str += fmt.Sprintf("pull_request_target_branch: %s", triggerItem.PullRequestTargetBranch) + } + } + + if triggerItem.Tag != "" { + if str != "" { + str += " " + } + + str += fmt.Sprintf("tag: %s", triggerItem.Tag) + } + + if triggerItem.Pattern != "" { + if str != "" { + str += " " + } + + str += fmt.Sprintf("pattern: %s && is_pull_request_allowed: %v", triggerItem.Pattern, triggerItem.IsPullRequestAllowed) + } + + if printWorkflow { + str += fmt.Sprintf(" -> workflow: %s", triggerItem.WorkflowID) + } + + return str +} + +func triggerEventType(pushBranch, prSourceBranch, prTargetBranch, tag string) (TriggerEventType, error) { + if pushBranch != "" { + // Ensure not mixed with code-push event + if prSourceBranch != "" { + return TriggerEventTypeUnknown, fmt.Errorf("push_branch (%s) selects code-push trigger event, but pull_request_source_branch (%s) also provided", pushBranch, prSourceBranch) + } + if prTargetBranch != "" { + return TriggerEventTypeUnknown, fmt.Errorf("push_branch (%s) selects code-push trigger event, but pull_request_target_branch (%s) also provided", pushBranch, prTargetBranch) + } + + // Ensure not mixed with tag event + if tag != "" { + return TriggerEventTypeUnknown, fmt.Errorf("push_branch (%s) selects code-push trigger event, but tag (%s) also provided", pushBranch, tag) + } + + return TriggerEventTypeCodePush, nil + } else if prSourceBranch != "" || prTargetBranch != "" { + // Ensure not mixed with tag event + if tag != "" { + return TriggerEventTypeUnknown, fmt.Errorf("pull_request_source_branch (%s) and pull_request_target_branch (%s) selects pull-request trigger event, but tag (%s) also provided", prSourceBranch, prTargetBranch, tag) + } + + return TriggerEventTypePullRequest, nil + } else if tag != "" { + return TriggerEventTypeTag, nil + } + + return TriggerEventTypeUnknown, fmt.Errorf("failed to determin trigger event from params: push-branch: %s, pr-source-branch: %s, pr-target-branch: %s, tag: %s", pushBranch, prSourceBranch, prTargetBranch, tag) +} + +func migrateDeprecatedTriggerItem(triggerItem TriggerMapItemModel) []TriggerMapItemModel { + migratedItems := []TriggerMapItemModel{ + TriggerMapItemModel{ + PushBranch: triggerItem.Pattern, + WorkflowID: triggerItem.WorkflowID, + }, + } + if triggerItem.IsPullRequestAllowed { + migratedItems = append(migratedItems, TriggerMapItemModel{ + PullRequestSourceBranch: triggerItem.Pattern, + WorkflowID: triggerItem.WorkflowID, + }) + } + return migratedItems +} + +// MatchWithParams ... +func (triggerItem TriggerMapItemModel) MatchWithParams(pushBranch, prSourceBranch, prTargetBranch, tag string) (bool, error) { + paramsEventType, err := triggerEventType(pushBranch, prSourceBranch, prTargetBranch, tag) + if err != nil { + return false, err + } + + migratedTriggerItems := []TriggerMapItemModel{triggerItem} + if triggerItem.Pattern != "" { + migratedTriggerItems = migrateDeprecatedTriggerItem(triggerItem) + } + + for _, migratedTriggerItem := range migratedTriggerItems { + itemEventType, err := triggerEventType(migratedTriggerItem.PushBranch, migratedTriggerItem.PullRequestSourceBranch, migratedTriggerItem.PullRequestTargetBranch, migratedTriggerItem.Tag) + if err != nil { + return false, err + } + + if paramsEventType != itemEventType { + continue + } + + switch itemEventType { + case TriggerEventTypeCodePush: + match := glob.Glob(migratedTriggerItem.PushBranch, pushBranch) + return match, nil + case TriggerEventTypePullRequest: + sourceMatch := false + if migratedTriggerItem.PullRequestSourceBranch == "" { + sourceMatch = true + } else { + sourceMatch = glob.Glob(migratedTriggerItem.PullRequestSourceBranch, prSourceBranch) + } + + targetMatch := false + if migratedTriggerItem.PullRequestTargetBranch == "" { + targetMatch = true + } else { + targetMatch = glob.Glob(migratedTriggerItem.PullRequestTargetBranch, prTargetBranch) + } + + return (sourceMatch && targetMatch), nil + case TriggerEventTypeTag: + match := glob.Glob(migratedTriggerItem.Tag, tag) + return match, nil + } + } + + return false, nil +} + +func containsWorkflowName(title string, workflowStack []string) bool { + for _, t := range workflowStack { + if t == title { + return true + } + } + return false +} + +func removeWorkflowName(title string, workflowStack []string) []string { + newStack := []string{} + for _, t := range workflowStack { + if t != title { + newStack = append(newStack, t) + } + } + return newStack +} + +func checkWorkflowReferenceCycle(workflowID string, workflow WorkflowModel, bitriseConfig BitriseDataModel, workflowStack []string) error { + if containsWorkflowName(workflowID, workflowStack) { + stackStr := "" + for _, aWorkflowID := range workflowStack { + stackStr += aWorkflowID + " -> " + } + stackStr += workflowID + return fmt.Errorf("Workflow reference cycle found: %s", stackStr) + } + workflowStack = append(workflowStack, workflowID) + + for _, beforeWorkflowName := range workflow.BeforeRun { + beforeWorkflow, exist := bitriseConfig.Workflows[beforeWorkflowName] + if !exist { + return errors.New("Workflow does not exist with name " + beforeWorkflowName) + } + + err := checkWorkflowReferenceCycle(beforeWorkflowName, beforeWorkflow, bitriseConfig, workflowStack) + if err != nil { + return err + } + } + + for _, afterWorkflowName := range workflow.AfterRun { + afterWorkflow, exist := bitriseConfig.Workflows[afterWorkflowName] + if !exist { + return errors.New("Workflow does not exist with name " + afterWorkflowName) + } + + err := checkWorkflowReferenceCycle(afterWorkflowName, afterWorkflow, bitriseConfig, workflowStack) + if err != nil { + return err + } + } + + workflowStack = removeWorkflowName(workflowID, workflowStack) + + return nil +} + +// ---------------------------- +// --- Normalize + +// Normalize ... +func (workflow *WorkflowModel) Normalize() error { + for _, env := range workflow.Environments { + if err := env.Normalize(); err != nil { + return err + } + } + + for _, stepListItem := range workflow.Steps { + stepID, step, err := GetStepIDStepDataPair(stepListItem) + if err != nil { + return err + } + if err := step.Normalize(); err != nil { + return err + } + stepListItem[stepID] = step + } + + return nil +} + +// Normalize ... +func (app *AppModel) Normalize() error { + for _, env := range app.Environments { + if err := env.Normalize(); err != nil { + return err + } + } + return nil +} + +// Normalize ... +func (config *BitriseDataModel) Normalize() error { + if err := config.App.Normalize(); err != nil { + return err + } + + for _, workflow := range config.Workflows { + if err := workflow.Normalize(); err != nil { + return err + } + } + + return nil +} + +// ---------------------------- +// --- Validate + +// Validate ... +func (workflow *WorkflowModel) Validate() ([]string, error) { + for _, env := range workflow.Environments { + if err := env.Validate(); err != nil { + return []string{}, err + } + } + + warnings := []string{} + for _, stepListItem := range workflow.Steps { + stepID, step, err := GetStepIDStepDataPair(stepListItem) + if err != nil { + return warnings, err + } + + if err := step.ValidateInputAndOutputEnvs(false); err != nil { + return warnings, err + } + + stepInputMap := map[string]bool{} + for _, input := range step.Inputs { + key, _, err := input.GetKeyValuePair() + if err != nil { + return warnings, err + } + + _, found := stepInputMap[key] + if found { + warnings = append(warnings, fmt.Sprintf("invalid step: duplicated input found: (%s)", key)) + } + stepInputMap[key] = true + } + + stepListItem[stepID] = step + } + + return warnings, nil +} + +// Validate ... +func (app *AppModel) Validate() error { + for _, env := range app.Environments { + if err := env.Validate(); err != nil { + return err + } + } + return nil +} + +// Validate ... +func (triggerItem TriggerMapItemModel) Validate() error { + if triggerItem.WorkflowID == "" { + return fmt.Errorf("invalid trigger item: (%s) -> (%s), error: empty workflow id", triggerItem.Pattern, triggerItem.WorkflowID) + } + + if triggerItem.Pattern == "" { + _, err := triggerEventType(triggerItem.PushBranch, triggerItem.PullRequestSourceBranch, triggerItem.PullRequestTargetBranch, triggerItem.Tag) + if err != nil { + return fmt.Errorf("trigger map item (%s) validate failed, error: %s", triggerItem.String(true), err) + } + } else if triggerItem.PushBranch != "" || + triggerItem.PullRequestSourceBranch != "" || triggerItem.PullRequestTargetBranch != "" || triggerItem.Tag != "" { + return fmt.Errorf("deprecated trigger item (pattern defined), mixed with trigger params (push_branch: %s, pull_request_source_branch: %s, pull_request_target_branch: %s, tag: %s)", triggerItem.PushBranch, triggerItem.PullRequestSourceBranch, triggerItem.PullRequestTargetBranch, triggerItem.Tag) + } + + return nil +} + +// Validate ... +func (triggerMap TriggerMapModel) Validate() error { + for _, item := range triggerMap { + if err := item.Validate(); err != nil { + return err + } + } + + return nil +} + +func checkDuplicatedTriggerMapItems(triggerMap TriggerMapModel) error { + triggeTypeItemMap := map[string][]TriggerMapItemModel{} + + for _, triggerItem := range triggerMap { + if triggerItem.Pattern == "" { + triggerType, err := triggerEventType(triggerItem.PushBranch, triggerItem.PullRequestSourceBranch, triggerItem.PullRequestTargetBranch, triggerItem.Tag) + if err != nil { + return fmt.Errorf("trigger map item (%v) validate failed, error: %s", triggerItem, err) + } + + triggerItems := triggeTypeItemMap[string(triggerType)] + + for _, item := range triggerItems { + switch triggerType { + case TriggerEventTypeCodePush: + if triggerItem.PushBranch == item.PushBranch { + return fmt.Errorf("duplicated trigger item found (%s)", triggerItem.String(false)) + } + case TriggerEventTypePullRequest: + if triggerItem.PullRequestSourceBranch == item.PullRequestSourceBranch && + triggerItem.PullRequestTargetBranch == item.PullRequestTargetBranch { + return fmt.Errorf("duplicated trigger item found (%s)", triggerItem.String(false)) + } + case TriggerEventTypeTag: + if triggerItem.Tag == item.Tag { + return fmt.Errorf("duplicated trigger item found (%s)", triggerItem.String(false)) + } + } + } + + triggerItems = append(triggerItems, triggerItem) + triggeTypeItemMap[string(triggerType)] = triggerItems + } else if triggerItem.Pattern != "" { + triggerItems := triggeTypeItemMap["deprecated"] + + for _, item := range triggerItems { + if triggerItem.Pattern == item.Pattern && + triggerItem.IsPullRequestAllowed == item.IsPullRequestAllowed { + return fmt.Errorf("duplicated trigger item found (%s)", triggerItem.String(false)) + } + } + + triggerItems = append(triggerItems, triggerItem) + triggeTypeItemMap["deprecated"] = triggerItems + } + } + + return nil +} + +// Validate ... +func (config *BitriseDataModel) Validate() ([]string, error) { + warnings := []string{} + + if config.FormatVersion == "" { + return warnings, fmt.Errorf("missing format_version") + } + + // trigger map + if err := config.TriggerMap.Validate(); err != nil { + return warnings, err + } + + for _, triggerMapItem := range config.TriggerMap { + if strings.HasPrefix(triggerMapItem.WorkflowID, "_") { + warnings = append(warnings, fmt.Sprintf("workflow (%s) defined in trigger item (%s), but utility workflows can't be triggered directly", triggerMapItem.WorkflowID, triggerMapItem.String(true))) + } + + found := false + + for workflowID := range config.Workflows { + if workflowID == triggerMapItem.WorkflowID { + found = true + } + } + + if !found { + return warnings, fmt.Errorf("workflow (%s) defined in trigger item (%s), but does not exist", triggerMapItem.WorkflowID, triggerMapItem.String(true)) + } + } + + if err := checkDuplicatedTriggerMapItems(config.TriggerMap); err != nil { + return warnings, err + } + // --- + + // app + if err := config.App.Validate(); err != nil { + return warnings, err + } + // --- + + // workflows + for ID, workflow := range config.Workflows { + if ID == "" { + return warnings, fmt.Errorf("invalid workflow ID (%s): empty", ID) + } + + r := regexp.MustCompile(`[A-Za-z0-9-_.]+`) + if find := r.FindString(ID); find != ID { + warnings = append(warnings, fmt.Sprintf("invalid workflow ID (%s): doesn't conform to: [A-Za-z0-9-_.]", ID)) + } + + warns, err := workflow.Validate() + warnings = append(warnings, warns...) + if err != nil { + return warnings, err + } + + if err := checkWorkflowReferenceCycle(ID, workflow, *config, []string{}); err != nil { + return warnings, err + } + } + // --- + + return warnings, nil +} + +// ---------------------------- +// --- FillMissingDefaults + +// FillMissingDefaults ... +func (workflow *WorkflowModel) FillMissingDefaults(title string) error { + // Don't call step.FillMissingDefaults() + // StepLib versions of steps (which are the default versions), + // contains different env defaults then normal envs + // example: isExpand = true by default for normal envs, + // but script step content input env isExpand = false by default + + for _, env := range workflow.Environments { + if err := env.FillMissingDefaults(); err != nil { + return err + } + } + + if workflow.Title == "" { + workflow.Title = title + } + + return nil +} + +// FillMissingDefaults ... +func (app *AppModel) FillMissingDefaults() error { + for _, env := range app.Environments { + if err := env.FillMissingDefaults(); err != nil { + return err + } + } + return nil +} + +// FillMissingDefaults ... +func (config *BitriseDataModel) FillMissingDefaults() error { + if err := config.App.FillMissingDefaults(); err != nil { + return err + } + + for title, workflow := range config.Workflows { + if err := workflow.FillMissingDefaults(title); err != nil { + return err + } + } + + return nil +} + +// ---------------------------- +// --- RemoveRedundantFields + +func removeEnvironmentRedundantFields(env *envmanModels.EnvironmentItemModel) error { + options, err := env.GetOptions() + if err != nil { + return err + } + + hasOptions := false + + if options.IsSensitive != nil { + if *options.IsSensitive == envmanModels.DefaultIsSensitive { + options.IsSensitive = nil + } else { + hasOptions = true + } + } + + if options.IsExpand != nil { + if *options.IsExpand == envmanModels.DefaultIsExpand { + options.IsExpand = nil + } else { + hasOptions = true + } + } + if options.SkipIfEmpty != nil { + if *options.SkipIfEmpty == envmanModels.DefaultSkipIfEmpty { + options.SkipIfEmpty = nil + } else { + hasOptions = true + } + } + if options.Title != nil { + if *options.Title == "" { + options.Title = nil + } else { + hasOptions = true + } + } + if options.Description != nil { + if *options.Description == "" { + options.Description = nil + } else { + hasOptions = true + } + } + if options.Summary != nil { + if *options.Summary == "" { + options.Summary = nil + } else { + hasOptions = true + } + } + if options.Category != nil { + if *options.Category == "" { + options.Category = nil + } else { + hasOptions = true + } + } + if options.ValueOptions != nil && len(options.ValueOptions) > 0 { + hasOptions = true + } + if options.IsRequired != nil { + if *options.IsRequired == envmanModels.DefaultIsRequired { + options.IsRequired = nil + } else { + hasOptions = true + } + } + if options.IsDontChangeValue != nil { + if *options.IsDontChangeValue == envmanModels.DefaultIsDontChangeValue { + options.IsDontChangeValue = nil + } else { + hasOptions = true + } + } + if options.IsTemplate != nil { + if *options.IsTemplate == envmanModels.DefaultIsTemplate { + options.IsTemplate = nil + } else { + hasOptions = true + } + } + if options.Meta != nil && len(options.Meta) > 0 { + hasOptions = true + } + + if hasOptions { + (*env)[envmanModels.OptionsKey] = options + } else { + delete(*env, envmanModels.OptionsKey) + } + + return nil +} + +func (workflow *WorkflowModel) removeRedundantFields() error { + // Don't call step.RemoveRedundantFields() + // StepLib versions of steps (which are the default versions), + // contains different env defaults then normal envs + // example: isExpand = true by default for normal envs, + // but script step content input env isExpand = false by default + for _, env := range workflow.Environments { + if err := removeEnvironmentRedundantFields(&env); err != nil { + return err + } + } + return nil +} + +func (app *AppModel) removeRedundantFields() error { + for _, env := range app.Environments { + if err := removeEnvironmentRedundantFields(&env); err != nil { + return err + } + } + return nil +} + +// RemoveRedundantFields ... +func (config *BitriseDataModel) RemoveRedundantFields() error { + if err := config.App.removeRedundantFields(); err != nil { + return err + } + for _, workflow := range config.Workflows { + if err := workflow.removeRedundantFields(); err != nil { + return err + } + } + return nil +} + +// ---------------------------- +// --- Merge + +// MergeEnvironmentWith ... +func MergeEnvironmentWith(env *envmanModels.EnvironmentItemModel, otherEnv envmanModels.EnvironmentItemModel) error { + // merge key-value + key, _, err := env.GetKeyValuePair() + if err != nil { + return err + } + + otherKey, otherValue, err := otherEnv.GetKeyValuePair() + if err != nil { + return err + } + + if otherKey != key { + return errors.New("Env keys are diferent") + } + + (*env)[key] = otherValue + + //merge options + options, err := env.GetOptions() + if err != nil { + return err + } + + otherOptions, err := otherEnv.GetOptions() + if err != nil { + return err + } + + if otherOptions.IsSensitive != nil { + options.IsSensitive = pointers.NewBoolPtr(*otherOptions.IsSensitive) + } + if otherOptions.IsExpand != nil { + options.IsExpand = pointers.NewBoolPtr(*otherOptions.IsExpand) + } + if otherOptions.SkipIfEmpty != nil { + options.SkipIfEmpty = pointers.NewBoolPtr(*otherOptions.SkipIfEmpty) + } + + if otherOptions.Title != nil { + options.Title = pointers.NewStringPtr(*otherOptions.Title) + } + if otherOptions.Description != nil { + options.Description = pointers.NewStringPtr(*otherOptions.Description) + } + if otherOptions.Summary != nil { + options.Summary = pointers.NewStringPtr(*otherOptions.Summary) + } + if otherOptions.Category != nil { + options.Category = pointers.NewStringPtr(*otherOptions.Category) + } + if len(otherOptions.ValueOptions) > 0 { + options.ValueOptions = otherOptions.ValueOptions + } + if otherOptions.IsRequired != nil { + options.IsRequired = pointers.NewBoolPtr(*otherOptions.IsRequired) + } + if otherOptions.IsDontChangeValue != nil { + options.IsDontChangeValue = pointers.NewBoolPtr(*otherOptions.IsDontChangeValue) + } + if otherOptions.IsTemplate != nil { + options.IsTemplate = pointers.NewBoolPtr(*otherOptions.IsTemplate) + } + (*env)[envmanModels.OptionsKey] = options + return nil +} + +func getInputByKey(step stepmanModels.StepModel, key string) (envmanModels.EnvironmentItemModel, bool) { + for _, input := range step.Inputs { + k, _, err := input.GetKeyValuePair() + if err != nil { + return envmanModels.EnvironmentItemModel{}, false + } + + if k == key { + return input, true + } + } + return envmanModels.EnvironmentItemModel{}, false +} + +func getOutputByKey(step stepmanModels.StepModel, key string) (envmanModels.EnvironmentItemModel, bool) { + for _, output := range step.Outputs { + k, _, err := output.GetKeyValuePair() + if err != nil { + return envmanModels.EnvironmentItemModel{}, false + } + + if k == key { + return output, true + } + } + return envmanModels.EnvironmentItemModel{}, false +} + +// MergeStepWith ... +func MergeStepWith(step, otherStep stepmanModels.StepModel) (stepmanModels.StepModel, error) { + if otherStep.Title != nil { + step.Title = pointers.NewStringPtr(*otherStep.Title) + } + if otherStep.Summary != nil { + step.Summary = pointers.NewStringPtr(*otherStep.Summary) + } + if otherStep.Description != nil { + step.Description = pointers.NewStringPtr(*otherStep.Description) + } + + if otherStep.Website != nil { + step.Website = pointers.NewStringPtr(*otherStep.Website) + } + if otherStep.SourceCodeURL != nil { + step.SourceCodeURL = pointers.NewStringPtr(*otherStep.SourceCodeURL) + } + if otherStep.SupportURL != nil { + step.SupportURL = pointers.NewStringPtr(*otherStep.SupportURL) + } + + if otherStep.PublishedAt != nil { + step.PublishedAt = pointers.NewTimePtr(*otherStep.PublishedAt) + } + if otherStep.Source != nil { + step.Source = new(stepmanModels.StepSourceModel) + + if otherStep.Source.Git != "" { + step.Source.Git = otherStep.Source.Git + } + if otherStep.Source.Commit != "" { + step.Source.Commit = otherStep.Source.Commit + } + } + if len(otherStep.AssetURLs) > 0 { + step.AssetURLs = otherStep.AssetURLs + } + + if len(otherStep.HostOsTags) > 0 { + step.HostOsTags = otherStep.HostOsTags + } + if len(otherStep.ProjectTypeTags) > 0 { + step.ProjectTypeTags = otherStep.ProjectTypeTags + } + if len(otherStep.TypeTags) > 0 { + step.TypeTags = otherStep.TypeTags + } + if len(otherStep.Dependencies) > 0 { + step.Dependencies = otherStep.Dependencies + } + if otherStep.Toolkit != nil { + step.Toolkit = new(stepmanModels.StepToolkitModel) + *step.Toolkit = *otherStep.Toolkit + } + if otherStep.Deps != nil && (len(otherStep.Deps.Brew) > 0 || len(otherStep.Deps.AptGet) > 0 || len(otherStep.Deps.CheckOnly) > 0) { + step.Deps = otherStep.Deps + } + if otherStep.IsRequiresAdminUser != nil { + step.IsRequiresAdminUser = pointers.NewBoolPtr(*otherStep.IsRequiresAdminUser) + } + + if otherStep.IsAlwaysRun != nil { + step.IsAlwaysRun = pointers.NewBoolPtr(*otherStep.IsAlwaysRun) + } + if otherStep.IsSkippable != nil { + step.IsSkippable = pointers.NewBoolPtr(*otherStep.IsSkippable) + } + if otherStep.RunIf != nil { + step.RunIf = pointers.NewStringPtr(*otherStep.RunIf) + } + if otherStep.Timeout != nil { + step.Timeout = pointers.NewIntPtr(*otherStep.Timeout) + } + + for _, input := range step.Inputs { + key, _, err := input.GetKeyValuePair() + if err != nil { + return stepmanModels.StepModel{}, err + } + otherInput, found := getInputByKey(otherStep, key) + if found { + err := MergeEnvironmentWith(&input, otherInput) + if err != nil { + return stepmanModels.StepModel{}, err + } + } + } + + for _, output := range step.Outputs { + key, _, err := output.GetKeyValuePair() + if err != nil { + return stepmanModels.StepModel{}, err + } + otherOutput, found := getOutputByKey(otherStep, key) + if found { + err := MergeEnvironmentWith(&output, otherOutput) + if err != nil { + return stepmanModels.StepModel{}, err + } + } + } + + return step, nil +} + +// ---------------------------- +// --- StepIDData + +// GetStepIDStepDataPair ... +func GetStepIDStepDataPair(stepListItem StepListItemModel) (string, stepmanModels.StepModel, error) { + if len(stepListItem) > 1 { + return "", stepmanModels.StepModel{}, errors.New("StepListItem contains more than 1 key-value pair") + } + for key, value := range stepListItem { + return key, value, nil + } + return "", stepmanModels.StepModel{}, errors.New("StepListItem does not contain a key-value pair") +} + +// CreateStepIDDataFromString ... +// compositeVersionStr examples: +// * local path: +// * path::~/path/to/step/dir +// * direct git url and branch or tag: +// * git::https://github.com/bitrise-io/steps-timestamp.git@master +// * Steplib independent step: +// * _::https://github.com/bitrise-io/steps-bash-script.git@2.0.0: +// * full ID with steplib, stepid and version: +// * https://github.com/bitrise-io/bitrise-steplib.git::script@2.0.0 +// * only stepid and version (requires a default steplib source to be provided): +// * script@2.0.0 +// * only stepid, latest version will be used (requires a default steplib source to be provided): +// * script +func CreateStepIDDataFromString(compositeVersionStr, defaultStepLibSource string) (StepIDData, error) { + // first, determine the steplib-source/type + stepSrc := "" + stepIDAndVersionOrURIStr := "" + libsourceStepSplits := strings.Split(compositeVersionStr, "::") + if len(libsourceStepSplits) == 2 { + // long/verbose ID mode, ex: step-lib-src::step-id@1.0.0 + stepSrc = libsourceStepSplits[0] + stepIDAndVersionOrURIStr = libsourceStepSplits[1] + } else if len(libsourceStepSplits) == 1 { + // missing steplib-src mode, ex: step-id@1.0.0 + // in this case if we have a default StepLibSource we'll use that + stepIDAndVersionOrURIStr = libsourceStepSplits[0] + } else { + return StepIDData{}, errors.New("No StepLib found, neither default provided (" + compositeVersionStr + ")") + } + + if stepSrc == "" { + if defaultStepLibSource == "" { + return StepIDData{}, errors.New("No default StepLib source, in this case the composite ID should contain the source, separated with a '::' separator from the step ID (" + compositeVersionStr + ")") + } + stepSrc = defaultStepLibSource + } + + // now determine the ID-or-URI and the version (if provided) + stepIDOrURI := "" + stepVersion := "" + stepidVersionOrURISplits := strings.Split(stepIDAndVersionOrURIStr, "@") + if len(stepidVersionOrURISplits) >= 2 { + splitsCnt := len(stepidVersionOrURISplits) + allButLastSplits := stepidVersionOrURISplits[:splitsCnt-1] + // the ID or URI is all components except the last @version component + // which will be the version itself + // for example in case it's a git direct URI like: + // git@github.com:bitrise-io/steps-timestamp.git@develop + // which contains 2 at (@) signs only the last should be the version, + // the first one is part of the URI + stepIDOrURI = strings.Join(allButLastSplits, "@") + // version is simply the last component + stepVersion = stepidVersionOrURISplits[splitsCnt-1] + } else if len(stepidVersionOrURISplits) == 1 { + stepIDOrURI = stepidVersionOrURISplits[0] + } else { + return StepIDData{}, errors.New("Step ID and version should be separated with a '@' separator (" + stepIDAndVersionOrURIStr + ")") + } + + if stepIDOrURI == "" { + return StepIDData{}, errors.New("No ID found at all (" + compositeVersionStr + ")") + } + + if stepSrc == "git" && stepVersion == "" { + stepVersion = "master" + } + + return StepIDData{ + SteplibSource: stepSrc, + IDorURI: stepIDOrURI, + Version: stepVersion, + }, nil +} + +// IsUniqueResourceID : true if this ID is a unique resource ID, which is true +// if the ID refers to the exact same step code/data every time. +// Practically, this is only true for steps from StepLibrary collections, +// a local path or direct git step ID is never guaranteed to identify the +// same resource every time, the step's behaviour can change at every execution! +// +// __If the ID is a Unique Resource ID then the step can be cached (locally)__, +// as it won't change between subsequent step execution. +func (sIDData StepIDData) IsUniqueResourceID() bool { + switch sIDData.SteplibSource { + case "path": + return false + case "git": + return false + case "_": + return false + case "": + return false + } + + // in any other case, it's a StepLib URL + // but it's only unique if StepID and Step Version are all defined! + if len(sIDData.IDorURI) > 0 && len(sIDData.Version) > 0 { + return true + } + + // in every other case, it's not unique, not even if it's from a StepLib + return false +} + +// ---------------------------- +// --- BuildRunResults + +// IsStepLibUpdated ... +func (buildRes BuildRunResultsModel) IsStepLibUpdated(stepLib string) bool { + return (buildRes.StepmanUpdates[stepLib] > 0) +} + +// IsBuildFailed ... +func (buildRes BuildRunResultsModel) IsBuildFailed() bool { + return len(buildRes.FailedSteps) > 0 +} + +// HasFailedSkippableSteps ... +func (buildRes BuildRunResultsModel) HasFailedSkippableSteps() bool { + return len(buildRes.FailedSkippableSteps) > 0 +} + +// ResultsCount ... +func (buildRes BuildRunResultsModel) ResultsCount() int { + return len(buildRes.SuccessSteps) + len(buildRes.FailedSteps) + len(buildRes.FailedSkippableSteps) + len(buildRes.SkippedSteps) +} + +func (buildRes BuildRunResultsModel) unorderedResults() []StepRunResultsModel { + results := append([]StepRunResultsModel{}, buildRes.SuccessSteps...) + results = append(results, buildRes.FailedSteps...) + results = append(results, buildRes.FailedSkippableSteps...) + return append(results, buildRes.SkippedSteps...) +} + +//OrderedResults ... +func (buildRes BuildRunResultsModel) OrderedResults() []StepRunResultsModel { + results := make([]StepRunResultsModel, buildRes.ResultsCount()) + unorderedResults := buildRes.unorderedResults() + for _, result := range unorderedResults { + results[result.Idx] = result + } + return results +} diff --git a/vendor/github.com/bitrise-io/envman/LICENSE b/vendor/github.com/bitrise-io/envman/LICENSE new file mode 100644 index 00000000..a6a5c39a --- /dev/null +++ b/vendor/github.com/bitrise-io/envman/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Bitrise + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/bitrise-io/envman/models/models.go b/vendor/github.com/bitrise-io/envman/models/models.go new file mode 100644 index 00000000..e3d2d505 --- /dev/null +++ b/vendor/github.com/bitrise-io/envman/models/models.go @@ -0,0 +1,32 @@ +package models + +// EnvironmentItemOptionsModel ... +type EnvironmentItemOptionsModel struct { + // These fields are processed by envman at envman run + IsExpand *bool `json:"is_expand,omitempty" yaml:"is_expand,omitempty"` + SkipIfEmpty *bool `json:"skip_if_empty,omitempty" yaml:"skip_if_empty,omitempty"` + // These fields used only by bitrise + Title *string `json:"title,omitempty" yaml:"title,omitempty"` + Description *string `json:"description,omitempty" yaml:"description,omitempty"` + Summary *string `json:"summary,omitempty" yaml:"summary,omitempty"` + Category *string `json:"category,omitempty" yaml:"category,omitempty"` + ValueOptions []string `json:"value_options,omitempty" yaml:"value_options,omitempty"` + IsRequired *bool `json:"is_required,omitempty" yaml:"is_required,omitempty"` + IsDontChangeValue *bool `json:"is_dont_change_value,omitempty" yaml:"is_dont_change_value,omitempty"` + IsTemplate *bool `json:"is_template,omitempty" yaml:"is_template,omitempty"` + IsSensitive *bool `json:"is_sensitive,omitempty" yaml:"is_sensitive,omitempty"` + Unset *bool `json:"unset,omitempty" yaml:"unset,omitempty"` + // + Meta map[string]interface{} `json:"meta,omitempty" yaml:"meta,omitempty"` +} + +// EnvironmentItemModel ... +type EnvironmentItemModel map[string]interface{} + +// EnvsSerializeModel ... +type EnvsSerializeModel struct { + Envs []EnvironmentItemModel `json:"envs" yaml:"envs"` +} + +// EnvsJSONListModel ... +type EnvsJSONListModel map[string]string diff --git a/vendor/github.com/bitrise-io/envman/models/models_methods.go b/vendor/github.com/bitrise-io/envman/models/models_methods.go new file mode 100644 index 00000000..000d3210 --- /dev/null +++ b/vendor/github.com/bitrise-io/envman/models/models_methods.go @@ -0,0 +1,340 @@ +package models + +import ( + "encoding/json" + "errors" + "fmt" + "sort" + + "github.com/bitrise-io/go-utils/parseutil" + "github.com/bitrise-io/go-utils/pointers" +) + +const ( + // OptionsKey ... + OptionsKey = "opts" +) + +const ( + // DefaultIsExpand ... + DefaultIsExpand = true + // DefaultIsSensitive ... + DefaultIsSensitive = false + // DefaultSkipIfEmpty ... + DefaultSkipIfEmpty = false + + //DefaultIsRequired ... + DefaultIsRequired = false + // DefaultIsDontChangeValue ... + DefaultIsDontChangeValue = false + // DefaultIsTemplate ... + DefaultIsTemplate = false + // DefaultUnset ... + DefaultUnset = false +) + +// NewEnvJSONList ... +func NewEnvJSONList(jsonStr string) (EnvsJSONListModel, error) { + list := EnvsJSONListModel{} + if err := json.Unmarshal([]byte(jsonStr), &list); err != nil { + return EnvsJSONListModel{}, err + } + return list, nil +} + +// GetKeyValuePair ... +func (env EnvironmentItemModel) GetKeyValuePair() (string, string, error) { + // Collect keys and values + keys := []string{} + values := []interface{}{} + + for key, value := range env { + keys = append(keys, key) + values = append(values, value) + } + + if len(keys) == 0 { + return "", "", errors.New("no environment key specified") + } else if len(keys) > 2 { + sort.Strings(keys) + return "", "", fmt.Errorf("more than 2 keys specified: %v", keys) + } + + // Collect env key and value + key := "" + var value interface{} + optionsFound := false + + for i := 0; i < len(keys); i++ { + k := keys[i] + if k != OptionsKey { + key = k + value = values[i] + } else { + optionsFound = true + } + } + + if key == "" { + sort.Strings(keys) + return "", "", fmt.Errorf("no environment key found, keys: %v", keys) + } + if len(keys) > 1 && !optionsFound { + sort.Strings(keys) + return "", "", fmt.Errorf("more than 1 environment key specified: %v", keys) + } + + // Cast env value to string + valueStr := "" + + if value != nil { + if str, ok := value.(string); ok { + valueStr = str + } else if str := parseutil.CastToString(value); str != "" { + valueStr = str + } else { + return "", "", fmt.Errorf("value (%#v) is not a string for key (%s)", value, key) + } + } + + return key, valueStr, nil +} + +// ParseFromInterfaceMap ... +func (envSerModel *EnvironmentItemOptionsModel) ParseFromInterfaceMap(input map[string]interface{}) error { + for keyStr, value := range input { + + switch keyStr { + case "title": + envSerModel.Title = parseutil.CastToStringPtr(value) + case "description": + envSerModel.Description = parseutil.CastToStringPtr(value) + case "summary": + envSerModel.Summary = parseutil.CastToStringPtr(value) + case "category": + envSerModel.Category = parseutil.CastToStringPtr(value) + case "value_options": + castedValue, ok := value.([]string) + if !ok { + // try with []interface{} instead and cast the + // items to string + castedValue = []string{} + interfArr, ok := value.([]interface{}) + if !ok { + return fmt.Errorf("invalid value type (%#v) for key: %s", value, keyStr) + } + for _, interfItm := range interfArr { + castedItm, ok := interfItm.(string) + if !ok { + castedItm = parseutil.CastToString(interfItm) + if castedItm == "" { + return fmt.Errorf("not a string value (%#v) in value_options", interfItm) + } + } + castedValue = append(castedValue, castedItm) + } + } + envSerModel.ValueOptions = castedValue + case "is_required": + castedBoolPtr, ok := parseutil.CastToBoolPtr(value) + if !ok { + return fmt.Errorf("failed to parse bool value (%#v) for key (%s)", value, keyStr) + } + envSerModel.IsRequired = castedBoolPtr + case "is_expand": + castedBoolPtr, ok := parseutil.CastToBoolPtr(value) + if !ok { + return fmt.Errorf("failed to parse bool value (%#v) for key (%s)", value, keyStr) + } + envSerModel.IsExpand = castedBoolPtr + case "is_sensitive": + castedBoolPtr, ok := parseutil.CastToBoolPtr(value) + if !ok { + return fmt.Errorf("failed to parse bool value (%#v) for key (%s)", value, keyStr) + } + envSerModel.IsSensitive = castedBoolPtr + case "is_dont_change_value": + castedBoolPtr, ok := parseutil.CastToBoolPtr(value) + if !ok { + return fmt.Errorf("failed to parse bool value (%#v) for key (%s)", value, keyStr) + } + envSerModel.IsDontChangeValue = castedBoolPtr + case "is_template": + castedBoolPtr, ok := parseutil.CastToBoolPtr(value) + if !ok { + return fmt.Errorf("failed to parse bool value (%#v) for key (%s)", value, keyStr) + } + envSerModel.IsTemplate = castedBoolPtr + case "skip_if_empty": + castedBoolPtr, ok := parseutil.CastToBoolPtr(value) + if !ok { + return fmt.Errorf("failed to parse bool value (%#v) for key (%s)", value, keyStr) + } + envSerModel.SkipIfEmpty = castedBoolPtr + case "unset": + castedBoolPtr, ok := parseutil.CastToBoolPtr(value) + if !ok { + return fmt.Errorf("failed to parse bool value (%#v) for key (%s)", value, keyStr) + } + envSerModel.Unset = castedBoolPtr + case "meta": + castedMapStringInterface, ok := parseutil.CastToMapStringInterface(value) + if !ok { + return fmt.Errorf("failed to parse map[string]interface{} value (%#v) for key (%s)", value, keyStr) + } + envSerModel.Meta = castedMapStringInterface + default: + // intentional no-op case -- we just ignore unrecognized fields + } + } + return nil +} + +// GetOptions ... +func (env EnvironmentItemModel) GetOptions() (EnvironmentItemOptionsModel, error) { + value, found := env[OptionsKey] + if !found { + return EnvironmentItemOptionsModel{}, nil + } + + envItmCasted, ok := value.(EnvironmentItemOptionsModel) + if ok { + return envItmCasted, nil + } + + // if it's read from a file (YAML/JSON) then it's most likely not the proper type + // so cast it from the generic interface-interface map + normalizedOptsInterfaceMap := make(map[string]interface{}) + isNormalizeOK := false + if optionsInterfaceMap, ok := value.(map[interface{}]interface{}); ok { + // Try to normalize every key to String + for key, value := range optionsInterfaceMap { + keyStr, ok := key.(string) + if !ok { + return EnvironmentItemOptionsModel{}, fmt.Errorf("failed to cask options key (%#v) to string", key) + } + normalizedOptsInterfaceMap[keyStr] = value + } + isNormalizeOK = true + } else { + if castedTmp, ok := value.(map[string]interface{}); ok { + normalizedOptsInterfaceMap = castedTmp + isNormalizeOK = true + } + } + + if isNormalizeOK { + options := EnvironmentItemOptionsModel{} + err := options.ParseFromInterfaceMap(normalizedOptsInterfaceMap) + if err != nil { + return EnvironmentItemOptionsModel{}, err + } + + return options, nil + } + + return EnvironmentItemOptionsModel{}, fmt.Errorf("failed to cast options value: (%#v)", value) +} + +// Normalize ... +func (env *EnvironmentItemModel) Normalize() error { + opts, err := env.GetOptions() + if err != nil { + return err + } + (*env)[OptionsKey] = opts + return nil +} + +// Normalize - if successful this makes the model JSON serializable. +// Without this, if the object was created with e.g. a YAML parser, +// the type of `opts` might be map[interface]interface, which is not JSON serializable. +// After this call it's ensured that the type of objects is map[string]interface, +// which is JSON serializable. +func (envsSerializeObj *EnvsSerializeModel) Normalize() error { + for _, envObj := range envsSerializeObj.Envs { + if err := envObj.Normalize(); err != nil { + return err + } + } + return nil +} + +// FillMissingDefaults ... +func (env *EnvironmentItemModel) FillMissingDefaults() error { + options, err := env.GetOptions() + if err != nil { + return err + } + if options.Title == nil { + options.Title = pointers.NewStringPtr("") + } + if options.Description == nil { + options.Description = pointers.NewStringPtr("") + } + if options.Summary == nil { + options.Summary = pointers.NewStringPtr("") + } + if options.Category == nil { + options.Category = pointers.NewStringPtr("") + } + if options.ValueOptions == nil { + options.ValueOptions = []string{} + } + if options.IsRequired == nil { + options.IsRequired = pointers.NewBoolPtr(DefaultIsRequired) + } + if options.IsExpand == nil { + options.IsExpand = pointers.NewBoolPtr(DefaultIsExpand) + } + if options.IsSensitive == nil { + options.IsSensitive = pointers.NewBoolPtr(DefaultIsSensitive) + } + if options.IsDontChangeValue == nil { + options.IsDontChangeValue = pointers.NewBoolPtr(DefaultIsDontChangeValue) + } + if options.IsTemplate == nil { + options.IsTemplate = pointers.NewBoolPtr(DefaultIsTemplate) + } + if options.SkipIfEmpty == nil { + options.SkipIfEmpty = pointers.NewBoolPtr(DefaultSkipIfEmpty) + } + if options.Meta == nil { + options.Meta = map[string]interface{}{} + } + if options.Unset == nil { + options.Unset = pointers.NewBoolPtr(DefaultUnset) + } + + (*env)[OptionsKey] = options + return nil +} + +// Validate ... +func (env EnvironmentItemModel) Validate() error { + key, _, err := env.GetKeyValuePair() + if err != nil { + return err + } + if key == "" { + return errors.New("no environment key found") + } + _, err = env.GetOptions() + if err != nil { + return err + } + return nil +} + +// NormalizeValidateFillDefaults ... +func (env EnvironmentItemModel) NormalizeValidateFillDefaults() error { + if err := env.Normalize(); err != nil { + return err + } + + if err := env.Validate(); err != nil { + return err + } + + return env.FillMissingDefaults() +} diff --git a/vendor/github.com/bitrise-tools/go-android/sdk/sdk.go b/vendor/github.com/bitrise-io/go-android/sdk/sdk.go similarity index 100% rename from vendor/github.com/bitrise-tools/go-android/sdk/sdk.go rename to vendor/github.com/bitrise-io/go-android/sdk/sdk.go diff --git a/vendor/github.com/bitrise-io/go-steputils/stepconf/stepconf.go b/vendor/github.com/bitrise-io/go-steputils/stepconf/stepconf.go new file mode 100644 index 00000000..a47b2fef --- /dev/null +++ b/vendor/github.com/bitrise-io/go-steputils/stepconf/stepconf.go @@ -0,0 +1,217 @@ +package stepconf + +import ( + "errors" + "fmt" + "os" + "reflect" + "regexp" + "strconv" + "strings" + + "github.com/bitrise-io/go-utils/colorstring" + "github.com/bitrise-io/go-utils/parseutil" +) + +// ErrNotStructPtr indicates a type is not a pointer to a struct. +var ErrNotStructPtr = errors.New("must be a pointer to a struct") + +// ParseError occurs when a struct field cannot be set. +type ParseError struct { + Field string + Value string + Err error +} + +// Error implements builtin errors.Error. +func (e *ParseError) Error() string { + segments := []string{e.Field} + if e.Value != "" { + segments = append(segments, e.Value) + } + segments = append(segments, e.Err.Error()) + return strings.Join(segments, ": ") +} + +// Secret variables are not shown in the printed output. +type Secret string + +const secret = "*****" + +// String implements fmt.Stringer.String. +// When a Secret is printed, it's masking the underlying string with asterisks. +func (s Secret) String() string { + if s == "" { + return "" + } + return secret +} + +// Print the name of the struct with Title case in blue color with followed by a newline, +// then print all fields formatted as '- field name: field value` separated by newline. +func Print(config interface{}) { + fmt.Printf(toString(config)) +} + +// returns the name of the struct with Title case in blue color followed by a newline, +// then print all fields formatted as '- field name: field value` separated by newline. +func toString(config interface{}) string { + v := reflect.ValueOf(config) + t := reflect.TypeOf(config) + + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + + str := fmt.Sprintf(colorstring.Bluef("%s:\n", strings.Title(t.Name()))) + for i := 0; i < t.NumField(); i++ { + str += fmt.Sprintf("- %s: %v\n", t.Field(i).Name, v.Field(i).Interface()) + } + + return str +} + +// parseTag splits a struct field's env tag into its name and option. +func parseTag(tag string) (string, string) { + if idx := strings.Index(tag, ","); idx != -1 { + return tag[:idx], tag[idx+1:] + } + return tag, "" +} + +// Parse populates a struct with the retrieved values from environment variables +// described by struct tags and applies the defined validations. +func Parse(conf interface{}) error { + c := reflect.ValueOf(conf) + if c.Kind() != reflect.Ptr { + return ErrNotStructPtr + } + c = c.Elem() + if c.Kind() != reflect.Struct { + return ErrNotStructPtr + } + t := c.Type() + + var errs []*ParseError + for i := 0; i < c.NumField(); i++ { + tag, ok := t.Field(i).Tag.Lookup("env") + if !ok { + continue + } + key, constraint := parseTag(tag) + value := os.Getenv(key) + + if err := setField(c.Field(i), value, constraint); err != nil { + errs = append(errs, &ParseError{t.Field(i).Name, value, err}) + } + } + if len(errs) > 0 { + errorString := "failed to parse config:" + for _, err := range errs { + errorString += fmt.Sprintf("\n- %s", err) + } + + errorString += fmt.Sprintf("\n\n%s", toString(conf)) + return errors.New(errorString) + } + + return nil +} + +func setField(field reflect.Value, value, constraint string) error { + switch constraint { + case "": + break + case "required": + if value == "" { + return errors.New("required variable is not present") + } + case "file", "dir": + if err := checkPath(value, constraint == "dir"); err != nil { + return err + } + // TODO: use FindStringSubmatch to distinguish no match and match for empty string. + case regexp.MustCompile(`^opt\[.*\]$`).FindString(constraint): + if !contains(value, constraint) { + // TODO: print only the value options, not the whole string. + return fmt.Errorf("value is not in value options (%s)", constraint) + } + default: + return fmt.Errorf("invalid constraint (%s)", constraint) + } + + if value == "" { + return nil + } + + switch field.Kind() { + case reflect.String: + field.SetString(value) + case reflect.Bool: + b, err := parseutil.ParseBool(value) + if err != nil { + return errors.New("can't convert to bool") + } + field.SetBool(b) + case reflect.Int: + n, err := strconv.ParseInt(value, 10, 32) + if err != nil { + return errors.New("can't convert to int") + } + field.SetInt(n) + case reflect.Slice: + field.Set(reflect.ValueOf(strings.Split(value, "|"))) + default: + return fmt.Errorf("type is not supported (%s)", field.Kind()) + } + return nil +} + +func checkPath(path string, dir bool) error { + file, err := os.Stat(path) + if err != nil { + // TODO: check case when file exist but os.Stat fails. + return os.ErrNotExist + } + if dir && !file.IsDir() { + return errors.New("not a directory") + } + return nil +} + +// contains reports whether s is within the value options, where value options +// are parsed from opt, which format's is opt[item1,item2,item3]. If an option +// contains commas, it should be single quoted (eg. opt[item1,'item2,item3']). +func contains(s, opt string) bool { + opt = strings.TrimSuffix(strings.TrimPrefix(opt, "opt["), "]") + var valueOpts []string + if strings.Contains(opt, "'") { + // The single quotes separate the options with comma and without comma + // Eg. "a,b,'c,d',e" will results "a,b," "c,d" and ",e" strings. + for _, s := range strings.Split(opt, "'") { + switch { + case s == "," || s == "": + case !strings.HasPrefix(s, ",") && !strings.HasSuffix(s, ","): + // If a string doesn't starts nor ends with a comma it means it's an option which + // contains comma, so we just append it to valueOpts as it is. Eg. "c,d" from above. + valueOpts = append(valueOpts, s) + default: + // If a string starts or ends with comma it means that it contains options without comma. + // So we split the string at commas to get the options. Eg. "a,b," and ",e" from above. + valueOpts = append(valueOpts, strings.Split(strings.Trim(s, ","), ",")...) + } + } + } else { + valueOpts = strings.Split(opt, ",") + } + for _, valOpt := range valueOpts { + if valOpt == s { + return true + } + } + return false +} diff --git a/vendor/github.com/bitrise-tools/go-steputils/tools/tools.go b/vendor/github.com/bitrise-io/go-steputils/tools/tools.go similarity index 100% rename from vendor/github.com/bitrise-tools/go-steputils/tools/tools.go rename to vendor/github.com/bitrise-io/go-steputils/tools/tools.go diff --git a/vendor/github.com/bitrise-io/go-utils/.gitignore b/vendor/github.com/bitrise-io/go-utils/.gitignore deleted file mode 100644 index 1bc052be..00000000 --- a/vendor/github.com/bitrise-io/go-utils/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.bitrise* -.gows.user.yml -.DS_Store diff --git a/vendor/github.com/bitrise-io/go-utils/README.md b/vendor/github.com/bitrise-io/go-utils/README.md deleted file mode 100644 index 744f21b7..00000000 --- a/vendor/github.com/bitrise-io/go-utils/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# go-utils -Common, utility packages for Go diff --git a/vendor/github.com/bitrise-io/go-utils/_scripts/install_bitrise_osx.sh b/vendor/github.com/bitrise-io/go-utils/_scripts/install_bitrise_osx.sh deleted file mode 100644 index ac1d1302..00000000 --- a/vendor/github.com/bitrise-io/go-utils/_scripts/install_bitrise_osx.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash - -set -e -set -v - - -curl -L https://github.com/bitrise-io/bitrise/releases/download/0.9.11/bitrise-$(uname -s)-$(uname -m) > /usr/local/bin/bitrise - -chmod +x /usr/local/bin/bitrise - -bitrise setup --minimal diff --git a/vendor/github.com/bitrise-io/go-utils/bitrise.yml b/vendor/github.com/bitrise-io/go-utils/bitrise.yml deleted file mode 100644 index 291b445a..00000000 --- a/vendor/github.com/bitrise-io/go-utils/bitrise.yml +++ /dev/null @@ -1,98 +0,0 @@ -format_version: 1.0.0 -default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git - -app: - envs: - - BITRISE_BIN_NAME: go-utils - -workflows: - - _install_test_tools: - steps: - - script: - title: Install required testing tools - inputs: - - content: |- - #!/bin/bash - set -ex - - # Check for unhandled errors - go get -u github.com/kisielk/errcheck - - # Go lint - go get -u github.com/golang/lint/golint - - go get -u github.com/stretchr/testify/require - go get -u golang.org/x/crypto/ssh/terminal - go get -u gopkg.in/yaml.v2 - - test: - steps: - - script: - title: Print go environment - inputs: - - content: |- - set -ex - - go version - - script: - title: Export go files to test - inputs: - - content: |- - set -ex - go_list="$(go list ./... | grep -v "github.com/bitrise-io/go-utils/pkcs12*")" - envman add --key GOLIST --value "$go_list" - - script: - title: Err check - inputs: - - content: errcheck -asserts=true -blank=true $GOLIST - - script: - title: Go lint - inputs: - - content: |- - #!/bin/bash - set -e - while read -r line; do - echo "-> Linting: $line" - golint_out="$(golint $line)" - if [[ "${golint_out}" != "" ]] ; then - echo "=> Golint issues found:" - echo "${golint_out}" - exit 1 - fi - done <<< "$GOLIST" - - script: - title: Go test - inputs: - - content: go test ./... - - script: - title: Go test coverage - description: | - To get the HTML report of a single package: - go test -coverprofile=coverage.out ./PACKAGE/ - go tool cover -html coverage.out - inputs: - - content: go test -cover ./... - - ci: - before_run: - - _install_test_tools - - test - steps: - - slack: - run_if: .IsCI - inputs: - - webhook_url: $INTERNAL_DEV_SLACK_WEBHOOK_URL - - channel: $INTERNAL_DEV_SLACK_CHANNEL - - from_username: ${BITRISE_BIN_NAME} - CI - OK - - from_username_on_error: ${BITRISE_BIN_NAME} - CI - ERROR - - emoji: ":white_check_mark:" - - emoji_on_error: ":no_entry_sign:" - - message: |- - CI was successful on branch: *${BITRISE_GIT_BRANCH}* - - Build URL: ${BITRISE_BUILD_URL} - - message_on_error: |- - CI FAILED on branch: *${BITRISE_GIT_BRANCH}* - - Build URL: ${BITRISE_BUILD_URL} diff --git a/vendor/github.com/bitrise-io/go-utils/builtinutil/builtinutil.go b/vendor/github.com/bitrise-io/go-utils/builtinutil/builtinutil.go deleted file mode 100644 index 28ca58b9..00000000 --- a/vendor/github.com/bitrise-io/go-utils/builtinutil/builtinutil.go +++ /dev/null @@ -1,37 +0,0 @@ -package builtinutil - -import ( - "fmt" - "reflect" -) - -// CastInterfaceToInterfaceSlice ... -func CastInterfaceToInterfaceSlice(slice interface{}) ([]interface{}, error) { - s := reflect.ValueOf(slice) - if s.Kind() != reflect.Slice { - return []interface{}{}, fmt.Errorf("Input is not a slice: %#v", slice) - } - - ret := make([]interface{}, s.Len()) - - for i := 0; i < s.Len(); i++ { - ret[i] = s.Index(i).Interface() - } - - return ret, nil -} - -// DeepEqualSlices ... -func DeepEqualSlices(expected, actual []interface{}) bool { - expectedMap := map[string]bool{} - for _, itm := range expected { - itmAsStr := fmt.Sprintf("%#v", itm) - expectedMap[itmAsStr] = true - } - actualMap := map[string]bool{} - for _, itm := range actual { - itmAsStr := fmt.Sprintf("%#v", itm) - actualMap[itmAsStr] = true - } - return reflect.DeepEqual(expectedMap, actualMap) -} diff --git a/vendor/github.com/bitrise-io/go-utils/builtinutil/builtinutil_test.go b/vendor/github.com/bitrise-io/go-utils/builtinutil/builtinutil_test.go deleted file mode 100644 index b44bc519..00000000 --- a/vendor/github.com/bitrise-io/go-utils/builtinutil/builtinutil_test.go +++ /dev/null @@ -1,92 +0,0 @@ -package builtinutil - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestCastInterfaceToInterfaceSlice(t *testing.T) { - // string - casted, err := CastInterfaceToInterfaceSlice([]string{"a", "b", "c"}) - require.NoError(t, err) - require.Equal(t, "a", casted[0]) - require.Equal(t, "b", casted[1]) - require.Equal(t, "c", casted[2]) - - // int - casted, err = CastInterfaceToInterfaceSlice([]int{3, 2, 1}) - require.NoError(t, err) - require.Equal(t, 3, casted[0]) - require.Equal(t, 2, casted[1]) - require.Equal(t, 1, casted[2]) - - // empty - casted, err = CastInterfaceToInterfaceSlice([]string{}) - require.NoError(t, err) - require.Equal(t, []interface{}{}, casted) -} - -func TestDeepEqualSlices(t *testing.T) { - { - // - s1 := []string{"a", "b"} - interfaceS1, err := CastInterfaceToInterfaceSlice(s1) - require.NoError(t, err) - // - s2 := []string{"b", "a"} - interfaceS2, err := CastInterfaceToInterfaceSlice(s2) - require.NoError(t, err) - // equal, order doesn't matter - require.True(t, DeepEqualSlices(interfaceS1, interfaceS2)) - - // NOT equal - s3 := []string{"b", "a", "c"} - interfaceS3, err := CastInterfaceToInterfaceSlice(s3) - require.NoError(t, err) - require.False(t, DeepEqualSlices(interfaceS1, interfaceS3)) - - // NOT equal - same length but element differs - s4 := []string{"b", "x"} - interfaceS4, err := CastInterfaceToInterfaceSlice(s4) - require.NoError(t, err) - require.False(t, DeepEqualSlices(interfaceS1, interfaceS4)) - } - - // empty - { - require.True(t, DeepEqualSlices([]interface{}{}, []interface{}{})) - } - - t.Log("Custom struct type") - { - type TestType struct { - StrKey string - IntSlice []int - } - s1 := []TestType{ - {StrKey: "key1", IntSlice: []int{1, 2}}, - {StrKey: "key2", IntSlice: []int{3, 4, 5}}, - } - s2 := []TestType{ - {StrKey: "key2", IntSlice: []int{3, 4, 5}}, - {StrKey: "key1", IntSlice: []int{1, 2}}, - } - - t.Log(" Should be equal") - interfaceS1, err := CastInterfaceToInterfaceSlice(s1) - require.NoError(t, err) - interfaceS2, err := CastInterfaceToInterfaceSlice(s2) - require.NoError(t, err) - require.True(t, DeepEqualSlices(interfaceS1, interfaceS2)) - - t.Log(" Should NOT be equal") - s3 := []TestType{ - {StrKey: "key2", IntSlice: []int{3, 4, 5}}, - {StrKey: "key3", IntSlice: []int{6, 7}}, - } - interfaceS3, err := CastInterfaceToInterfaceSlice(s3) - require.NoError(t, err) - require.False(t, DeepEqualSlices(interfaceS1, interfaceS3)) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/colorstring/colorstring_test.go b/vendor/github.com/bitrise-io/go-utils/colorstring/colorstring_test.go deleted file mode 100644 index 05974234..00000000 --- a/vendor/github.com/bitrise-io/go-utils/colorstring/colorstring_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package colorstring - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestAddColor(t *testing.T) { - /* - blackColor Color = "\x1b[30;1m" - resetColor Color = "\x1b[0m" - */ - - t.Log("colored_string = color + string + reset_color") - { - desiredColored := "\x1b[30;1m" + "test" + "\x1b[0m" - colored := addColor(blackColor, "test") - require.Equal(t, desiredColored, colored) - } -} - -func TestBlack(t *testing.T) { - t.Log("Simple string can be blacked") - { - desiredColored := "\x1b[30;1m" + "test" + "\x1b[0m" - colored := Black("test") - require.Equal(t, desiredColored, colored) - } - - t.Log("Multiple strings can be blacked") - { - desiredColored := "\x1b[30;1m" + "Hello Bitrise !" + "\x1b[0m" - colored := Black("Hello ", "Bitrise ", "!") - require.Equal(t, desiredColored, colored) - } -} - -func TestBlackf(t *testing.T) { - t.Log("Simple format can be blacked") - { - desiredColored := "\x1b[30;1m" + fmt.Sprintf("Hello %s", "bitrise") + "\x1b[0m" - colored := Blackf("Hello %s", "bitrise") - require.Equal(t, desiredColored, colored) - } - - t.Log("Complex format can be blacked") - { - desiredColored := "\x1b[30;1m" + fmt.Sprintf("Hello %s %s", "bitrise", "!") + "\x1b[0m" - colored := Blackf("Hello %s %s", "bitrise", "!") - require.Equal(t, desiredColored, colored) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/command/command_test.go b/vendor/github.com/bitrise-io/go-utils/command/command_test.go deleted file mode 100644 index 8816d7ae..00000000 --- a/vendor/github.com/bitrise-io/go-utils/command/command_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package command - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewCommandSlice(t *testing.T) { - t.Log("it fails if slice empty") - { - cmd, err := NewFromSlice([]string{}) - require.Error(t, err) - require.Equal(t, (*Model)(nil), cmd) - } - - t.Log("it creates cmd if cmdSlice has 1 element") - { - _, err := NewFromSlice([]string{"ls"}) - require.NoError(t, err) - } - - t.Log("it creates cmd if cmdSlice has multiple elements") - { - _, err := NewFromSlice([]string{"ls", "-a", "-l", "-h"}) - require.NoError(t, err) - } -} - -func TestNewWithParams(t *testing.T) { - t.Log("it fails if params empty") - { - cmd, err := NewWithParams() - require.Error(t, err) - require.Equal(t, (*Model)(nil), cmd) - } - - t.Log("it creates cmd if params has 1 element") - { - _, err := NewWithParams("ls") - require.NoError(t, err) - } - - t.Log("it creates cmd if params has multiple elements") - { - _, err := NewWithParams("ls", "-a", "-l", "-h") - require.NoError(t, err) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/command/file_test.go b/vendor/github.com/bitrise-io/go-utils/command/file_test.go deleted file mode 100644 index 7647f871..00000000 --- a/vendor/github.com/bitrise-io/go-utils/command/file_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package command - -import ( - "testing" - - "github.com/bitrise-io/go-utils/pathutil" - "github.com/stretchr/testify/require" -) - -func TestCopyFileErrorIfDirectory(t *testing.T) { - t.Log("It fails if source is a directory") - { - tmpFolder, err := pathutil.NormalizedOSTempDirPath("_tmp") - require.NoError(t, err) - require.EqualError(t, CopyFile(tmpFolder, "./nothing/whatever"), "Source is a directory: "+tmpFolder) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/command/git/git.go b/vendor/github.com/bitrise-io/go-utils/command/git/git.go deleted file mode 100644 index 22d4087a..00000000 --- a/vendor/github.com/bitrise-io/go-utils/command/git/git.go +++ /dev/null @@ -1,209 +0,0 @@ -package git - -import ( - "fmt" - - "os" - - "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-io/go-utils/pathutil" -) - -func setStandardOutAndErr(cmd *command.Model) { - cmd.SetStdout(os.Stdout) - cmd.SetStderr(os.Stderr) -} - -// CloneCommand ... -func CloneCommand(uri, destination string) *command.Model { - return command.New("git", "clone", "--recursive", uri, destination) -} - -// Clone ... -func Clone(uri, destination string) error { - cmd := CloneCommand(uri, destination) - setStandardOutAndErr(cmd) - return cmd.Run() -} - -// CloneTagOrBranchCommand ... -func CloneTagOrBranchCommand(uri, destination, tagOrBranch string) *command.Model { - return command.New("git", "clone", "--recursive", "--branch", tagOrBranch, uri, destination) -} - -// CloneTagOrBranch ... -func CloneTagOrBranch(uri, destination, tagOrBranch string) error { - cmd := CloneTagOrBranchCommand(uri, destination, tagOrBranch) - setStandardOutAndErr(cmd) - return cmd.Run() -} - -// BranchCommand ... -func BranchCommand() *command.Model { - return command.New("git", "branch") -} - -// CloneTagAndEnsureHead ... -func CloneTagAndEnsureHead(uri, destination, tag string) error { - cmd := CloneTagOrBranchCommand(uri, destination, tag) - setStandardOutAndErr(cmd) - if err := cmd.Run(); err != nil { - return fmt.Errorf("(%s) failed, error: %s", cmd.PrintableCommandArgs(), err) - } - - cmd = BranchCommand() - cmd.SetDir(destination) - out, err := cmd.RunAndReturnTrimmedCombinedOutput() - if err != nil { - return fmt.Errorf("(%s) failed, error: %s", cmd.PrintableCommandArgs(), err) - } - - if out != "* (no branch)" { - return fmt.Errorf("current HEAD is not detached head, current branch should be: '* (no branch)', got: %s", out) - } - - return nil -} - -// CloneTagOrBranchAndValidateCommitHash ... -func CloneTagOrBranchAndValidateCommitHash(uri, destination, tagOrBranch, commithash string) error { - cmd := CloneTagOrBranchCommand(uri, destination, tagOrBranch) - setStandardOutAndErr(cmd) - if err := cmd.Run(); err != nil { - return fmt.Errorf("(%s) failed, error: %s", cmd.PrintableCommandArgs(), err) - } - - cmd = GetCommitHashOfHeadCommand() - cmd.SetDir(destination) - out, err := cmd.RunAndReturnTrimmedCombinedOutput() - if err != nil { - return fmt.Errorf("(%s) failed, error: %s", cmd.PrintableCommandArgs(), err) - } - if commithash != out { - return fmt.Errorf("commit hash doesn't match the one specified for the version tag. (version tag: %s) (expected commit hash: %s) (got: %s)", tagOrBranch, out, commithash) - } - - return nil -} - -// PullCommand ... -func PullCommand() *command.Model { - return command.New("git", "pull") -} - -// Pull ... -func Pull(sourceDir string) error { - cmd := PullCommand() - setStandardOutAndErr(cmd) - cmd.SetDir(sourceDir) - return cmd.Run() -} - -// Update ... -func Update(uri, sourceDir string) error { - if exists, err := pathutil.IsPathExists(sourceDir); err != nil { - return err - } else if !exists { - return Clone(uri, sourceDir) - } - - return Pull(sourceDir) -} - -// CheckoutCommand ... -func CheckoutCommand(branchOrTag string) *command.Model { - return command.New("git", "checkout", branchOrTag) -} - -// Checkout ... -func Checkout(sourceDir, branchOrTag string) error { - cmd := CheckoutCommand(branchOrTag) - setStandardOutAndErr(cmd) - cmd.SetDir(sourceDir) - return cmd.Run() -} - -// CreateAndCheckoutBranchCommand ... -func CreateAndCheckoutBranchCommand(branch string) *command.Model { - return command.New("git", "checkout", "-b", branch) -} - -// CreateAndCheckoutBranch ... -func CreateAndCheckoutBranch(sourceDir, branch string) error { - cmd := CreateAndCheckoutBranchCommand(branch) - setStandardOutAndErr(cmd) - cmd.SetDir(sourceDir) - return cmd.Run() -} - -// AddCommand ... -func AddCommand(pth string) *command.Model { - return command.New("git", "add", pth) -} - -// AddFile ... -func AddFile(sourceDir, filePth string) error { - cmd := AddCommand(filePth) - setStandardOutAndErr(cmd) - cmd.SetDir(sourceDir) - return cmd.Run() -} - -// PushToOriginCommand ... -func PushToOriginCommand(branch string) *command.Model { - return command.New("git", "push", "-u", "origin", branch) -} - -// PushToOrigin ... -func PushToOrigin(sourceDir, branch string) error { - cmd := PushToOriginCommand(branch) - setStandardOutAndErr(cmd) - cmd.SetDir(sourceDir) - return cmd.Run() -} - -// StatusPorcelainCommand ... -func StatusPorcelainCommand() *command.Model { - return command.New("git", "status", "--porcelain") -} - -// CheckIsNoChanges ... -func CheckIsNoChanges(sourceDir string) error { - cmd := StatusPorcelainCommand() - cmd.SetDir(sourceDir) - - out, err := cmd.RunAndReturnTrimmedCombinedOutput() - if err != nil { - return fmt.Errorf("(%s) failed, error: %s", cmd.PrintableCommandArgs(), err) - } - - if out != "" { - return fmt.Errorf("uncommited changes: %s", out) - } - return nil -} - -// CommitCommand ... -func CommitCommand(message string) *command.Model { - return command.New("git", "commit", "-m", message) -} - -// Commit ... -func Commit(sourceDir string, message string) error { - cmd := CommitCommand(message) - setStandardOutAndErr(cmd) - cmd.SetDir(sourceDir) - return cmd.Run() -} - -// GetCommitHashOfHeadCommand ... -func GetCommitHashOfHeadCommand() *command.Model { - return command.New("git", "rev-parse", "HEAD") -} - -// GetCommitHashOfHead ... -func GetCommitHashOfHead(pth string) (string, error) { - cmd := GetCommitHashOfHeadCommand() - cmd.SetDir(pth) - return cmd.RunAndReturnTrimmedCombinedOutput() -} diff --git a/vendor/github.com/bitrise-io/go-utils/command/rubycommand/rubycommand.go b/vendor/github.com/bitrise-io/go-utils/command/rubycommand/rubycommand.go deleted file mode 100644 index 3a6b9389..00000000 --- a/vendor/github.com/bitrise-io/go-utils/command/rubycommand/rubycommand.go +++ /dev/null @@ -1,200 +0,0 @@ -package rubycommand - -import ( - "errors" - "regexp" - - "bufio" - "bytes" - - "fmt" - - "github.com/bitrise-io/go-utils/command" -) - -const ( - systemRubyPth = "/usr/bin/ruby" - brewRubyPth = "/usr/local/bin/ruby" -) - -// InstallType ... -type InstallType int8 - -const ( - // Unkown ... - Unkown InstallType = iota - // SystemRuby ... - SystemRuby - // BrewRuby ... - BrewRuby - // RVMRuby ... - RVMRuby - // RbenvRuby ... - RbenvRuby -) - -func cmdExist(slice ...string) bool { - if len(slice) == 0 { - return false - } - - cmd, err := command.NewWithParams(slice...) - if err != nil { - return false - } - - return (cmd.Run() == nil) -} - -func installType() InstallType { - whichRuby, err := command.New("which", "ruby").RunAndReturnTrimmedCombinedOutput() - if err != nil { - return Unkown - } - - installType := Unkown - if whichRuby == systemRubyPth { - installType = SystemRuby - } else if whichRuby == brewRubyPth { - installType = BrewRuby - } else if cmdExist("rvm", "-v") { - installType = RVMRuby - } else if cmdExist("rbenv", "-v") { - installType = RbenvRuby - } - - return installType -} - -func sudoNeeded(installType InstallType, slice ...string) bool { - if installType != SystemRuby { - return false - } - - if len(slice) < 2 { - return false - } - - name := slice[0] - command := slice[1] - if name == "bundle" { - return (command == "install" || command == "update") - } else if name == "gem" { - return (command == "install" || command == "uninstall") - } - - return false -} - -// NewWithParams ... -func NewWithParams(params ...string) (*command.Model, error) { - rubyInstallType := installType() - if rubyInstallType == Unkown { - return nil, errors.New("unkown ruby installation type") - } - - if sudoNeeded(rubyInstallType, params...) { - params = append([]string{"sudo"}, params...) - } - - return command.NewWithParams(params...) -} - -// NewFromSlice ... -func NewFromSlice(slice []string) (*command.Model, error) { - return NewWithParams(slice...) -} - -// New ... -func New(name string, args ...string) (*command.Model, error) { - slice := append([]string{name}, args...) - return NewWithParams(slice...) -} - -// GemUpdate ... -func GemUpdate(gem string) ([]*command.Model, error) { - cmds := []*command.Model{} - - cmd, err := New("gem", "update", gem, "--no-document") - if err != nil { - return []*command.Model{}, err - } - - cmds = append(cmds, cmd) - - rubyInstallType := installType() - if rubyInstallType == RbenvRuby { - cmd, err := New("rbenv", "rehash") - if err != nil { - return []*command.Model{}, err - } - - cmds = append(cmds, cmd) - } - - return cmds, nil -} - -// GemInstall ... -func GemInstall(gem, version string) ([]*command.Model, error) { - cmds := []*command.Model{} - - slice := []string{"gem", "install", gem, "--no-document"} - if version != "" { - slice = append(slice, "-v", version) - } - - cmd, err := NewFromSlice(slice) - if err != nil { - return []*command.Model{}, err - } - - cmds = append(cmds, cmd) - - rubyInstallType := installType() - if rubyInstallType == RbenvRuby { - cmd, err := New("rbenv", "rehash") - if err != nil { - return []*command.Model{}, err - } - - cmds = append(cmds, cmd) - } - - return cmds, nil -} - -func findGemInList(gemList, gem, version string) (bool, error) { - // minitest (5.10.1, 5.9.1, 5.9.0, 5.8.3, 4.7.5) - pattern := fmt.Sprintf(`^%s \(.*%s.*\)`, gem, version) - re := regexp.MustCompile(pattern) - - reader := bytes.NewReader([]byte(gemList)) - scanner := bufio.NewScanner(reader) - for scanner.Scan() { - line := scanner.Text() - match := re.FindString(line) - if match != "" { - return true, nil - } - } - if err := scanner.Err(); err != nil { - return false, err - } - return false, nil -} - -// IsGemInstalled ... -func IsGemInstalled(gem, version string) (bool, error) { - cmd, err := New("gem", "list") - if err != nil { - return false, err - } - - out, err := cmd.RunAndReturnTrimmedCombinedOutput() - if err != nil { - return false, err - } - - return findGemInList(out, gem, version) -} diff --git a/vendor/github.com/bitrise-io/go-utils/command/rubycommand/rubycommand_test.go b/vendor/github.com/bitrise-io/go-utils/command/rubycommand/rubycommand_test.go deleted file mode 100644 index b3c07790..00000000 --- a/vendor/github.com/bitrise-io/go-utils/command/rubycommand/rubycommand_test.go +++ /dev/null @@ -1,129 +0,0 @@ -package rubycommand - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestCmdExist(t *testing.T) { - t.Log("exist") - { - require.Equal(t, true, cmdExist("ls")) - } - - t.Log("not exist") - { - require.Equal(t, false, cmdExist("__not_existing_command__")) - } -} - -func TestSudoNeeded(t *testing.T) { - t.Log("sudo NOT need") - { - require.Equal(t, false, sudoNeeded(Unkown, "ls")) - require.Equal(t, false, sudoNeeded(SystemRuby, "ls")) - require.Equal(t, false, sudoNeeded(BrewRuby, "ls")) - require.Equal(t, false, sudoNeeded(RVMRuby, "ls")) - require.Equal(t, false, sudoNeeded(RbenvRuby, "ls")) - } - - t.Log("sudo needed for SystemRuby in case of gem list management command") - { - require.Equal(t, false, sudoNeeded(Unkown, "gem", "install", "fastlane")) - require.Equal(t, true, sudoNeeded(SystemRuby, "gem", "install", "fastlane")) - require.Equal(t, false, sudoNeeded(BrewRuby, "gem", "install", "fastlane")) - require.Equal(t, false, sudoNeeded(RVMRuby, "gem", "install", "fastlane")) - require.Equal(t, false, sudoNeeded(RbenvRuby, "gem", "install", "fastlane")) - - require.Equal(t, false, sudoNeeded(Unkown, "gem", "uninstall", "fastlane")) - require.Equal(t, true, sudoNeeded(SystemRuby, "gem", "uninstall", "fastlane")) - require.Equal(t, false, sudoNeeded(BrewRuby, "gem", "uninstall", "fastlane")) - require.Equal(t, false, sudoNeeded(RVMRuby, "gem", "uninstall", "fastlane")) - require.Equal(t, false, sudoNeeded(RbenvRuby, "gem", "uninstall", "fastlane")) - - require.Equal(t, false, sudoNeeded(Unkown, "bundle", "install")) - require.Equal(t, true, sudoNeeded(SystemRuby, "bundle", "install")) - require.Equal(t, false, sudoNeeded(BrewRuby, "bundle", "install")) - require.Equal(t, false, sudoNeeded(RVMRuby, "bundle", "install")) - require.Equal(t, false, sudoNeeded(RbenvRuby, "bundle", "install")) - - require.Equal(t, false, sudoNeeded(Unkown, "bundle", "update")) - require.Equal(t, true, sudoNeeded(SystemRuby, "bundle", "update")) - require.Equal(t, false, sudoNeeded(BrewRuby, "bundle", "update")) - require.Equal(t, false, sudoNeeded(RVMRuby, "bundle", "update")) - require.Equal(t, false, sudoNeeded(RbenvRuby, "bundle", "update")) - } -} - -func TestFindGemInList(t *testing.T) { - t.Log("finds gem") - { - gemList := ` -*** LOCAL GEMS *** - -addressable (2.5.0, 2.4.0, 2.3.8) -activesupport (5.0.0.1, 4.2.7.1, 4.2.6, 4.2.5, 4.1.16, 4.0.13) -angularjs-rails (1.5.8)` - - found, err := findGemInList(gemList, "activesupport", "") - require.NoError(t, err) - require.Equal(t, true, found) - } - - t.Log("finds gem with version") - { - gemList := ` -*** LOCAL GEMS *** - -addressable (2.5.0, 2.4.0, 2.3.8) -activesupport (5.0.0.1, 4.2.7.1, 4.2.6, 4.2.5, 4.1.16, 4.0.13) -angularjs-rails (1.5.8)` - - found, err := findGemInList(gemList, "activesupport", "4.2.5") - require.NoError(t, err) - require.Equal(t, true, found) - } - - t.Log("gem version not found in list") - { - gemList := ` -*** LOCAL GEMS *** - -addressable (2.5.0, 2.4.0, 2.3.8) -activesupport (5.0.0.1, 4.2.7.1, 4.2.6, 4.2.5, 4.1.16, 4.0.13) -angularjs-rails (1.5.8)` - - found, err := findGemInList(gemList, "activesupport", "0.9.0") - require.NoError(t, err) - require.Equal(t, false, found) - } - - t.Log("gem not found in list") - { - gemList := ` -*** LOCAL GEMS *** - -addressable (2.5.0, 2.4.0, 2.3.8) -activesupport (5.0.0.1, 4.2.7.1, 4.2.6, 4.2.5, 4.1.16, 4.0.13) -angularjs-rails (1.5.8)` - - found, err := findGemInList(gemList, "fastlane", "") - require.NoError(t, err) - require.Equal(t, false, found) - } - - t.Log("gem with version not found in list") - { - gemList := ` -*** LOCAL GEMS *** - -addressable (2.5.0, 2.4.0, 2.3.8) -activesupport (5.0.0.1, 4.2.7.1, 4.2.6, 4.2.5, 4.1.16, 4.0.13) -angularjs-rails (1.5.8)` - - found, err := findGemInList(gemList, "fastlane", "2.70") - require.NoError(t, err) - require.Equal(t, false, found) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/command/rubyscript/rubyscript.go b/vendor/github.com/bitrise-io/go-utils/command/rubyscript/rubyscript.go deleted file mode 100644 index becf1d58..00000000 --- a/vendor/github.com/bitrise-io/go-utils/command/rubyscript/rubyscript.go +++ /dev/null @@ -1,88 +0,0 @@ -package rubyscript - -import ( - "path" - - "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-io/go-utils/fileutil" - "github.com/bitrise-io/go-utils/pathutil" -) - -// Helper ... -type Helper struct { - scriptContent string - tmpDir string - gemfilePth string -} - -// New ... -func New(scriptContent string) Helper { - return Helper{ - scriptContent: scriptContent, - } -} - -func (h *Helper) ensureTmpDir() (string, error) { - if h.tmpDir != "" { - return h.tmpDir, nil - } - - tmpDir, err := pathutil.NormalizedOSTempDirPath("__ruby-script-runner__") - if err != nil { - return "", err - } - - h.tmpDir = tmpDir - - return tmpDir, nil -} - -// BundleInstallCommand ... -func (h *Helper) BundleInstallCommand(gemfileContent, gemfileLockContent string) (*command.Model, error) { - tmpDir, err := h.ensureTmpDir() - if err != nil { - return nil, err - } - - gemfilePth := path.Join(tmpDir, "Gemfile") - if err := fileutil.WriteStringToFile(gemfilePth, gemfileContent); err != nil { - return nil, err - } - - if gemfileLockContent != "" { - gemfileLockPth := path.Join(tmpDir, "Gemfile.lock") - if err := fileutil.WriteStringToFile(gemfileLockPth, gemfileLockContent); err != nil { - return nil, err - } - } - - h.gemfilePth = gemfilePth - - // use '--gemfile=' flag to specify Gemfile path - // ... In general, bundler will assume that the location of the Gemfile(5) is also the project root, - // and will look for the Gemfile.lock and vendor/cache relative to it. ... - return command.New("bundle", "install", "--gemfile="+gemfilePth), nil -} - -// RunScriptCommand ... -func (h Helper) RunScriptCommand() (*command.Model, error) { - tmpDir, err := h.ensureTmpDir() - if err != nil { - return nil, err - } - - rubyScriptPth := path.Join(tmpDir, "script.rb") - if err := fileutil.WriteStringToFile(rubyScriptPth, h.scriptContent); err != nil { - return nil, err - } - - var cmd *command.Model - if h.gemfilePth != "" { - cmd = command.New("bundle", "exec", "ruby", rubyScriptPth) - cmd.AppendEnvs("BUNDLE_GEMFILE=" + h.gemfilePth) - } else { - cmd = command.New("ruby", rubyScriptPth) - } - - return cmd, nil -} diff --git a/vendor/github.com/bitrise-io/go-utils/command/rubyscript/rubyscript_test.go b/vendor/github.com/bitrise-io/go-utils/command/rubyscript/rubyscript_test.go deleted file mode 100644 index 6e43fa01..00000000 --- a/vendor/github.com/bitrise-io/go-utils/command/rubyscript/rubyscript_test.go +++ /dev/null @@ -1,143 +0,0 @@ -package rubyscript - -import ( - "path/filepath" - "strings" - "testing" - - "github.com/bitrise-io/go-utils/pathutil" - "github.com/stretchr/testify/require" -) - -const gemfileContent = `# frozen_string_literal: true -source "https://rubygems.org" - -gem "json" -` - -const gemfileLockContent = `GEM - remote: https://rubygems.org/ - specs: - json (2.1.0) - -PLATFORMS - ruby - -DEPENDENCIES - json - -BUNDLED WITH - 1.15.3 -` - -const rubyScriptWithGemContent = `require 'json' - -begin - messageObj = '{"message":"Hi Bitrise"}' - messageJSON = JSON.parse(messageObj) - puts "#{{ :data => messageJSON['message'] }.to_json}" -rescue => e - puts "#{{ :error => e.to_s }.to_json}" -end -` - -const rubyScriptContent = `puts '{"data":"Hi Bitrise"}'` - -func TestNew(t *testing.T) { - t.Log("initialize new ruby script runner with the ruby script content") - { - runner := New(rubyScriptContent) - require.NotNil(t, runner) - } -} - -func Test_ensureTmpDir(t *testing.T) { - t.Log("ensure runner holds a tmp dir path") - { - runner := New(rubyScriptContent) - require.NotNil(t, runner) - - tmpDir, err := runner.ensureTmpDir() - require.NoError(t, err) - - exist, err := pathutil.IsDirExists(tmpDir) - require.NoError(t, err) - require.True(t, exist) - } -} - -func TestBundleInstallCommand(t *testing.T) { - t.Log("bundle install gems") - { - runner := New(rubyScriptWithGemContent) - require.NotNil(t, runner) - - bundleInstallCmd, err := runner.BundleInstallCommand(gemfileContent, gemfileLockContent) - require.NoError(t, err) - - cmd := bundleInstallCmd.GetCmd() - - require.Equal(t, filepath.Base(cmd.Path), "bundle") - require.Equal(t, 3, len(cmd.Args)) - require.Equal(t, "bundle", cmd.Args[0]) - require.Equal(t, "install", cmd.Args[1]) - - gemfileFlag := cmd.Args[2] - split := strings.Split(gemfileFlag, "=") - require.Equal(t, 2, len(split)) - require.Equal(t, "--gemfile", split[0]) - require.Equal(t, "Gemfile", filepath.Base(split[1])) - - require.NoError(t, bundleInstallCmd.Run()) - } -} - -func TestRunScriptCommand(t *testing.T) { - t.Log("runs 'ruby script.rb'") - { - runner := New(rubyScriptContent) - require.NotNil(t, runner) - - runCmd, err := runner.RunScriptCommand() - require.NoError(t, err) - - cmd := runCmd.GetCmd() - - require.Equal(t, filepath.Base(cmd.Path), "ruby") - require.Equal(t, 2, len(cmd.Args)) - require.Equal(t, "ruby", cmd.Args[0]) - require.Equal(t, "script.rb", filepath.Base(cmd.Args[1])) - - out, err := runCmd.RunAndReturnTrimmedCombinedOutput() - require.NoError(t, err) - require.Equal(t, `{"data":"Hi Bitrise"}`, out) - } - - t.Log("runy 'bundle exec ruby script.rb', if Gemfile installed with bundler") - { - runner := New(rubyScriptWithGemContent) - require.NotNil(t, runner) - - bundleInstallCmd, err := runner.BundleInstallCommand(gemfileContent, gemfileLockContent) - require.NoError(t, err) - t.Logf("$ %s", bundleInstallCmd.PrintableCommandArgs()) - require.NoError(t, bundleInstallCmd.Run()) - - runCmd, err := runner.RunScriptCommand() - require.NoError(t, err) - - cmd := runCmd.GetCmd() - - require.Equal(t, filepath.Base(cmd.Path), "bundle") - require.Equal(t, 4, len(cmd.Args)) - require.Equal(t, "bundle", cmd.Args[0]) - require.Equal(t, "exec", cmd.Args[1]) - require.Equal(t, "ruby", cmd.Args[2]) - require.Equal(t, "script.rb", filepath.Base(cmd.Args[3])) - - t.Logf("$ %s", runCmd.PrintableCommandArgs()) - out, err := runCmd.RunAndReturnTrimmedCombinedOutput() - require.NoError(t, err, out) - require.Equal(t, `{"data":"Hi Bitrise"}`, out) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/envutil/envutil.go b/vendor/github.com/bitrise-io/go-utils/envutil/envutil.go deleted file mode 100644 index 594a90a4..00000000 --- a/vendor/github.com/bitrise-io/go-utils/envutil/envutil.go +++ /dev/null @@ -1,43 +0,0 @@ -package envutil - -import "os" - -// RevokableSetenv ... -func RevokableSetenv(envKey, envValue string) (func() error, error) { - origValue := os.Getenv(envKey) - revokeFn := func() error { - return os.Setenv(envKey, origValue) - } - - return revokeFn, os.Setenv(envKey, envValue) -} - -// SetenvForFunction ... -func SetenvForFunction(envKey, envValue string, fn func()) error { - revokeFn, err := RevokableSetenv(envKey, envValue) - if err != nil { - return err - } - - fn() - - return revokeFn() -} - -// StringFlagOrEnv - returns the value of the flag if specified, otherwise the env's value. -// Empty string counts as not specified! -func StringFlagOrEnv(flagValue *string, envKey string) string { - if flagValue != nil && *flagValue != "" { - return *flagValue - } - return os.Getenv(envKey) -} - -// GetenvWithDefault - returns the env if specified, default value otherwise -func GetenvWithDefault(envKey, defValue string) string { - retVal := os.Getenv(envKey) - if retVal == "" { - return defValue - } - return retVal -} diff --git a/vendor/github.com/bitrise-io/go-utils/envutil/envutil_test.go b/vendor/github.com/bitrise-io/go-utils/envutil/envutil_test.go deleted file mode 100644 index c155e943..00000000 --- a/vendor/github.com/bitrise-io/go-utils/envutil/envutil_test.go +++ /dev/null @@ -1,85 +0,0 @@ -package envutil - -import "testing" -import "os" -import "github.com/stretchr/testify/require" -import "github.com/bitrise-io/go-utils/pointers" - -func TestSetenvForFunction(t *testing.T) { - // set an original value - testKey := "KEY_SetenvForFunction" - require.NoError(t, os.Setenv(testKey, "orig value")) - - // quick test it - require.EqualValues(t, "orig value", os.Getenv(testKey)) - - // now apply another value, but just for the function - setEnvErr := SetenvForFunction(testKey, "temp value", func() { - require.EqualValues(t, "temp value", os.Getenv(testKey)) - }) - require.NoError(t, setEnvErr) - - // should be the original value again - require.EqualValues(t, "orig value", os.Getenv(testKey)) -} - -func TestRevokableSetenv(t *testing.T) { - // set an original value - testKey := "KEY_RevokableSetenv" - require.NoError(t, os.Setenv(testKey, "RevokableSetenv orig value")) - - // quick test it - require.EqualValues(t, "RevokableSetenv orig value", os.Getenv(testKey)) - - // revokable set - revokeFn, err := RevokableSetenv(testKey, "revokable value") - require.NoError(t, err) - - // env should now be the changed value - require.EqualValues(t, "revokable value", os.Getenv(testKey)) - - // revoke it - require.NoError(t, revokeFn()) - - // should be the original value again - require.EqualValues(t, "RevokableSetenv orig value", os.Getenv(testKey)) -} - -func TestStringFlagOrEnv(t *testing.T) { - testEnvKey := "KEY_TestStringFlagOrEnv" - - revokeFn, err := RevokableSetenv(testEnvKey, "env value") - require.NoError(t, err) - defer func() { - require.NoError(t, revokeFn()) - }() - - // quick test it - require.EqualValues(t, "env value", os.Getenv(testEnvKey)) - - // flag provided - value should be that - require.Equal(t, "flag value", StringFlagOrEnv(pointers.NewStringPtr("flag value"), testEnvKey)) - - // flag not provided - value should be the env's value - require.Equal(t, "env value", StringFlagOrEnv(nil, testEnvKey)) - - // flag provided but empty string - value should be the env's value, it's the same as a nil flag - require.Equal(t, "env value", StringFlagOrEnv(pointers.NewStringPtr(""), testEnvKey)) -} - -func TestGetenvWithDefault(t *testing.T) { - testEnvKey := "KEY_TestGetenvWithDefault" - - // no env set yet, return with default - require.Equal(t, "default value", GetenvWithDefault(testEnvKey, "default value")) - - // set the env - revokeFn, err := RevokableSetenv(testEnvKey, "env value") - require.NoError(t, err) - defer func() { - require.NoError(t, revokeFn()) - }() - - // env set - value should be the env's value - require.Equal(t, "env value", GetenvWithDefault(testEnvKey, "default value")) -} diff --git a/vendor/github.com/bitrise-io/go-utils/errorutil/errorutil_test.go b/vendor/github.com/bitrise-io/go-utils/errorutil/errorutil_test.go deleted file mode 100644 index 7ecba725..00000000 --- a/vendor/github.com/bitrise-io/go-utils/errorutil/errorutil_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package errorutil - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestIsExitStatusErrorStr(t *testing.T) { - // --- Should match --- - require.Equal(t, true, IsExitStatusErrorStr("exit status 1")) - require.Equal(t, true, IsExitStatusErrorStr("exit status 0")) - require.Equal(t, true, IsExitStatusErrorStr("exit status 2")) - require.Equal(t, true, IsExitStatusErrorStr("exit status 11")) - require.Equal(t, true, IsExitStatusErrorStr("exit status 111")) - require.Equal(t, true, IsExitStatusErrorStr("exit status 999")) - - // --- Should not match --- - require.Equal(t, false, IsExitStatusErrorStr("xit status 1")) - require.Equal(t, false, IsExitStatusErrorStr("status 1")) - require.Equal(t, false, IsExitStatusErrorStr("exit status ")) - require.Equal(t, false, IsExitStatusErrorStr("exit status")) - require.Equal(t, false, IsExitStatusErrorStr("exit status 2112")) - require.Equal(t, false, IsExitStatusErrorStr("exit status 21121")) - - // prefixed - require.Equal(t, false, IsExitStatusErrorStr(".exit status 1")) - require.Equal(t, false, IsExitStatusErrorStr(" exit status 1")) - require.Equal(t, false, IsExitStatusErrorStr("error: exit status 1")) - // postfixed - require.Equal(t, false, IsExitStatusErrorStr("exit status 1.")) - require.Equal(t, false, IsExitStatusErrorStr("exit status 1 ")) - require.Equal(t, false, IsExitStatusErrorStr("exit status 1 - something else")) - require.Equal(t, false, IsExitStatusErrorStr("exit status 1 2")) - - // other - require.Equal(t, false, IsExitStatusErrorStr("-exit status 211-")) - require.Equal(t, false, IsExitStatusErrorStr("something else: exit status 1")) -} diff --git a/vendor/github.com/bitrise-io/go-utils/freezable/freezable.go b/vendor/github.com/bitrise-io/go-utils/freezable/freezable.go deleted file mode 100644 index f00f90f5..00000000 --- a/vendor/github.com/bitrise-io/go-utils/freezable/freezable.go +++ /dev/null @@ -1,97 +0,0 @@ -package freezable - -import ( - "fmt" -) - -// -// This package implements a `freeze` function, -// similar to Ruby's `freeze` method: http://ruby-doc.org/core-2.3.0/Object.html#method-i-freeze -// Once an object is fozen you can't unfreeze it, and `Set` will return an error -// if called on a frozen object. -// You can check whether the object is frozen with the `IsFrozen` function. -// - -// --- String ---------------------------- - -// String ... -type String struct { - data *string - isFrozen bool -} - -// Set ... -func (freezableObj *String) Set(s string) error { - if freezableObj.isFrozen { - return fmt.Errorf("freezable.String: Object is already frozen. (Current value: %s) (New value was: %s)", - freezableObj.String(), s) - } - - freezableObj.data = &s - return nil -} - -// Freeze ... -func (freezableObj *String) Freeze() { - freezableObj.isFrozen = true -} - -// IsFrozen ... -func (freezableObj *String) IsFrozen() bool { - return freezableObj.isFrozen -} - -// Get ... -func (freezableObj String) Get() string { - if freezableObj.data == nil { - return "" - } - return *freezableObj.data -} - -// String ... -func (freezableObj String) String() string { - return freezableObj.Get() -} - -// --- StringSlice ---------------------------- - -// StringSlice ... -type StringSlice struct { - data *[]string - isFrozen bool -} - -// Set ... -func (freezableObj *StringSlice) Set(s []string) error { - if freezableObj.isFrozen { - return fmt.Errorf("freezable.StringSlice: Object is already frozen. (Current value: %s) (New value was: %s)", - freezableObj.Get(), s) - } - - freezableObj.data = &s - return nil -} - -// Freeze ... -func (freezableObj *StringSlice) Freeze() { - freezableObj.isFrozen = true -} - -// IsFrozen ... -func (freezableObj *StringSlice) IsFrozen() bool { - return freezableObj.isFrozen -} - -// Get ... -func (freezableObj StringSlice) Get() []string { - if freezableObj.data == nil { - return []string{} - } - return *freezableObj.data -} - -// String ... -func (freezableObj StringSlice) String() string { - return fmt.Sprintf("%s", freezableObj.Get()) -} diff --git a/vendor/github.com/bitrise-io/go-utils/freezable/freezable_test.go b/vendor/github.com/bitrise-io/go-utils/freezable/freezable_test.go deleted file mode 100644 index e7437e98..00000000 --- a/vendor/github.com/bitrise-io/go-utils/freezable/freezable_test.go +++ /dev/null @@ -1,97 +0,0 @@ -package freezable - -import ( - "fmt" - "testing" - - "github.com/stretchr/testify/require" -) - -func Test_String(t *testing.T) { - var freezableObj String - - t.Log("Empty") - { - require.Equal(t, "", freezableObj.Get()) - require.Equal(t, false, freezableObj.IsFrozen()) - } - - t.Log("Set") - { - err := freezableObj.Set("initial value") - require.NoError(t, err) - require.Equal(t, "initial value", freezableObj.Get()) - require.Equal(t, "initial value", freezableObj.String()) - require.Equal(t, false, freezableObj.IsFrozen()) - } - - t.Log("fmt - Stringer") - { - require.Equal(t, "initial value", fmt.Sprintf("%s", freezableObj)) - } - - t.Log("Re-Set (not yet frozen)") - { - err := freezableObj.Set("frozen value") - require.NoError(t, err) - require.Equal(t, "frozen value", freezableObj.Get()) - require.Equal(t, false, freezableObj.IsFrozen()) - } - - t.Log("Freeze") - { - freezableObj.Freeze() - require.Equal(t, "frozen value", freezableObj.Get()) - require.Equal(t, true, freezableObj.IsFrozen()) - } - t.Log("Try to change - should error") - { - err := freezableObj.Set("something else") - require.EqualError(t, err, "freezable.String: Object is already frozen. (Current value: frozen value) (New value was: something else)") - } -} - -func Test_StringSlice(t *testing.T) { - var freezableObj StringSlice - - t.Log("Empty") - { - require.Equal(t, []string{}, freezableObj.Get()) - require.Equal(t, false, freezableObj.IsFrozen()) - } - - t.Log("Set") - { - err := freezableObj.Set([]string{"initial value"}) - require.NoError(t, err) - require.Equal(t, []string{"initial value"}, freezableObj.Get()) - require.Equal(t, false, freezableObj.IsFrozen()) - } - - t.Log("fmt - Stringer") - { - require.Equal(t, "[initial value]", fmt.Sprintf("%s", freezableObj)) - require.Equal(t, "[initial value]", freezableObj.String()) - } - - t.Log("Re-Set (not yet frozen)") - { - err := freezableObj.Set([]string{"frozen value"}) - require.NoError(t, err) - require.Equal(t, []string{"frozen value"}, freezableObj.Get()) - require.Equal(t, false, freezableObj.IsFrozen()) - } - - t.Log("Freeze") - { - freezableObj.Freeze() - require.Equal(t, []string{"frozen value"}, freezableObj.Get()) - require.Equal(t, true, freezableObj.IsFrozen()) - } - - t.Log("Try to change - should error") - { - err := freezableObj.Set([]string{"something else"}) - require.EqualError(t, err, "freezable.StringSlice: Object is already frozen. (Current value: [frozen value]) (New value was: [something else])") - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/gows.yml b/vendor/github.com/bitrise-io/go-utils/gows.yml deleted file mode 100644 index cc85b3a3..00000000 --- a/vendor/github.com/bitrise-io/go-utils/gows.yml +++ /dev/null @@ -1 +0,0 @@ -package_name: github.com/bitrise-io/go-utils diff --git a/vendor/github.com/bitrise-io/go-utils/log/defaultlogger.go b/vendor/github.com/bitrise-io/go-utils/log/defaultlogger.go new file mode 100644 index 00000000..0d2a307f --- /dev/null +++ b/vendor/github.com/bitrise-io/go-utils/log/defaultlogger.go @@ -0,0 +1,57 @@ +package log + +// DefaultLogger ... +type DefaultLogger struct { + ts bool +} + +// NewDefaultLogger ... +func NewDefaultLogger(withTimestamp bool) DefaultLogger { + return DefaultLogger{withTimestamp} +} + +// Donef ... +func (dl DefaultLogger) Donef(format string, v ...interface{}) { + fSelect(dl.ts, TDonef, Donef)(format, v...) +} + +// Successf ... +func (dl DefaultLogger) Successf(format string, v ...interface{}) { + fSelect(dl.ts, TSuccessf, Successf)(format, v...) +} + +// Infof ... +func (dl DefaultLogger) Infof(format string, v ...interface{}) { + fSelect(dl.ts, TInfof, Infof)(format, v...) +} + +// Printf ... +func (dl DefaultLogger) Printf(format string, v ...interface{}) { + fSelect(dl.ts, TPrintf, Printf)(format, v...) +} + +// Warnf ... +func (dl DefaultLogger) Warnf(format string, v ...interface{}) { + fSelect(dl.ts, TWarnf, Warnf)(format, v...) +} + +// Errorf ... +func (dl DefaultLogger) Errorf(format string, v ...interface{}) { + fSelect(dl.ts, TErrorf, Errorf)(format, v...) +} + +// Debugf ... +func (dl DefaultLogger) Debugf(format string, v ...interface{}) { + if enableDebugLog { + fSelect(dl.ts, TDebugf, Debugf)(format, v...) + } +} + +type logfunc func(string, ...interface{}) + +func fSelect(t bool, tf logfunc, f logfunc) logfunc { + if t { + return tf + } + return f +} diff --git a/vendor/github.com/bitrise-io/go-utils/log/dummylogger.go b/vendor/github.com/bitrise-io/go-utils/log/dummylogger.go new file mode 100644 index 00000000..54b0bb97 --- /dev/null +++ b/vendor/github.com/bitrise-io/go-utils/log/dummylogger.go @@ -0,0 +1,30 @@ +package log + +// DummyLogger ... +type DummyLogger struct{} + +// NewDummyLogger ... +func NewDummyLogger() DummyLogger { + return DummyLogger{} +} + +// Donef ... +func (dl DummyLogger) Donef(format string, v ...interface{}) {} + +// Successf ... +func (dl DummyLogger) Successf(format string, v ...interface{}) {} + +// Infof ... +func (dl DummyLogger) Infof(format string, v ...interface{}) {} + +// Printf ... +func (dl DummyLogger) Printf(format string, v ...interface{}) {} + +// Debugf ... +func (dl DummyLogger) Debugf(format string, v ...interface{}) {} + +// Warnf ... +func (dl DummyLogger) Warnf(format string, v ...interface{}) {} + +// Errorf ... +func (dl DummyLogger) Errorf(format string, v ...interface{}) {} diff --git a/vendor/github.com/bitrise-io/go-utils/log/internal_logger.go b/vendor/github.com/bitrise-io/go-utils/log/internal_logger.go new file mode 100644 index 00000000..245f9954 --- /dev/null +++ b/vendor/github.com/bitrise-io/go-utils/log/internal_logger.go @@ -0,0 +1,76 @@ +package log + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "net/http" + "time" +) + +var ( + analyticsServerURL = "https://bitrise-step-analytics.herokuapp.com" + httpClient = http.Client{ + Timeout: time.Second * 5, + } +) + +// Entry represents a line in a log +type Entry struct { + LogLevel string `json:"log_level"` + Message string `json:"message"` + Data map[string]interface{} `json:"data"` +} + +// SetAnalyticsServerURL updates the the analytics server collecting the +// logs. It is intended for use during tests. Warning: current implementation +// is not thread safe, do not call the function during runtime. +func SetAnalyticsServerURL(url string) { + analyticsServerURL = url +} + +// Internal sends the log message to the configured analytics server +func rprintf(logLevel string, stepID string, tag string, data map[string]interface{}, format string, v ...interface{}) { + e := Entry{ + Message: fmt.Sprintf(format, v...), + LogLevel: logLevel, + } + + e.Data = make(map[string]interface{}) + for k, v := range data { + e.Data[k] = v + } + + if v, ok := e.Data["step_id"]; ok { + fmt.Printf("internal logger: data.step_id (%s) will be overriden with (%s) ", v, stepID) + } + if v, ok := e.Data["tag"]; ok { + fmt.Printf("internal logger: data.tag (%s) will be overriden with (%s) ", v, tag) + } + + e.Data["step_id"] = stepID + e.Data["tag"] = tag + + var b bytes.Buffer + if err := json.NewEncoder(&b).Encode(e); err != nil { + return + } + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + req, err := http.NewRequest(http.MethodPost, analyticsServerURL+"/logs", &b) + if err != nil { + // deliberately not writing into users log + return + } + req = req.WithContext(ctx) + req.Header.Add("Content-Type", "application/json") + + if _, err := httpClient.Do(req); err != nil { + // deliberately not writing into users log + return + } + +} diff --git a/vendor/github.com/bitrise-io/go-utils/log/json_logger.go b/vendor/github.com/bitrise-io/go-utils/log/json_logger.go index 43b8bfb5..31148b35 100644 --- a/vendor/github.com/bitrise-io/go-utils/log/json_logger.go +++ b/vendor/github.com/bitrise-io/go-utils/log/json_logger.go @@ -27,5 +27,7 @@ func NewDefaultJSONLoger() JSONLoger { // Print ... func (l JSONLoger) Print(f Formatable) { - fmt.Fprint(l.writer, f.JSON()) + if _, err := fmt.Fprint(l.writer, f.JSON()); err != nil { + fmt.Printf("failed to print message: %s, error: %s\n", f.JSON(), err) + } } diff --git a/vendor/github.com/bitrise-io/go-utils/log/json_logger_test.go b/vendor/github.com/bitrise-io/go-utils/log/json_logger_test.go deleted file mode 100644 index 01f277d0..00000000 --- a/vendor/github.com/bitrise-io/go-utils/log/json_logger_test.go +++ /dev/null @@ -1,41 +0,0 @@ -package log - -import ( - "bytes" - "fmt" - "testing" - - "github.com/stretchr/testify/require" -) - -type TestFormattable struct { - A string `json:"a,omitempty"` - B string `json:"b,omitempty"` -} - -// String ... -func (f TestFormattable) String() string { - return fmt.Sprintf("%s %s", f.A, f.B) -} - -// JSON ... -func (f TestFormattable) JSON() string { - return fmt.Sprintf(`{"a":"%s","b":"%s"}`, f.A, f.B) -} - -func TestJSONPrint(t *testing.T) { - - t.Log("Custom Formattable") - { - var b bytes.Buffer - logger := NewJSONLoger(&b) - - test := TestFormattable{ - A: "log", - B: "test", - } - - logger.Print(test) - require.Equal(t, `{"a":"log","b":"test"}`, b.String()) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/log/log.go b/vendor/github.com/bitrise-io/go-utils/log/log.go index bc1af2fb..1b690285 100644 --- a/vendor/github.com/bitrise-io/go-utils/log/log.go +++ b/vendor/github.com/bitrise-io/go-utils/log/log.go @@ -2,24 +2,11 @@ package log import ( "fmt" - "time" - "io" "os" - - "github.com/bitrise-io/go-utils/colorstring" + "time" ) -// -// Log configuration - -var timestampLayout = "15:04:05" - -// SetTimestampLayout ... -func SetTimestampLayout(layout string) { - timestampLayout = layout -} - var outWriter io.Writer = os.Stdout // SetOutWriter ... @@ -27,74 +14,21 @@ func SetOutWriter(writer io.Writer) { outWriter = writer } -// -// Print with color - -func printfWithColor(color colorstring.ColorfFunc, format string, v ...interface{}) { - strWithColor := color(format, v...) - fmt.Fprintln(outWriter, strWithColor) -} - -// Printf ... -func Printf(format string, v ...interface{}) { - printfWithColor(colorstring.NoColorf, format, v...) -} - -// Infof ... -func Infof(format string, v ...interface{}) { - printfWithColor(colorstring.Bluef, format, v...) -} +var enableDebugLog = false -// Donef ... -func Donef(format string, v ...interface{}) { - printfWithColor(colorstring.Greenf, format, v...) +// SetEnableDebugLog ... +func SetEnableDebugLog(enable bool) { + enableDebugLog = enable } -// Errorf ... -func Errorf(format string, v ...interface{}) { - printfWithColor(colorstring.Redf, format, v...) -} +var timestampLayout = "15:04:05" -// Warnf ... -func Warnf(format string, v ...interface{}) { - printfWithColor(colorstring.Yellowf, format, v...) +// SetTimestampLayout ... +func SetTimestampLayout(layout string) { + timestampLayout = layout } -// -// Print with color and timestamp - -func timestamp() string { +func timestampField() string { currentTime := time.Now() - return currentTime.Format(timestampLayout) -} - -func printfWithColorAndTime(color colorstring.ColorfFunc, format string, v ...interface{}) { - strWithColor := color(format, v...) - strWithColorAndTime := fmt.Sprintf("[%s] %s", timestamp(), strWithColor) - fmt.Fprintln(outWriter, strWithColorAndTime) -} - -// Printft ... -func Printft(format string, v ...interface{}) { - printfWithColorAndTime(colorstring.NoColorf, format, v...) -} - -// Infoft ... -func Infoft(format string, v ...interface{}) { - printfWithColorAndTime(colorstring.Bluef, format, v...) -} - -// Doneft ... -func Doneft(format string, v ...interface{}) { - printfWithColorAndTime(colorstring.Greenf, format, v...) -} - -// Errorft ... -func Errorft(format string, v ...interface{}) { - printfWithColorAndTime(colorstring.Redf, format, v...) -} - -// Warnft ... -func Warnft(format string, v ...interface{}) { - printfWithColorAndTime(colorstring.Yellowf, format, v...) + return fmt.Sprintf("[%s]", currentTime.Format(timestampLayout)) } diff --git a/vendor/github.com/bitrise-io/go-utils/log/log_test.go b/vendor/github.com/bitrise-io/go-utils/log/log_test.go deleted file mode 100644 index 18ffeff9..00000000 --- a/vendor/github.com/bitrise-io/go-utils/log/log_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package log - -import ( - "bytes" - "testing" - - "regexp" - - "github.com/stretchr/testify/require" -) - -func TestPrintf(t *testing.T) { - t.Log("string") - { - var b bytes.Buffer - SetOutWriter(&b) - - Printf("test") - require.Equal(t, "test\n", b.String()) - } - - t.Log("format") - { - var b bytes.Buffer - SetOutWriter(&b) - - Printf("%s", "test") - require.Equal(t, "test\n", b.String()) - } - - t.Log("complex format") - { - var b bytes.Buffer - SetOutWriter(&b) - - Printf("%s %s", "log", "test") - require.Equal(t, "log test\n", b.String()) - } -} - -func TestPrintft(t *testing.T) { - t.Log("string") - { - var b bytes.Buffer - SetOutWriter(&b) - - Printft("test") - - pattern := `\[.*\] test` - re := regexp.MustCompile(pattern) - - require.Equal(t, true, re.MatchString(b.String())) - } - - t.Log("format") - { - var b bytes.Buffer - SetOutWriter(&b) - - Printft("%s", "test") - - pattern := `\[.*\] test` - re := regexp.MustCompile(pattern) - - require.Equal(t, true, re.MatchString(b.String())) - } - - t.Log("complex format") - { - var b bytes.Buffer - SetOutWriter(&b) - - Printft("%s %s", "log", "test") - - pattern := `\[.*\] log test` - re := regexp.MustCompile(pattern) - - require.Equal(t, true, re.MatchString(b.String())) - } - -} diff --git a/vendor/github.com/bitrise-io/go-utils/log/print.go b/vendor/github.com/bitrise-io/go-utils/log/print.go new file mode 100644 index 00000000..1c817c4b --- /dev/null +++ b/vendor/github.com/bitrise-io/go-utils/log/print.go @@ -0,0 +1,115 @@ +package log + +import ( + "fmt" +) + +func printf(severity Severity, withTime bool, format string, v ...interface{}) { + message := createLogMsg(severity, withTime, format, v...) + if _, err := fmt.Fprintln(outWriter, message); err != nil { + fmt.Printf("failed to print message: %s, error: %s\n", message, err) + } +} + +func createLogMsg(severity Severity, withTime bool, format string, v ...interface{}) string { + colorFunc := severityColorFuncMap[severity] + message := colorFunc(format, v...) + if withTime { + message = prefixCurrentTime(message) + } + + return message +} + +func prefixCurrentTime(message string) string { + return fmt.Sprintf("%s %s", timestampField(), message) +} + +// Successf ... +func Successf(format string, v ...interface{}) { + printf(successSeverity, false, format, v...) +} + +// Donef ... +func Donef(format string, v ...interface{}) { + Successf(format, v...) +} + +// Infof ... +func Infof(format string, v ...interface{}) { + printf(infoSeverity, false, format, v...) +} + +// Printf ... +func Printf(format string, v ...interface{}) { + printf(normalSeverity, false, format, v...) +} + +// Debugf ... +func Debugf(format string, v ...interface{}) { + if enableDebugLog { + printf(debugSeverity, false, format, v...) + } +} + +// Warnf ... +func Warnf(format string, v ...interface{}) { + printf(warnSeverity, false, format, v...) +} + +// Errorf ... +func Errorf(format string, v ...interface{}) { + printf(errorSeverity, false, format, v...) +} + +// TSuccessf ... +func TSuccessf(format string, v ...interface{}) { + printf(successSeverity, true, format, v...) +} + +// TDonef ... +func TDonef(format string, v ...interface{}) { + TSuccessf(format, v...) +} + +// TInfof ... +func TInfof(format string, v ...interface{}) { + printf(infoSeverity, true, format, v...) +} + +// TPrintf ... +func TPrintf(format string, v ...interface{}) { + printf(normalSeverity, true, format, v...) +} + +// TDebugf ... +func TDebugf(format string, v ...interface{}) { + if enableDebugLog { + printf(debugSeverity, true, format, v...) + } +} + +// TWarnf ... +func TWarnf(format string, v ...interface{}) { + printf(warnSeverity, true, format, v...) +} + +// TErrorf ... +func TErrorf(format string, v ...interface{}) { + printf(errorSeverity, true, format, v...) +} + +// RInfof ... +func RInfof(stepID string, tag string, data map[string]interface{}, format string, v ...interface{}) { + rprintf("info", stepID, tag, data, format, v...) +} + +// RWarnf ... +func RWarnf(stepID string, tag string, data map[string]interface{}, format string, v ...interface{}) { + rprintf("warn", stepID, tag, data, format, v...) +} + +// RErrorf ... +func RErrorf(stepID string, tag string, data map[string]interface{}, format string, v ...interface{}) { + rprintf("error", stepID, tag, data, format, v...) +} diff --git a/vendor/github.com/bitrise-io/go-utils/log/raw_logger.go b/vendor/github.com/bitrise-io/go-utils/log/raw_logger.go index 82dc54ea..a6733803 100644 --- a/vendor/github.com/bitrise-io/go-utils/log/raw_logger.go +++ b/vendor/github.com/bitrise-io/go-utils/log/raw_logger.go @@ -27,5 +27,7 @@ func NewDefaultRawLogger() RawLogger { // Print ... func (l RawLogger) Print(f Formatable) { - fmt.Fprintln(l.writer, f.String()) + if _, err := fmt.Fprintln(l.writer, f.String()); err != nil { + fmt.Printf("failed to print message: %s, error: %s\n", f.String(), err) + } } diff --git a/vendor/github.com/bitrise-io/go-utils/log/raw_logger_test.go b/vendor/github.com/bitrise-io/go-utils/log/raw_logger_test.go deleted file mode 100644 index da7f9acc..00000000 --- a/vendor/github.com/bitrise-io/go-utils/log/raw_logger_test.go +++ /dev/null @@ -1,24 +0,0 @@ -package log - -import ( - "bytes" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestRawPrint(t *testing.T) { - t.Log("Custom Formattable") - { - var b bytes.Buffer - logger := NewRawLogger(&b) - - test := TestFormattable{ - A: "log", - B: "test", - } - - logger.Print(test) - require.Equal(t, "log test\n", b.String()) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/log/severity.go b/vendor/github.com/bitrise-io/go-utils/log/severity.go new file mode 100644 index 00000000..a1c46312 --- /dev/null +++ b/vendor/github.com/bitrise-io/go-utils/log/severity.go @@ -0,0 +1,35 @@ +package log + +import "github.com/bitrise-io/go-utils/colorstring" + +// Severity ... +type Severity uint8 + +const ( + errorSeverity Severity = iota + warnSeverity + normalSeverity + infoSeverity + successSeverity + debugSeverity +) + +type severityColorFunc colorstring.ColorfFunc + +var ( + successSeverityColorFunc severityColorFunc = colorstring.Greenf + infoSeverityColorFunc severityColorFunc = colorstring.Bluef + normalSeverityColorFunc severityColorFunc = colorstring.NoColorf + debugSeverityColorFunc severityColorFunc = colorstring.NoColorf + warnSeverityColorFunc severityColorFunc = colorstring.Yellowf + errorSeverityColorFunc severityColorFunc = colorstring.Redf +) + +var severityColorFuncMap = map[Severity]severityColorFunc{ + successSeverity: successSeverityColorFunc, + infoSeverity: infoSeverityColorFunc, + normalSeverity: normalSeverityColorFunc, + debugSeverity: debugSeverityColorFunc, + warnSeverity: warnSeverityColorFunc, + errorSeverity: errorSeverityColorFunc, +} diff --git a/vendor/github.com/bitrise-io/go-utils/maputil/maputil.go b/vendor/github.com/bitrise-io/go-utils/maputil/maputil.go deleted file mode 100644 index 060beff5..00000000 --- a/vendor/github.com/bitrise-io/go-utils/maputil/maputil.go +++ /dev/null @@ -1,46 +0,0 @@ -package maputil - -// KeysOfStringInterfaceMap ... -func KeysOfStringInterfaceMap(m map[string]interface{}) []string { - keys := make([]string, len(m)) - - i := 0 - for k := range m { - keys[i] = k - i++ - } - - return keys -} - -// KeysOfStringStringMap ... -func KeysOfStringStringMap(m map[string]string) []string { - keys := make([]string, len(m)) - - i := 0 - for k := range m { - keys[i] = k - i++ - } - - return keys -} - -// CloneStringStringMap ... -func CloneStringStringMap(m map[string]string) map[string]string { - cloneMap := map[string]string{} - for k, v := range m { - cloneMap[k] = v - } - return cloneMap -} - -// MergeStringStringMap - returns a new map object, -// DOES NOT modify either input map -func MergeStringStringMap(m1, m2 map[string]string) map[string]string { - mergedMap := CloneStringStringMap(m1) - for k, v := range m2 { - mergedMap[k] = v - } - return mergedMap -} diff --git a/vendor/github.com/bitrise-io/go-utils/maputil/maputil_test.go b/vendor/github.com/bitrise-io/go-utils/maputil/maputil_test.go deleted file mode 100644 index ca729917..00000000 --- a/vendor/github.com/bitrise-io/go-utils/maputil/maputil_test.go +++ /dev/null @@ -1,138 +0,0 @@ -package maputil - -import ( - "testing" - - "github.com/bitrise-io/go-utils/testutil" - "github.com/stretchr/testify/require" -) - -func TestKeysOfStringInterfaceMap(t *testing.T) { - t.Log("Empty map") - { - keys := KeysOfStringInterfaceMap(map[string]interface{}{}) - require.Equal(t, []string{}, keys) - require.Equal(t, 0, len(keys)) - } - - t.Log("Nil map") - { - keys := KeysOfStringInterfaceMap(map[string]interface{}(nil)) - require.Equal(t, []string{}, keys) - require.Equal(t, 0, len(keys)) - - var nilMap map[string]interface{} - keys = KeysOfStringInterfaceMap(nilMap) - require.Equal(t, []string{}, keys) - require.Equal(t, 0, len(keys)) - } - - t.Log("Single key") - { - keys := KeysOfStringInterfaceMap(map[string]interface{}{"a": "value"}) - require.Equal(t, 1, len(keys)) - require.Equal(t, []string{"a"}, keys) - } - - t.Log("Multiple keys") - { - keys := KeysOfStringInterfaceMap(map[string]interface{}{"a": "value 1", "b": "value 2"}) - require.Equal(t, 2, len(keys)) - testutil.EqualSlicesWithoutOrder(t, []string{"a", "b"}, keys) - } -} - -func TestKeysOfStringStringMap(t *testing.T) { - t.Log("Empty map") - { - keys := KeysOfStringStringMap(map[string]string{}) - require.Equal(t, []string{}, keys) - require.Equal(t, 0, len(keys)) - } - - t.Log("Nil map") - { - keys := KeysOfStringStringMap(map[string]string(nil)) - require.Equal(t, []string{}, keys) - require.Equal(t, 0, len(keys)) - - var nilMap map[string]string - keys = KeysOfStringStringMap(nilMap) - require.Equal(t, []string{}, keys) - require.Equal(t, 0, len(keys)) - } - - t.Log("Single key") - { - keys := KeysOfStringStringMap(map[string]string{"a": "value"}) - require.Equal(t, 1, len(keys)) - require.Equal(t, []string{"a"}, keys) - } - - t.Log("Multiple keys") - { - keys := KeysOfStringStringMap(map[string]string{"a": "value 1", "b": "value 2"}) - require.Equal(t, 2, len(keys)) - testutil.EqualSlicesWithoutOrder(t, []string{"a", "b"}, keys) - } -} - -func TestCloneStringStringMap(t *testing.T) { - t.Log("Should copy the map") - { - m1 := map[string]string{"key": "v1"} - m1Clone := CloneStringStringMap(m1) - require.Equal(t, map[string]string{"key": "v1"}, m1) - require.Equal(t, map[string]string{"key": "v1"}, m1Clone) - m1["key"] = "v2" - require.Equal(t, map[string]string{"key": "v2"}, m1) - require.Equal(t, map[string]string{"key": "v1"}, m1Clone) - } - - t.Log("Should also work for empty map") - { - m1 := map[string]string{} - m1Clone := CloneStringStringMap(m1) - require.Equal(t, map[string]string{}, m1) - require.Equal(t, map[string]string{}, m1Clone) - m1["key"] = "v2" - require.Equal(t, map[string]string{"key": "v2"}, m1) - require.Equal(t, map[string]string{}, m1Clone) - } -} - -func TestMergeStringStringMap(t *testing.T) { - t.Log("Merge maps - target should overwrite source's value, but should not modify either input map") - { - m1 := map[string]string{"key": "v1", "m1": "yes"} - m2 := map[string]string{"key": "v2", "m2": "yes"} - merged := MergeStringStringMap(m1, m2) - require.Equal(t, map[string]string{"key": "v1", "m1": "yes"}, m1) - require.Equal(t, map[string]string{"key": "v2", "m2": "yes"}, m2) - require.Equal(t, map[string]string{"key": "v2", "m1": "yes", "m2": "yes"}, merged) - } - - t.Log("Merge empty maps") - { - m1 := map[string]string{} - m2 := map[string]string{} - merged := MergeStringStringMap(m1, m2) - require.Equal(t, map[string]string{}, merged) - } - - t.Log("Merge maps where source is empty") - { - m1 := map[string]string{} - m2 := map[string]string{"key": "v2", "m2": "yes"} - merged := MergeStringStringMap(m1, m2) - require.Equal(t, map[string]string{"key": "v2", "m2": "yes"}, merged) - } - - t.Log("Merge maps where target is empty") - { - m1 := map[string]string{"key": "v1", "m1": "yes"} - m2 := map[string]string{} - merged := MergeStringStringMap(m1, m2) - require.Equal(t, map[string]string{"key": "v1", "m1": "yes"}, merged) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/parseutil/parseutil_test.go b/vendor/github.com/bitrise-io/go-utils/parseutil/parseutil_test.go deleted file mode 100644 index 36ddf15f..00000000 --- a/vendor/github.com/bitrise-io/go-utils/parseutil/parseutil_test.go +++ /dev/null @@ -1,148 +0,0 @@ -package parseutil - -import ( - "testing" - - "gopkg.in/yaml.v2" - - "github.com/stretchr/testify/require" -) - -func TestParseBool(t *testing.T) { - testUserInput := "y" - isYes, err := ParseBool("YeS") - require.Equal(t, nil, err) - require.Equal(t, true, isYes) - - testUserInput = "no" - isYes, err = ParseBool("n") - require.Equal(t, nil, err) - require.Equal(t, false, isYes) - - testUserInput = ` - yes -` - isYes, err = ParseBool(testUserInput) - require.Equal(t, nil, err) - require.Equal(t, true, isYes) -} - -func TestCastToString(t *testing.T) { - require.Equal(t, "1", CastToString(1)) - require.Equal(t, "1.1", CastToString(1.1)) - require.Equal(t, "true", CastToString(true)) - require.Equal(t, "false", CastToString("false")) -} - -func TestCastToStringPtr(t *testing.T) { - require.Equal(t, "1", *CastToStringPtr(1)) - require.Equal(t, "0.1", *CastToStringPtr(0.1)) - require.Equal(t, "true", *CastToStringPtr(true)) - require.Equal(t, "false", *CastToStringPtr(false)) - require.Equal(t, "yes", *CastToStringPtr("yes")) -} - -func TestCastToBoolPtr(t *testing.T) { - casted, ok := CastToBoolPtr(true) - require.Equal(t, true, ok) - require.Equal(t, true, *casted) - - casted, ok = CastToBoolPtr("true") - require.Equal(t, true, ok) - require.Equal(t, true, *casted) - - casted, ok = CastToBoolPtr(false) - require.Equal(t, true, ok) - require.Equal(t, false, *casted) - - casted, ok = CastToBoolPtr("false") - require.Equal(t, true, ok) - require.Equal(t, false, *casted) - - casted, ok = CastToBoolPtr("yes") - require.Equal(t, true, ok) - require.Equal(t, true, *casted) - - casted, ok = CastToBoolPtr("no") - require.Equal(t, true, ok) - require.Equal(t, false, *casted) - - casted, ok = CastToBoolPtr(1) - require.Equal(t, true, ok) - require.Equal(t, true, *casted) - - casted, ok = CastToBoolPtr("1") - require.Equal(t, true, ok) - require.Equal(t, true, *casted) - - casted, ok = CastToBoolPtr(0) - require.Equal(t, true, ok) - require.Equal(t, false, *casted) - - casted, ok = CastToBoolPtr("0") - require.Equal(t, true, ok) - require.Equal(t, false, *casted) - - casted, ok = CastToBoolPtr(0.1) - require.Equal(t, false, ok) - require.Equal(t, (*bool)(nil), casted) - - casted, ok = CastToBoolPtr("0.1") - require.Equal(t, false, ok) - require.Equal(t, (*bool)(nil), casted) - - casted, ok = CastToBoolPtr("test") - require.Equal(t, false, ok) - require.Equal(t, (*bool)(nil), casted) -} - -func TestCastToMapStringInterfacePtr(t *testing.T) { - t.Log("cast map[string]string") - { - serializedObj := `key: "value"` - var obj interface{} - require.NoError(t, yaml.Unmarshal([]byte(serializedObj), &obj)) - castedObj, ok := CastToMapStringInterfacePtr(obj.(interface{})) - require.Equal(t, true, ok) - require.Equal(t, 1, len(*castedObj)) - require.Equal(t, "value", (*castedObj)["key"]) - } - - t.Log("cast map[string]bool") - { - serializedObj := `key: true` - var obj interface{} - require.NoError(t, yaml.Unmarshal([]byte(serializedObj), &obj)) - castedObj, ok := CastToMapStringInterfacePtr(obj) - require.Equal(t, true, ok) - require.Equal(t, 1, len(*castedObj)) - require.Equal(t, true, (*castedObj)["key"]) - } - - t.Log("cast map[int]bool - FAIL") - { - serializedObj := `1: true` - var obj interface{} - require.NoError(t, yaml.Unmarshal([]byte(serializedObj), &obj)) - castedObj, ok := CastToMapStringInterfacePtr(obj) - require.Equal(t, false, ok) - require.Nil(t, castedObj) - } - - t.Log("cast string - FAIL") - { - serializedObj := `"message"` - var obj interface{} - require.NoError(t, yaml.Unmarshal([]byte(serializedObj), &obj)) - castedObj, ok := CastToMapStringInterfacePtr(obj) - require.Equal(t, false, ok) - require.Nil(t, castedObj) - } - - t.Log("cast map[string]string - FAIL") - { - castedObj, ok := CastToMapStringInterfacePtr(map[string]string{"key": "value"}) - require.Equal(t, false, ok) - require.Nil(t, castedObj) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/pathutil/pathutil.go b/vendor/github.com/bitrise-io/go-utils/pathutil/pathutil.go index 4e31d3cd..1ef74f93 100644 --- a/vendor/github.com/bitrise-io/go-utils/pathutil/pathutil.go +++ b/vendor/github.com/bitrise-io/go-utils/pathutil/pathutil.go @@ -4,6 +4,7 @@ import ( "errors" "io/ioutil" "os" + "os/user" "path/filepath" "runtime" "strings" @@ -111,12 +112,44 @@ func AbsPath(pth string) (string, error) { if pth == "" { return "", errors.New("No Path provided") } - if len(pth) >= 2 && pth[:2] == "~/" { - pth = strings.Replace(pth, "~/", "$HOME/", 1) + + pth, err := ExpandTilde(pth) + if err != nil { + return "", err } + return filepath.Abs(os.ExpandEnv(pth)) } +// ExpandTilde ... +func ExpandTilde(pth string) (string, error) { + if pth == "" { + return "", errors.New("No Path provided") + } + + if strings.HasPrefix(pth, "~") { + pth = strings.TrimPrefix(pth, "~") + + if len(pth) == 0 || strings.HasPrefix(pth, "/") { + return os.ExpandEnv("$HOME" + pth), nil + } + + splitPth := strings.Split(pth, "/") + username := splitPth[0] + + usr, err := user.Lookup(username) + if err != nil { + return "", err + } + + pathInUsrHome := strings.Join(splitPth[1:], "/") + + return filepath.Join(usr.HomeDir, pathInUsrHome), nil + } + + return pth, nil +} + // CurrentWorkingDirectoryAbsolutePath ... func CurrentWorkingDirectoryAbsolutePath() (string, error) { return filepath.Abs("./") diff --git a/vendor/github.com/bitrise-io/go-utils/pathutil/pathutil_test.go b/vendor/github.com/bitrise-io/go-utils/pathutil/pathutil_test.go deleted file mode 100644 index c48a7120..00000000 --- a/vendor/github.com/bitrise-io/go-utils/pathutil/pathutil_test.go +++ /dev/null @@ -1,164 +0,0 @@ -package pathutil - -import ( - "fmt" - "os" - "path" - "path/filepath" - "strings" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestChangeDirForFunction(t *testing.T) { - origDir, err := CurrentWorkingDirectoryAbsolutePath() - require.NoError(t, err) - - // now change dir, but just for the function - newDir := UserHomeDir() - require.NoError(t, ChangeDirForFunction(newDir, func() { - // current dir should be the changed value - dir, err := CurrentWorkingDirectoryAbsolutePath() - require.NoError(t, err) - require.Equal(t, newDir, dir) - })) - - // current dir should be the original value - dir, err := CurrentWorkingDirectoryAbsolutePath() - require.NoError(t, err) - require.Equal(t, origDir, dir) -} - -func TestRevokableChangeDir(t *testing.T) { - origDir, err := CurrentWorkingDirectoryAbsolutePath() - require.NoError(t, err) - - // revokable change dir - newDir := UserHomeDir() - revokeFn, err := RevokableChangeDir(newDir) - require.NoError(t, err) - - { - // current dir should be the changed value - dir, err := CurrentWorkingDirectoryAbsolutePath() - require.NoError(t, err) - require.Equal(t, newDir, dir) - } - - { - // revoke it - require.NoError(t, revokeFn()) - - // current dir should be the original value - dir, err := CurrentWorkingDirectoryAbsolutePath() - require.NoError(t, err) - require.Equal(t, origDir, dir) - } - -} - -func TestEnsureDirExist(t *testing.T) { - // testDir not exist - - currDirPath, err := filepath.Abs(".") - require.Equal(t, nil, err) - - currentTime := time.Now() - currentTimeStamp := currentTime.Format("20060102150405") - testDir := path.Join(currDirPath, currentTimeStamp+"TestEnsurePathExist") - exist, err := IsDirExists(testDir) - require.Equal(t, nil, err) - require.Equal(t, false, exist) - defer func() { - require.Equal(t, nil, os.Remove(testDir)) - }() - - require.Equal(t, nil, EnsureDirExist(testDir)) - exist, err = IsDirExists(testDir) - require.Equal(t, nil, err) - require.Equal(t, true, exist) - - // testDir exist - - require.Equal(t, nil, EnsureDirExist(testDir)) - exist, err = IsDirExists(testDir) - require.Equal(t, nil, err) - require.Equal(t, true, exist) -} - -func TestIsRelativePath(t *testing.T) { - // should return true if relative path, false if absolute path - - require.Equal(t, true, IsRelativePath("./rel")) - require.Equal(t, false, IsRelativePath("/abs")) - require.Equal(t, false, IsRelativePath("$THISENVDOESNTEXIST/some")) - require.Equal(t, true, IsRelativePath("rel")) -} - -func TestIsPathExists(t *testing.T) { - // should return false if path doesn't exist - - exists, err := IsPathExists("this/should/not/exist") - require.Equal(t, nil, err) - require.Equal(t, false, exists) - - exists, err = IsPathExists(".") - require.Equal(t, nil, err) - require.Equal(t, true, exists) - - exists, err = IsPathExists("") - require.NotEqual(t, nil, err) - require.Equal(t, false, exists) -} - -func TestAbsPath(t *testing.T) { - // should expand path - - currDirPath, err := filepath.Abs(".") - require.Equal(t, nil, err) - require.NotEqual(t, "", currDirPath) - require.NotEqual(t, ".", currDirPath) - - homePathEnv := "/path/home/test-user" - require.Equal(t, nil, os.Setenv("HOME", homePathEnv)) - - testFileRelPathFromHome := "some/file.ext" - absPathToTestFile := fmt.Sprintf("%s/%s", homePathEnv, testFileRelPathFromHome) - - expandedPath, err := AbsPath("") - require.NotEqual(t, nil, err) - require.Equal(t, "", expandedPath) - - expandedPath, err = AbsPath(".") - require.Equal(t, nil, err) - require.Equal(t, currDirPath, expandedPath) - - expandedPath, err = AbsPath(fmt.Sprintf("$HOME/%s", testFileRelPathFromHome)) - require.Equal(t, nil, err) - require.Equal(t, absPathToTestFile, expandedPath) - - expandedPath, err = AbsPath(fmt.Sprintf("~/%s", testFileRelPathFromHome)) - require.Equal(t, nil, err) - require.Equal(t, absPathToTestFile, expandedPath) -} - -func TestUserHomeDir(t *testing.T) { - // should return the path of the users home directory - - require.NotEqual(t, "", UserHomeDir()) -} - -func TestNormalizedOSTempDirPath(t *testing.T) { - // returned temp dir path should not have a / at it's end - - tmpPth, err := NormalizedOSTempDirPath("some-test") - require.Equal(t, nil, err) - require.Equal(t, false, strings.HasSuffix(tmpPth, "/")) - - // should work if empty prefix is defined - tmpPth, err = NormalizedOSTempDirPath("") - require.Equal(t, nil, err) - require.Equal(t, false, strings.HasSuffix(tmpPth, "/")) -} diff --git a/vendor/github.com/bitrise-io/go-utils/pkcs12/bmp-string_test.go b/vendor/github.com/bitrise-io/go-utils/pkcs12/bmp-string_test.go deleted file mode 100755 index 7fca55f4..00000000 --- a/vendor/github.com/bitrise-io/go-utils/pkcs12/bmp-string_test.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkcs12 - -import ( - "bytes" - "encoding/hex" - "testing" -) - -var bmpStringTests = []struct { - in string - expectedHex string - shouldFail bool -}{ - {"", "0000", false}, - // Example from https://tools.ietf.org/html/rfc7292#appendix-B. - {"Beavis", "0042006500610076006900730000", false}, - // Some characters from the "Letterlike Symbols Unicode block". - {"\u2115 - Double-struck N", "21150020002d00200044006f00750062006c0065002d00730074007200750063006b0020004e0000", false}, - // any character outside the BMP should trigger an error. - {"\U0001f000 East wind (Mahjong)", "", true}, -} - -func TestBMPString(t *testing.T) { - for i, test := range bmpStringTests { - expected, err := hex.DecodeString(test.expectedHex) - if err != nil { - t.Fatalf("#%d: failed to decode expectation", i) - } - - out, err := bmpString(test.in) - if err == nil && test.shouldFail { - t.Errorf("#%d: expected to fail, but produced %x", i, out) - continue - } - - if err != nil && !test.shouldFail { - t.Errorf("#%d: failed unexpectedly: %s", i, err) - continue - } - - if !test.shouldFail { - if !bytes.Equal(out, expected) { - t.Errorf("#%d: expected %s, got %x", i, test.expectedHex, out) - continue - } - - roundTrip, err := decodeBMPString(out) - if err != nil { - t.Errorf("#%d: decoding output gave an error: %s", i, err) - continue - } - - if roundTrip != test.in { - t.Errorf("#%d: decoding output resulted in %q, but it should have been %q", i, roundTrip, test.in) - continue - } - } - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/pkcs12/crypto_test.go b/vendor/github.com/bitrise-io/go-utils/pkcs12/crypto_test.go deleted file mode 100755 index eb4dae8f..00000000 --- a/vendor/github.com/bitrise-io/go-utils/pkcs12/crypto_test.go +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkcs12 - -import ( - "bytes" - "crypto/x509/pkix" - "encoding/asn1" - "testing" -) - -var sha1WithTripleDES = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 3}) - -func TestPbDecrypterFor(t *testing.T) { - params, _ := asn1.Marshal(pbeParams{ - Salt: []byte{1, 2, 3, 4, 5, 6, 7, 8}, - Iterations: 2048, - }) - alg := pkix.AlgorithmIdentifier{ - Algorithm: asn1.ObjectIdentifier([]int{1, 2, 3}), - Parameters: asn1.RawValue{ - FullBytes: params, - }, - } - - pass, _ := bmpString("Sesame open") - - _, _, err := pbDecrypterFor(alg, pass) - if _, ok := err.(NotImplementedError); !ok { - t.Errorf("expected not implemented error, got: %T %s", err, err) - } - - alg.Algorithm = sha1WithTripleDES - cbc, blockSize, err := pbDecrypterFor(alg, pass) - if err != nil { - t.Errorf("unexpected error from pbDecrypterFor %v", err) - } - if blockSize != 8 { - t.Errorf("unexpected block size %d, wanted 8", blockSize) - } - - plaintext := []byte{1, 2, 3, 4, 5, 6, 7, 8} - expectedCiphertext := []byte{185, 73, 135, 249, 137, 1, 122, 247} - ciphertext := make([]byte, len(plaintext)) - cbc.CryptBlocks(ciphertext, plaintext) - - if bytes.Compare(ciphertext, expectedCiphertext) != 0 { - t.Errorf("bad ciphertext, got %x but wanted %x", ciphertext, expectedCiphertext) - } -} - -var pbDecryptTests = []struct { - in []byte - expected []byte - expectedError error -}{ - { - []byte("\x33\x73\xf3\x9f\xda\x49\xae\xfc\xa0\x9a\xdf\x5a\x58\xa0\xea\x46"), // 7 padding bytes - []byte("A secret!"), - nil, - }, - { - []byte("\x33\x73\xf3\x9f\xda\x49\xae\xfc\x96\x24\x2f\x71\x7e\x32\x3f\xe7"), // 8 padding bytes - []byte("A secret"), - nil, - }, - { - []byte("\x35\x0c\xc0\x8d\xab\xa9\x5d\x30\x7f\x9a\xec\x6a\xd8\x9b\x9c\xd9"), // 9 padding bytes, incorrect - nil, - ErrDecryption, - }, - { - []byte("\xb2\xf9\x6e\x06\x60\xae\x20\xcf\x08\xa0\x7b\xd9\x6b\x20\xef\x41"), // incorrect padding bytes: [ ... 0x04 0x02 ] - nil, - ErrDecryption, - }, -} - -func TestPbDecrypt(t *testing.T) { - for i, test := range pbDecryptTests { - decryptable := testDecryptable{ - data: test.in, - algorithm: pkix.AlgorithmIdentifier{ - Algorithm: sha1WithTripleDES, - Parameters: pbeParams{ - Salt: []byte("\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8"), - Iterations: 4096, - }.RawASN1(), - }, - } - password, _ := bmpString("sesame") - - plaintext, err := pbDecrypt(decryptable, password) - if err != test.expectedError { - t.Errorf("#%d: got error %q, but wanted %q", i, err, test.expectedError) - continue - } - - if !bytes.Equal(plaintext, test.expected) { - t.Errorf("#%d: got %x, but wanted %x", i, plaintext, test.expected) - } - } -} - -type testDecryptable struct { - data []byte - algorithm pkix.AlgorithmIdentifier -} - -func (d testDecryptable) Algorithm() pkix.AlgorithmIdentifier { return d.algorithm } -func (d testDecryptable) Data() []byte { return d.data } - -func (params pbeParams) RawASN1() (raw asn1.RawValue) { - asn1Bytes, err := asn1.Marshal(params) - if err != nil { - panic(err) - } - _, err = asn1.Unmarshal(asn1Bytes, &raw) - if err != nil { - panic(err) - } - return -} diff --git a/vendor/github.com/bitrise-io/go-utils/pkcs12/internal/rc2/bench_test.go b/vendor/github.com/bitrise-io/go-utils/pkcs12/internal/rc2/bench_test.go deleted file mode 100755 index 3347f338..00000000 --- a/vendor/github.com/bitrise-io/go-utils/pkcs12/internal/rc2/bench_test.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package rc2 - -import ( - "testing" -) - -func BenchmarkEncrypt(b *testing.B) { - r, _ := New([]byte{0, 0, 0, 0, 0, 0, 0, 0}, 64) - b.ResetTimer() - var src [8]byte - for i := 0; i < b.N; i++ { - r.Encrypt(src[:], src[:]) - } -} - -func BenchmarkDecrypt(b *testing.B) { - r, _ := New([]byte{0, 0, 0, 0, 0, 0, 0, 0}, 64) - b.ResetTimer() - var src [8]byte - for i := 0; i < b.N; i++ { - r.Decrypt(src[:], src[:]) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/pkcs12/internal/rc2/rc2_test.go b/vendor/github.com/bitrise-io/go-utils/pkcs12/internal/rc2/rc2_test.go deleted file mode 100755 index 8a49dfaf..00000000 --- a/vendor/github.com/bitrise-io/go-utils/pkcs12/internal/rc2/rc2_test.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package rc2 - -import ( - "bytes" - "encoding/hex" - "testing" -) - -func TestEncryptDecrypt(t *testing.T) { - - // TODO(dgryski): add the rest of the test vectors from the RFC - var tests = []struct { - key string - plain string - cipher string - t1 int - }{ - { - "0000000000000000", - "0000000000000000", - "ebb773f993278eff", - 63, - }, - { - "ffffffffffffffff", - "ffffffffffffffff", - "278b27e42e2f0d49", - 64, - }, - { - "3000000000000000", - "1000000000000001", - "30649edf9be7d2c2", - 64, - }, - { - "88", - "0000000000000000", - "61a8a244adacccf0", - 64, - }, - { - "88bca90e90875a", - "0000000000000000", - "6ccf4308974c267f", - 64, - }, - { - "88bca90e90875a7f0f79c384627bafb2", - "0000000000000000", - "1a807d272bbe5db1", - 64, - }, - { - "88bca90e90875a7f0f79c384627bafb2", - "0000000000000000", - "2269552ab0f85ca6", - 128, - }, - { - "88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e", - "0000000000000000", - "5b78d3a43dfff1f1", - 129, - }, - } - - for _, tt := range tests { - k, _ := hex.DecodeString(tt.key) - p, _ := hex.DecodeString(tt.plain) - c, _ := hex.DecodeString(tt.cipher) - - b, _ := New(k, tt.t1) - - var dst [8]byte - - b.Encrypt(dst[:], p) - - if !bytes.Equal(dst[:], c) { - t.Errorf("encrypt failed: got % 2x wanted % 2x\n", dst, c) - } - - b.Decrypt(dst[:], c) - - if !bytes.Equal(dst[:], p) { - t.Errorf("decrypt failed: got % 2x wanted % 2x\n", dst, p) - } - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/pkcs12/mac_test.go b/vendor/github.com/bitrise-io/go-utils/pkcs12/mac_test.go deleted file mode 100755 index 1ed4ff21..00000000 --- a/vendor/github.com/bitrise-io/go-utils/pkcs12/mac_test.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkcs12 - -import ( - "encoding/asn1" - "testing" -) - -func TestVerifyMac(t *testing.T) { - td := macData{ - Mac: digestInfo{ - Digest: []byte{0x18, 0x20, 0x3d, 0xff, 0x1e, 0x16, 0xf4, 0x92, 0xf2, 0xaf, 0xc8, 0x91, 0xa9, 0xba, 0xd6, 0xca, 0x9d, 0xee, 0x51, 0x93}, - }, - MacSalt: []byte{1, 2, 3, 4, 5, 6, 7, 8}, - Iterations: 2048, - } - - message := []byte{11, 12, 13, 14, 15} - password, _ := bmpString("") - - td.Mac.Algorithm.Algorithm = asn1.ObjectIdentifier([]int{1, 2, 3}) - err := verifyMac(&td, message, password) - if _, ok := err.(NotImplementedError); !ok { - t.Errorf("err: %v", err) - } - - td.Mac.Algorithm.Algorithm = asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}) - err = verifyMac(&td, message, password) - if err != ErrIncorrectPassword { - t.Errorf("Expected incorrect password, got err: %v", err) - } - - password, _ = bmpString("Sesame open") - err = verifyMac(&td, message, password) - if err != nil { - t.Errorf("err: %v", err) - } - -} diff --git a/vendor/github.com/bitrise-io/go-utils/pkcs12/pbkdf_test.go b/vendor/github.com/bitrise-io/go-utils/pkcs12/pbkdf_test.go deleted file mode 100755 index 262037d7..00000000 --- a/vendor/github.com/bitrise-io/go-utils/pkcs12/pbkdf_test.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkcs12 - -import ( - "bytes" - "testing" -) - -func TestThatPBKDFWorksCorrectlyForLongKeys(t *testing.T) { - cipherInfo := shaWithTripleDESCBC{} - - salt := []byte("\xff\xff\xff\xff\xff\xff\xff\xff") - password, _ := bmpString("sesame") - key := cipherInfo.deriveKey(salt, password, 2048) - - if expected := []byte("\x7c\xd9\xfd\x3e\x2b\x3b\xe7\x69\x1a\x44\xe3\xbe\xf0\xf9\xea\x0f\xb9\xb8\x97\xd4\xe3\x25\xd9\xd1"); bytes.Compare(key, expected) != 0 { - t.Fatalf("expected key '%x', but found '%x'", expected, key) - } -} - -func TestThatPBKDFHandlesLeadingZeros(t *testing.T) { - // This test triggers a case where I_j (in step 6C) ends up with leading zero - // byte, meaning that len(Ijb) < v (leading zeros get stripped by big.Int). - // This was previously causing bug whereby certain inputs would break the - // derivation and produce the wrong output. - key := pbkdf(sha1Sum, 20, 64, []byte("\xf3\x7e\x05\xb5\x18\x32\x4b\x4b"), []byte("\x00\x00"), 2048, 1, 24) - expected := []byte("\x00\xf7\x59\xff\x47\xd1\x4d\xd0\x36\x65\xd5\x94\x3c\xb3\xc4\xa3\x9a\x25\x55\xc0\x2a\xed\x66\xe1") - if bytes.Compare(key, expected) != 0 { - t.Fatalf("expected key '%x', but found '%x'", expected, key) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/pkcs12/pkcs12_test.go b/vendor/github.com/bitrise-io/go-utils/pkcs12/pkcs12_test.go deleted file mode 100755 index 14dd2a6c..00000000 --- a/vendor/github.com/bitrise-io/go-utils/pkcs12/pkcs12_test.go +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package pkcs12 - -import ( - "crypto/rsa" - "crypto/tls" - "encoding/base64" - "encoding/pem" - "testing" -) - -func TestPfx(t *testing.T) { - for commonName, base64P12 := range testdata { - p12, _ := base64.StdEncoding.DecodeString(base64P12) - - priv, cert, err := Decode(p12, "") - if err != nil { - t.Fatal(err) - } - - if err := priv.(*rsa.PrivateKey).Validate(); err != nil { - t.Errorf("error while validating private key: %v", err) - } - - if cert.Subject.CommonName != commonName { - t.Errorf("expected common name to be %q, but found %q", commonName, cert.Subject.CommonName) - } - } -} - -func TestPEM(t *testing.T) { - for commonName, base64P12 := range testdata { - p12, _ := base64.StdEncoding.DecodeString(base64P12) - - blocks, err := ToPEM(p12, "") - if err != nil { - t.Fatalf("error while converting to PEM: %s", err) - } - - var pemData []byte - for _, b := range blocks { - pemData = append(pemData, pem.EncodeToMemory(b)...) - } - - cert, err := tls.X509KeyPair(pemData, pemData) - if err != nil { - t.Errorf("err while converting to key pair: %v", err) - } - config := tls.Config{ - Certificates: []tls.Certificate{cert}, - } - config.BuildNameToCertificate() - - if _, exists := config.NameToCertificate[commonName]; !exists { - t.Errorf("did not find our cert in PEM?: %v", config.NameToCertificate) - } - } -} - -func ExampleToPEM() { - p12, _ := base64.StdEncoding.DecodeString(`MIIJzgIBAzCCCZQGCS ... CA+gwggPk==`) - - blocks, err := ToPEM(p12, "password") - if err != nil { - panic(err) - } - - var pemData []byte - for _, b := range blocks { - pemData = append(pemData, pem.EncodeToMemory(b)...) - } - - // then use PEM data for tls to construct tls certificate: - cert, err := tls.X509KeyPair(pemData, pemData) - if err != nil { - panic(err) - } - - config := &tls.Config{ - Certificates: []tls.Certificate{cert}, - } - - _ = config -} - -var testdata = map[string]string{ - // 'null' password test case - "Windows Azure Tools": `MIIKDAIBAzCCCcwGCSqGSIb3DQEHAaCCCb0Eggm5MIIJtTCCBe4GCSqGSIb3DQEHAaCCBd8EggXbMIIF1zCCBdMGCyqGSIb3DQEMCgECoIIE7jCCBOowHAYKKoZIhvcNAQwBAzAOBAhStUNnlTGV+gICB9AEggTIJ81JIossF6boFWpPtkiQRPtI6DW6e9QD4/WvHAVrM2bKdpMzSMsCML5NyuddANTKHBVq00Jc9keqGNAqJPKkjhSUebzQFyhe0E1oI9T4zY5UKr/I8JclOeccH4QQnsySzYUG2SnniXnQ+JrG3juetli7EKth9h6jLc6xbubPadY5HMB3wL/eG/kJymiXwU2KQ9Mgd4X6jbcV+NNCE/8jbZHvSTCPeYTJIjxfeX61Sj5kFKUCzERbsnpyevhY3X0eYtEDezZQarvGmXtMMdzf8HJHkWRdk9VLDLgjk8uiJif/+X4FohZ37ig0CpgC2+dP4DGugaZZ51hb8tN9GeCKIsrmWogMXDIVd0OACBp/EjJVmFB6y0kUCXxUE0TZt0XA1tjAGJcjDUpBvTntZjPsnH/4ZySy+s2d9OOhJ6pzRQBRm360TzkFdSwk9DLiLdGfv4pwMMu/vNGBlqjP/1sQtj+jprJiD1sDbCl4AdQZVoMBQHadF2uSD4/o17XG/Ci0r2h6Htc2yvZMAbEY4zMjjIn2a+vqIxD6onexaek1R3zbkS9j19D6EN9EWn8xgz80YRCyW65znZk8xaIhhvlU/mg7sTxeyuqroBZNcq6uDaQTehDpyH7bY2l4zWRpoj10a6JfH2q5shYz8Y6UZC/kOTfuGqbZDNZWro/9pYquvNNW0M847E5t9bsf9VkAAMHRGBbWoVoU9VpI0UnoXSfvpOo+aXa2DSq5sHHUTVY7A9eov3z5IqT+pligx11xcs+YhDWcU8di3BTJisohKvv5Y8WSkm/rloiZd4ig269k0jTRk1olP/vCksPli4wKG2wdsd5o42nX1yL7mFfXocOANZbB+5qMkiwdyoQSk+Vq+C8nAZx2bbKhUq2MbrORGMzOe0Hh0x2a0PeObycN1Bpyv7Mp3ZI9h5hBnONKCnqMhtyQHUj/nNvbJUnDVYNfoOEqDiEqqEwB7YqWzAKz8KW0OIqdlM8uiQ4JqZZlFllnWJUfaiDrdFM3lYSnFQBkzeVlts6GpDOOBjCYd7dcCNS6kq6pZC6p6HN60Twu0JnurZD6RT7rrPkIGE8vAenFt4iGe/yF52fahCSY8Ws4K0UTwN7bAS+4xRHVCWvE8sMRZsRCHizb5laYsVrPZJhE6+hux6OBb6w8kwPYXc+ud5v6UxawUWgt6uPwl8mlAtU9Z7Miw4Nn/wtBkiLL/ke1UI1gqJtcQXgHxx6mzsjh41+nAgTvdbsSEyU6vfOmxGj3Rwc1eOrIhJUqn5YjOWfzzsz/D5DzWKmwXIwdspt1p+u+kol1N3f2wT9fKPnd/RGCb4g/1hc3Aju4DQYgGY782l89CEEdalpQ/35bQczMFk6Fje12HykakWEXd/bGm9Unh82gH84USiRpeOfQvBDYoqEyrY3zkFZzBjhDqa+jEcAj41tcGx47oSfDq3iVYCdL7HSIjtnyEktVXd7mISZLoMt20JACFcMw+mrbjlug+eU7o2GR7T+LwtOp/p4LZqyLa7oQJDwde1BNZtm3TCK2P1mW94QDL0nDUps5KLtr1DaZXEkRbjSJub2ZE9WqDHyU3KA8G84Tq/rN1IoNu/if45jacyPje1Npj9IftUZSP22nV7HMwZtwQ4P4MYHRMBMGCSqGSIb3DQEJFTEGBAQBAAAAMFsGCSqGSIb3DQEJFDFOHkwAewBCADQAQQA0AEYARQBCADAALQBBADEAOABBAC0ANAA0AEIAQgAtAEIANQBGADIALQA0ADkAMQBFAEYAMQA1ADIAQgBBADEANgB9MF0GCSsGAQQBgjcRATFQHk4ATQBpAGMAcgBvAHMAbwBmAHQAIABTAG8AZgB0AHcAYQByAGUAIABLAGUAeQAgAFMAdABvAHIAYQBnAGUAIABQAHIAbwB2AGkAZABlAHIwggO/BgkqhkiG9w0BBwagggOwMIIDrAIBADCCA6UGCSqGSIb3DQEHATAcBgoqhkiG9w0BDAEGMA4ECEBk5ZAYpu0WAgIH0ICCA3hik4mQFGpw9Ha8TQPtk+j2jwWdxfF0+sTk6S8PTsEfIhB7wPltjiCK92Uv2tCBQnodBUmatIfkpnRDEySmgmdglmOCzj204lWAMRs94PoALGn3JVBXbO1vIDCbAPOZ7Z0Hd0/1t2hmk8v3//QJGUg+qr59/4y/MuVfIg4qfkPcC2QSvYWcK3oTf6SFi5rv9B1IOWFgN5D0+C+x/9Lb/myPYX+rbOHrwtJ4W1fWKoz9g7wwmGFA9IJ2DYGuH8ifVFbDFT1Vcgsvs8arSX7oBsJVW0qrP7XkuDRe3EqCmKW7rBEwYrFznhxZcRDEpMwbFoSvgSIZ4XhFY9VKYglT+JpNH5iDceYEBOQL4vBLpxNUk3l5jKaBNxVa14AIBxq18bVHJ+STInhLhad4u10v/Xbx7wIL3f9DX1yLAkPrpBYbNHS2/ew6H/ySDJnoIDxkw2zZ4qJ+qUJZ1S0lbZVG+VT0OP5uF6tyOSpbMlcGkdl3z254n6MlCrTifcwkzscysDsgKXaYQw06rzrPW6RDub+t+hXzGny799fS9jhQMLDmOggaQ7+LA4oEZsfT89HLMWxJYDqjo3gIfjciV2mV54R684qLDS+AO09U49e6yEbwGlq8lpmO/pbXCbpGbB1b3EomcQbxdWxW2WEkkEd/VBn81K4M3obmywwXJkw+tPXDXfBmzzaqqCR+onMQ5ME1nMkY8ybnfoCc1bDIupjVWsEL2Wvq752RgI6KqzVNr1ew1IdqV5AWN2fOfek+0vi3Jd9FHF3hx8JMwjJL9dZsETV5kHtYJtE7wJ23J68BnCt2eI0GEuwXcCf5EdSKN/xXCTlIokc4Qk/gzRdIZsvcEJ6B1lGovKG54X4IohikqTjiepjbsMWj38yxDmK3mtENZ9ci8FPfbbvIEcOCZIinuY3qFUlRSbx7VUerEoV1IP3clUwexVQo4lHFee2jd7ocWsdSqSapW7OWUupBtDzRkqVhE7tGria+i1W2d6YLlJ21QTjyapWJehAMO637OdbJCCzDs1cXbodRRE7bsP492ocJy8OX66rKdhYbg8srSFNKdb3pF3UDNbN9jhI/t8iagRhNBhlQtTr1me2E/c86Q18qcRXl4bcXTt6acgCeffK6Y26LcVlrgjlD33AEYRRUeyC+rpxbT0aMjdFderlndKRIyG23mSp0HaUwNzAfMAcGBSsOAwIaBBRlviCbIyRrhIysg2dc/KbLFTc2vQQUg4rfwHMM4IKYRD/fsd1x6dda+wQ=`, - // empty string password test case - "testing@example.com": `MIIJzgIBAzCCCZQGCSqGSIb3DQEHAaCCCYUEggmBMIIJfTCCA/cGCSqGSIb3DQEHBqCCA+gwggPk -AgEAMIID3QYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIIszfRGqcmPcCAggAgIIDsOZ9Eg1L -s5Wx8JhYoV3HAL4aRnkAWvTYB5NISZOgSgIQTssmt/3A7134dibTmaT/93LikkL3cTKLnQzJ4wDf -YZ1bprpVJvUqz+HFT79m27bP9zYXFrvxWBJbxjYKTSjQMgz+h8LAEpXXGajCmxMJ1oCOtdXkhhzc -LdZN6SAYgtmtyFnCdMEDskSggGuLb3fw84QEJ/Sj6FAULXunW/CPaS7Ce0TMsKmNU/jfFWj3yXXw -ro0kwjKiVLpVFlnBlHo2OoVU7hmkm59YpGhLgS7nxLD3n7nBroQ0ID1+8R01NnV9XLGoGzxMm1te -6UyTCkr5mj+kEQ8EP1Ys7g/TC411uhVWySMt/rcpkx7Vz1r9kYEAzJpONAfr6cuEVkPKrxpq4Fh0 -2fzlKBky0i/hrfIEUmngh+ERHUb/Mtv/fkv1j5w9suESbhsMLLiCXAlsP1UWMX+3bNizi3WVMEts -FM2k9byn+p8IUD/A8ULlE4kEaWeoc+2idkCNQkLGuIdGUXUFVm58se0auUkVRoRJx8x4CkMesT8j -b1H831W66YRWoEwwDQp2kK1lA2vQXxdVHWlFevMNxJeromLzj3ayiaFrfByeUXhR2S+Hpm+c0yNR -4UVU9WED2kacsZcpRm9nlEa5sr28mri5JdBrNa/K02OOhvKCxr5ZGmbOVzUQKla2z4w+Ku9k8POm -dfDNU/fGx1b5hcFWtghXe3msWVsSJrQihnN6q1ughzNiYZlJUGcHdZDRtiWwCFI0bR8h/Dmg9uO9 -4rawQQrjIRT7B8yF3UbkZyAqs8Ppb1TsMeNPHh1rxEfGVQknh/48ouJYsmtbnzugTUt3mJCXXiL+ -XcPMV6bBVAUu4aaVKSmg9+yJtY4/VKv10iw88ktv29fViIdBe3t6l/oPuvQgbQ8dqf4T8w0l/uKZ -9lS1Na9jfT1vCoS7F5TRi+tmyj1vL5kr/amEIW6xKEP6oeAMvCMtbPAzVEj38zdJ1R22FfuIBxkh -f0Zl7pdVbmzRxl/SBx9iIBJSqAvcXItiT0FIj8HxQ+0iZKqMQMiBuNWJf5pYOLWGrIyntCWwHuaQ -wrx0sTGuEL9YXLEAsBDrsvzLkx/56E4INGZFrH8G7HBdW6iGqb22IMI4GHltYSyBRKbB0gadYTyv -abPEoqww8o7/85aPSzOTJ/53ozD438Q+d0u9SyDuOb60SzCD/zPuCEd78YgtXJwBYTuUNRT27FaM -3LGMX8Hz+6yPNRnmnA2XKPn7dx/IlaqAjIs8MIIFfgYJKoZIhvcNAQcBoIIFbwSCBWswggVnMIIF -YwYLKoZIhvcNAQwKAQKgggTuMIIE6jAcBgoqhkiG9w0BDAEDMA4ECJr0cClYqOlcAgIIAASCBMhe -OQSiP2s0/46ONXcNeVAkz2ksW3u/+qorhSiskGZ0b3dFa1hhgBU2Q7JVIkc4Hf7OXaT1eVQ8oqND -uhqsNz83/kqYo70+LS8Hocj49jFgWAKrf/yQkdyP1daHa2yzlEw4mkpqOfnIORQHvYCa8nEApspZ -wVu8y6WVuLHKU67mel7db2xwstQp7PRuSAYqGjTfAylElog8ASdaqqYbYIrCXucF8iF9oVgmb/Qo -xrXshJ9aSLO4MuXlTPELmWgj07AXKSb90FKNihE+y0bWb9LPVFY1Sly3AX9PfrtkSXIZwqW3phpv -MxGxQl/R6mr1z+hlTfY9Wdpb5vlKXPKA0L0Rt8d2pOesylFi6esJoS01QgP1kJILjbrV731kvDc0 -Jsd+Oxv4BMwA7ClG8w1EAOInc/GrV1MWFGw/HeEqj3CZ/l/0jv9bwkbVeVCiIhoL6P6lVx9pXq4t -KZ0uKg/tk5TVJmG2vLcMLvezD0Yk3G2ZOMrywtmskrwoF7oAUpO9e87szoH6fEvUZlkDkPVW1NV4 -cZk3DBSQiuA3VOOg8qbo/tx/EE3H59P0axZWno2GSB0wFPWd1aj+b//tJEJHaaNR6qPRj4IWj9ru -Qbc8eRAcVWleHg8uAehSvUXlFpyMQREyrnpvMGddpiTC8N4UMrrBRhV7+UbCOWhxPCbItnInBqgl -1JpSZIP7iUtsIMdu3fEC2cdbXMTRul+4rdzUR7F9OaezV3jjvcAbDvgbK1CpyC+MJ1Mxm/iTgk9V -iUArydhlR8OniN84GyGYoYCW9O/KUwb6ASmeFOu/msx8x6kAsSQHIkKqMKv0TUR3kZnkxUvdpBGP -KTl4YCTvNGX4dYALBqrAETRDhua2KVBD/kEttDHwBNVbN2xi81+Mc7ml461aADfk0c66R/m2sjHB -2tN9+wG12OIWFQjL6wF/UfJMYamxx2zOOExiId29Opt57uYiNVLOO4ourPewHPeH0u8Gz35aero7 -lkt7cZAe1Q0038JUuE/QGlnK4lESK9UkSIQAjSaAlTsrcfwtQxB2EjoOoLhwH5mvxUEmcNGNnXUc -9xj3M5BD3zBz3Ft7G3YMMDwB1+zC2l+0UG0MGVjMVaeoy32VVNvxgX7jk22OXG1iaOB+PY9kdk+O -X+52BGSf/rD6X0EnqY7XuRPkMGgjtpZeAYxRQnFtCZgDY4wYheuxqSSpdF49yNczSPLkgB3CeCfS -+9NTKN7aC6hBbmW/8yYh6OvSiCEwY0lFS/T+7iaVxr1loE4zI1y/FFp4Pe1qfLlLttVlkygga2UU -SCunTQ8UB/M5IXWKkhMOO11dP4niWwb39Y7pCWpau7mwbXOKfRPX96cgHnQJK5uG+BesDD1oYnX0 -6frN7FOnTSHKruRIwuI8KnOQ/I+owmyz71wiv5LMQt+yM47UrEjB/EZa5X8dpEwOZvkdqL7utcyo -l0XH5kWMXdW856LL/FYftAqJIDAmtX1TXF/rbP6mPyN/IlDC0gjP84Uzd/a2UyTIWr+wk49Ek3vQ -/uDamq6QrwAxVmNh5Tset5Vhpc1e1kb7mRMZIzxSP8JcTuYd45oFKi98I8YjvueHVZce1g7OudQP -SbFQoJvdT46iBg1TTatlltpOiH2mFaxWVS0xYjAjBgkqhkiG9w0BCRUxFgQUdA9eVqvETX4an/c8 -p8SsTugkit8wOwYJKoZIhvcNAQkUMS4eLABGAHIAaQBlAG4AZABsAHkAIABuAGEAbQBlACAAZgBv -AHIAIABjAGUAcgB0MDEwITAJBgUrDgMCGgUABBRFsNz3Zd1O1GI8GTuFwCWuDOjEEwQIuBEfIcAy -HQ8CAggA`, -} diff --git a/vendor/github.com/bitrise-io/go-utils/pointers/pointers_test.go b/vendor/github.com/bitrise-io/go-utils/pointers/pointers_test.go deleted file mode 100644 index c54952bc..00000000 --- a/vendor/github.com/bitrise-io/go-utils/pointers/pointers_test.go +++ /dev/null @@ -1,275 +0,0 @@ -package pointers - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestNewBoolPtr(t *testing.T) { - t.Log("Create false ptr") - if *NewBoolPtr(false) != false { - t.Fatal("Invalid pointer") - } - - t.Log("Create true ptr") - if *NewBoolPtr(true) != true { - t.Fatal("Invalid pointer") - } - - t.Log("Try to change the original value - should not be affected!") - mybool := true - myboolPtr := NewBoolPtr(mybool) - if *myboolPtr != true { - t.Fatal("Invalid pointer - original value") - } - *myboolPtr = false - if *myboolPtr != false { - t.Fatal("Invalid pointer - changed value") - } - // the original var should remain intact! - if mybool != true { - t.Fatal("The original var was affected!!") - } -} - -func TestNewStringPtr(t *testing.T) { - t.Log("Create a string") - if *NewStringPtr("mystr") != "mystr" { - t.Fatal("Invalid pointer") - } - - t.Log("Try to change the original value - should not be affected!") - myStr := "my-orig-str" - myStrPtr := NewStringPtr(myStr) - if *myStrPtr != "my-orig-str" { - t.Fatal("Invalid pointer - original value") - } - *myStrPtr = "new-str-value" - if *myStrPtr != "new-str-value" { - t.Fatal("Invalid pointer - changed value") - } - // the original var should remain intact! - if myStr != "my-orig-str" { - t.Fatal("The original var was affected!!") - } -} - -func TestNewTimePtr(t *testing.T) { - t.Log("Create a time") - if (*NewTimePtr(time.Date(2009, time.January, 1, 0, 0, 0, 0, time.UTC))).Equal(time.Date(2009, time.January, 1, 0, 0, 0, 0, time.UTC)) == false { - t.Fatal("Invalid pointer") - } - - t.Log("Try to change the original value - should not be affected!") - myTime := time.Date(2012, time.January, 1, 0, 0, 0, 0, time.UTC) - myTimePtr := NewTimePtr(myTime) - if (*myTimePtr).Equal(time.Date(2012, time.January, 1, 0, 0, 0, 0, time.UTC)) == false { - t.Fatal("Invalid pointer - original value") - } - *myTimePtr = time.Date(2015, time.January, 1, 0, 0, 0, 0, time.UTC) - if *myTimePtr != time.Date(2015, time.January, 1, 0, 0, 0, 0, time.UTC) { - t.Fatal("Invalid pointer - changed value") - } - // the original var should remain intact! - if myTime.Equal(time.Date(2012, time.January, 1, 0, 0, 0, 0, time.UTC)) == false { - t.Fatal("The original var was affected!!") - } -} - -func TestNewIntPtr(t *testing.T) { - t.Log("Create 1 ptr") - if *NewIntPtr(1) != 1 { - t.Fatal("Invalid pointer") - } - - t.Log("Create 0 ptr") - if *NewIntPtr(0) != 0 { - t.Fatal("Invalid pointer") - } - - t.Log("Try to change the original value - should not be affected!") - myint := 2 - myintPtr := NewIntPtr(myint) - if *myintPtr != 2 { - t.Fatal("Invalid pointer - original value") - } - - *myintPtr = 3 - if *myintPtr != 3 { - t.Fatal("Invalid pointer - changed value") - } - // the original var should remain intact! - if myint != 2 { - t.Fatal("The original var was affected!!") - } -} - -func TestNewInt64Ptr(t *testing.T) { - t.Log("Create 1 ptr") - if *NewInt64Ptr(1) != 1 { - t.Fatal("Invalid pointer") - } - - t.Log("Create 0 ptr") - if *NewInt64Ptr(0) != 0 { - t.Fatal("Invalid pointer") - } - - t.Log("Try to change the original value - should not be affected!") - myint := int64(2) - myintPtr := NewInt64Ptr(myint) - if *myintPtr != 2 { - t.Fatal("Invalid pointer - original value") - } - - *myintPtr = 3 - if *myintPtr != 3 { - t.Fatal("Invalid pointer - changed value") - } - // the original var should remain intact! - if myint != 2 { - t.Fatal("The original var was affected!!") - } -} - -func TestNewMapStringInterfacePtr(t *testing.T) { - t.Log("Create a map") - { - ptr := NewMapStringInterfacePtr(map[string]interface{}{"key": "value"}) - require.Equal(t, 1, len(*ptr)) - require.Equal(t, "value", (*ptr)["key"]) - } - - t.Log("Try to change the original value - should not be affected!") - { - myMap := map[string]interface{}{"key": "orig-value"} - myMapPtr := NewMapStringInterfacePtr(myMap) - require.Equal(t, 1, len(*myMapPtr)) - require.Equal(t, "orig-value", (*myMapPtr)["key"]) - - (*myMapPtr)["key"] = "new-value" - require.Equal(t, 1, len(*myMapPtr)) - require.Equal(t, "new-value", (*myMapPtr)["key"]) - - // the original var should remain intact! - require.Equal(t, 1, len(myMap)) - require.Equal(t, "orig-value", (myMap)["key"]) - } - - t.Log("Try to change the original value - should not be affected!") - { - type TestObject struct { - Title string - Message string - } - - // create ptr with an orig value - testObj := TestObject{ - Title: "title", - Message: "message", - } - myMap := map[string]interface{}{"key": testObj} - myMapPtr := NewMapStringInterfacePtr(myMap) - - require.Equal(t, 1, len(*myMapPtr)) - obj, ok := (*myMapPtr)["key"] - require.Equal(t, true, ok) - - casted, ok := obj.(TestObject) - require.Equal(t, true, ok) - require.Equal(t, "title", casted.Title) - require.Equal(t, "message", casted.Message) - - // modify the value of the ptr - casted.Title = "new-title" - casted.Message = "new-message" - - (*myMapPtr)["key"] = casted - require.Equal(t, 1, len(*myMapPtr)) - newObj, ok := (*myMapPtr)["key"] - require.Equal(t, true, ok) - - newCasted, ok := newObj.(TestObject) - require.Equal(t, true, ok) - require.Equal(t, "new-title", newCasted.Title) - require.Equal(t, "new-message", newCasted.Message) - - // the original var should remain intact! - require.Equal(t, 1, len(myMap)) - origObj, ok := myMap["key"] - require.Equal(t, true, ok) - - origCasted, ok := origObj.(TestObject) - require.Equal(t, true, ok) - require.Equal(t, "title", origCasted.Title) - require.Equal(t, "message", origCasted.Message) - } -} - -func TestBool(t *testing.T) { - require.Equal(t, false, Bool(nil)) - - sampleVal := true - sampleValPtr := &sampleVal - require.Equal(t, true, Bool(sampleValPtr)) -} - -func TestBoolWithDefault(t *testing.T) { - require.Equal(t, false, BoolWithDefault(nil, false)) - require.Equal(t, true, BoolWithDefault(nil, true)) - - sampleVal := true - sampleValPtr := &sampleVal - require.Equal(t, true, BoolWithDefault(sampleValPtr, false)) -} - -func TestString(t *testing.T) { - require.Equal(t, "", String(nil)) - - sampleStr := "sample string" - sampleStrPtr := &sampleStr - require.Equal(t, "sample string", String(sampleStrPtr)) -} - -func TestStringWithDefault(t *testing.T) { - require.Equal(t, "", StringWithDefault(nil, "")) - require.Equal(t, "default value", StringWithDefault(nil, "default value")) - - sampleStr := "sample string" - sampleStrPtr := &sampleStr - require.Equal(t, "sample string", StringWithDefault(sampleStrPtr, "default value")) -} - -func TestTimeWithDefault(t *testing.T) { - const longForm = "Jan 2, 2006 at 3:04pm (MST)" - defaultTime, err := time.Parse(longForm, "Feb 3, 2013 at 7:54pm (PST)") - require.NoError(t, err) - - require.Equal(t, defaultTime, TimeWithDefault(nil, defaultTime)) - - anotherTime, err := time.Parse(longForm, "Feb 4, 2014 at 8:54pm (PST)") - require.NoError(t, err) - anotherTimePtr := &anotherTime - - require.Equal(t, anotherTime, TimeWithDefault(anotherTimePtr, defaultTime)) -} - -func TestInt(t *testing.T) { - require.Equal(t, 0, Int(nil)) - - sampleVal := 12 - sampleValPtr := &sampleVal - require.Equal(t, 12, Int(sampleValPtr)) -} - -func TestIntWithDefault(t *testing.T) { - require.Equal(t, 0, IntWithDefault(nil, 0)) - require.Equal(t, 12, IntWithDefault(nil, 12)) - require.Equal(t, -12, IntWithDefault(nil, -12)) - - sampleVal := 23 - sampleValPtr := &sampleVal - require.Equal(t, 23, IntWithDefault(sampleValPtr, 1)) -} diff --git a/vendor/github.com/bitrise-io/go-utils/progress/progress.go b/vendor/github.com/bitrise-io/go-utils/progress/progress.go deleted file mode 100644 index a3a4d252..00000000 --- a/vendor/github.com/bitrise-io/go-utils/progress/progress.go +++ /dev/null @@ -1,39 +0,0 @@ -package progress - -import ( - "fmt" - "time" -) - -// SimpleProgressE ... -func SimpleProgressE(printChar string, tickInterval time.Duration, action func() error) error { - var actionError error - SimpleProgress(printChar, tickInterval, func() { - actionError = action() - }) - return actionError -} - -// SimpleProgress ... -// action : have to be a synchronous action! -// tickInterval : e.g. : 5000 * time.Millisecond -func SimpleProgress(printChar string, tickInterval time.Duration, action func()) { - // run async - finishedChan := make(chan bool) - - go func() { - action() - finishedChan <- true - }() - - isRunFinished := false - for !isRunFinished { - select { - case <-finishedChan: - isRunFinished = true - case <-time.Tick(tickInterval): - fmt.Print(printChar) - } - } - fmt.Println() -} diff --git a/vendor/github.com/bitrise-io/go-utils/progress/progress_test.go b/vendor/github.com/bitrise-io/go-utils/progress/progress_test.go deleted file mode 100644 index 130a9623..00000000 --- a/vendor/github.com/bitrise-io/go-utils/progress/progress_test.go +++ /dev/null @@ -1,69 +0,0 @@ -package progress - -import ( - "errors" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestSimpleProgress(t *testing.T) { - startTime := time.Now() - - SimpleProgress(".", 500*time.Millisecond, func() { - t.Log("- SimpleProgress [start] -") - time.Sleep(3 * time.Second) - t.Log("- SimpleProgress [end] -") - }) - - duration := time.Now().Sub(startTime) - if duration >= time.Duration(4)*time.Second { - t.Fatalf("Should take no more than 4 sec, but got: %s", duration) - } - if duration < time.Duration(2)*time.Second { - t.Fatalf("Should take at least 2 sec, but got: %s", duration) - } -} - -func TestSimpleProgressE(t *testing.T) { - t.Log("No error") - { - startTime := time.Now() - actionErr := SimpleProgressE(".", 500*time.Millisecond, func() error { - t.Log("- SimpleProgressE [start] -") - time.Sleep(3 * time.Second) - t.Log("- SimpleProgressE [end] -") - return nil - }) - require.NoError(t, actionErr) - - duration := time.Now().Sub(startTime) - if duration >= time.Duration(4)*time.Second { - t.Fatalf("Should take no more than 4 sec, but got: %s", duration) - } - if duration < time.Duration(2)*time.Second { - t.Fatalf("Should take at least 2 sec, but got: %s", duration) - } - } - - t.Log("Return error") - { - startTime := time.Now() - actionErr := SimpleProgressE(".", 500*time.Millisecond, func() error { - t.Log("- SimpleProgressE [start] -") - time.Sleep(3 * time.Second) - t.Log("- SimpleProgressE [end] -") - return errors.New("Test error") - }) - require.EqualError(t, actionErr, "Test error") - - duration := time.Now().Sub(startTime) - if duration >= time.Duration(4)*time.Second { - t.Fatalf("Should take no more than 4 sec, but got: %s", duration) - } - if duration < time.Duration(2)*time.Second { - t.Fatalf("Should take at least 2 sec, but got: %s", duration) - } - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/progress/spinner.go b/vendor/github.com/bitrise-io/go-utils/progress/spinner.go deleted file mode 100644 index e740056f..00000000 --- a/vendor/github.com/bitrise-io/go-utils/progress/spinner.go +++ /dev/null @@ -1,88 +0,0 @@ -package progress - -import ( - "fmt" - "io" - "os" - "time" - "unicode/utf8" -) - -// Spinner ... -type Spinner struct { - message string - chars []string - delay time.Duration - writer io.Writer - - active bool - lastOutput string - stopChan chan bool -} - -// NewSpinner ... -func NewSpinner(message string, chars []string, delay time.Duration, writer io.Writer) Spinner { - return Spinner{ - message: message, - chars: chars, - delay: delay, - writer: writer, - - active: false, - stopChan: make(chan bool), - } -} - -// NewDefaultSpinner ... -func NewDefaultSpinner(message string) Spinner { - chars := []string{"⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"} - delay := 100 * time.Millisecond - writer := os.Stdout - return NewSpinner(message, chars, delay, writer) -} - -func (s *Spinner) erase() { - n := utf8.RuneCountInString(s.lastOutput) - for _, c := range []string{"\b", " ", "\b"} { - for i := 0; i < n; i++ { - fmt.Fprintf(s.writer, c) - } - } - s.lastOutput = "" -} - -// Start ... -func (s *Spinner) Start() { - if s.active { - return - } - s.active = true - - go func() { - for { - for i := 0; i < len(s.chars); i++ { - select { - case <-s.stopChan: - return - default: - s.erase() - - out := fmt.Sprintf("%s %s", s.message, s.chars[i]) - fmt.Fprint(s.writer, out) - s.lastOutput = out - - time.Sleep(s.delay) - } - } - } - }() -} - -// Stop ... -func (s *Spinner) Stop() { - if s.active { - s.active = false - s.erase() - s.stopChan <- true - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/progress/spinner_test.go b/vendor/github.com/bitrise-io/go-utils/progress/spinner_test.go deleted file mode 100644 index 0fd7ee46..00000000 --- a/vendor/github.com/bitrise-io/go-utils/progress/spinner_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package progress - -import ( - "os" - "testing" - "time" -) - -func TestNewSpinner(t *testing.T) { - message := "loading" - chars := []string{"⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"} - delay := 100 * time.Millisecond - writer := os.Stdout - - spinner := NewSpinner(message, chars, delay, writer) - spinner.Start() - time.Sleep(2 * time.Second) - spinner.Stop() -} - -func TestNewDefaultSpinner(t *testing.T) { - message := "loading" - spinner := NewDefaultSpinner(message) - spinner.Start() - time.Sleep(2 * time.Second) - spinner.Stop() -} diff --git a/vendor/github.com/bitrise-io/go-utils/progress/wrapper.go b/vendor/github.com/bitrise-io/go-utils/progress/wrapper.go deleted file mode 100644 index 2ffa2373..00000000 --- a/vendor/github.com/bitrise-io/go-utils/progress/wrapper.go +++ /dev/null @@ -1,52 +0,0 @@ -package progress - -import ( - "fmt" - "os" - "strings" - - "golang.org/x/crypto/ssh/terminal" -) - -// Wrapper ... -type Wrapper struct { - spinner Spinner - action func() - interactiveMode bool -} - -// NewWrapper ... -func NewWrapper(spinner Spinner, interactiveMode bool) Wrapper { - return Wrapper{ - spinner: spinner, - interactiveMode: interactiveMode, - } -} - -// NewDefaultWrapper ... -func NewDefaultWrapper(message string) Wrapper { - spinner := NewDefaultSpinner(message) - interactiveMode := OutputDeviceIsTerminal() - return NewWrapper(spinner, interactiveMode) -} - -// WrapAction ... -func (w Wrapper) WrapAction(action func()) { - if w.interactiveMode { - w.spinner.Start() - action() - w.spinner.Stop() - } else { - message := w.spinner.message - if !strings.HasSuffix(message, ".") { - message = message + "..." - } - fmt.Fprintln(w.spinner.writer, message) - action() - } -} - -// OutputDeviceIsTerminal ... -func OutputDeviceIsTerminal() bool { - return terminal.IsTerminal(int(os.Stdout.Fd())) -} diff --git a/vendor/github.com/bitrise-io/go-utils/progress/wrapper_test.go b/vendor/github.com/bitrise-io/go-utils/progress/wrapper_test.go deleted file mode 100644 index d74e654a..00000000 --- a/vendor/github.com/bitrise-io/go-utils/progress/wrapper_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package progress - -import ( - "testing" - "time" -) - -func TestNewWrapper(t *testing.T) { - message := "loading" - spinner := NewDefaultSpinner(message) - - isInteractiveMode := true - NewWrapper(spinner, isInteractiveMode).WrapAction(func() { - time.Sleep(2 * time.Second) - }) -} - -func TestNewDefaultWrapper(t *testing.T) { - message := "loading" - NewDefaultWrapper(message).WrapAction(func() { - time.Sleep(2 * time.Second) - }) -} diff --git a/vendor/github.com/bitrise-io/go-utils/readerutil/readerutil.go b/vendor/github.com/bitrise-io/go-utils/readerutil/readerutil.go deleted file mode 100644 index 6fc87bee..00000000 --- a/vendor/github.com/bitrise-io/go-utils/readerutil/readerutil.go +++ /dev/null @@ -1,62 +0,0 @@ -package readerutil - -import ( - "bufio" - "io" - "strings" -) - -// ReadLongLine - an alternative to bufio.Scanner.Scan, -// which can't handle long lines. This function is slower than -// bufio.Scanner.Scan, but can handle arbitrary long lines. -func ReadLongLine(r *bufio.Reader) (string, error) { - // Do NOT create a `bufio.Reader` inside thise function, - // get it as an input! (just in case you'd thing about doing a "revision" on this) - // Creating the `bufio.Reader` here would reset/alter the reader, - // if it would be created for every line! Not a good idea! - - isPrefix := true - var err error - var line, ln []byte - - for isPrefix && err == nil { - line, isPrefix, err = r.ReadLine() - ln = append(ln, line...) - } - - return string(ln), err -} - -// WalkLineFn - gets a line as its input -// if returns an error it stops the walk/reading -// to break the walk early, without an error, just return io.EOF -type WalkLineFn func(string) error - -// WalkLines ... -func WalkLines(inpReader io.Reader, walkFn WalkLineFn) error { - reader := bufio.NewReader(inpReader) - - var walkErr error - line, readErr := ReadLongLine(reader) - for ; walkErr == nil && readErr == nil; line, readErr = ReadLongLine(reader) { - walkErr = walkFn(line) - } - - // if walk returned an error (other than io.EOF) - // return that error - if walkErr != nil && walkErr != io.EOF { - return walkErr - } - - // otherwise, if there was a read error (except io.EOF), return that - if readErr != nil && readErr != io.EOF { - return readErr - } - - return nil -} - -// WalkLinesString ... -func WalkLinesString(inputStr string, walkFn WalkLineFn) error { - return WalkLines(strings.NewReader(inputStr), walkFn) -} diff --git a/vendor/github.com/bitrise-io/go-utils/readerutil/readerutil_test.go b/vendor/github.com/bitrise-io/go-utils/readerutil/readerutil_test.go deleted file mode 100644 index a9d1f816..00000000 --- a/vendor/github.com/bitrise-io/go-utils/readerutil/readerutil_test.go +++ /dev/null @@ -1,182 +0,0 @@ -package readerutil - -import ( - "bufio" - "errors" - "fmt" - "io" - "strings" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestReadLongLine(t *testing.T) { - t.Log("Empty string") - { - reader := bufio.NewReader(strings.NewReader(``)) - line, err := ReadLongLine(reader) - require.Equal(t, io.EOF, err) - require.Equal(t, "", line) - } - - t.Log("Single line") - { - reader := bufio.NewReader(strings.NewReader(`a single line`)) - line, err := ReadLongLine(reader) - require.NoError(t, err) - require.Equal(t, "a single line", line) - // read one more - line, err = ReadLongLine(reader) - require.Equal(t, io.EOF, err) - require.Equal(t, "", line) - } - - t.Log("Two lines") - { - reader := bufio.NewReader(strings.NewReader(`first line -second line`)) - // first line - line, readErr := ReadLongLine(reader) - require.NoError(t, readErr) - require.Equal(t, "first line", line) - // second line - line, readErr = ReadLongLine(reader) - require.NoError(t, readErr) - require.Equal(t, "second line", line) - // read one more - line, readErr = ReadLongLine(reader) - require.Equal(t, io.EOF, readErr) - require.Equal(t, "", line) - } - - t.Log("Multi line, with long line") - { - inputStr := fmt.Sprintf(`first line -second line -third, really long line: %s - fourth line -`, strings.Repeat("-", 1000000)) - - reader := bufio.NewReader(strings.NewReader(inputStr)) - // - lines := []string{} - line, readErr := ReadLongLine(reader) - for ; readErr == nil; line, readErr = ReadLongLine(reader) { - lines = append(lines, line) - } - // ideally the error will be io.EOF - require.Equal(t, io.EOF, readErr) - // - require.Equal(t, 4, len(lines)) - require.Equal(t, "first line", lines[0]) - require.Equal(t, "second line", lines[1]) - // check the start of the long line - require.Equal(t, "third, really long line: ---", lines[2][0:28]) - require.Equal(t, " fourth line", lines[3]) - } -} - -func TestWalkLinesString(t *testing.T) { - t.Log("Empty string") - { - inputStr := `` - // - lines := []string{} - err := WalkLinesString(inputStr, func(line string) error { - lines = append(lines, line) - return nil - }) - require.Equal(t, nil, err) - require.Equal(t, []string{}, lines) - } - - t.Log("Single line") - { - inputStr := `a single line` - // - lines := []string{} - err := WalkLinesString(inputStr, func(line string) error { - lines = append(lines, line) - return nil - }) - require.Equal(t, nil, err) - require.Equal(t, []string{"a single line"}, lines) - } - - t.Log("Two lines") - { - inputStr := `first line -second line` - // - lines := []string{} - err := WalkLinesString(inputStr, func(line string) error { - lines = append(lines, line) - return nil - }) - require.Equal(t, nil, err) - require.Equal(t, []string{"first line", "second line"}, lines) - } - - t.Log("Multi line, with long line") - { - inputStr := fmt.Sprintf(`first line -second line -third, really long line: %s - fourth line -`, strings.Repeat("-", 1000000)) - - // - lines := []string{} - err := WalkLinesString(inputStr, func(line string) error { - lines = append(lines, line) - return nil - }) - require.Equal(t, nil, err) - // - require.Equal(t, 4, len(lines)) - require.Equal(t, "first line", lines[0]) - require.Equal(t, "second line", lines[1]) - // check the start of the long line - require.Equal(t, "third, really long line: ---", lines[2][0:28]) - require.Equal(t, " fourth line", lines[3]) - } - - t.Log("Break early, with io.EOF") - { - inputStr := `first line -second line -break here -this should not be included` - // - lines := []string{} - err := WalkLinesString(inputStr, func(line string) error { - if line == "break here" { - return io.EOF - } - lines = append(lines, line) - return nil - }) - require.Equal(t, nil, err) - require.Equal(t, []string{"first line", "second line"}, lines) - } - - t.Log("Break early, with a non io.EOF error") - { - inputStr := `first line -second line -break here -this should not be included` - // - lines := []string{} - err := WalkLinesString(inputStr, func(line string) error { - if line == "break here" { - return errors.New("Please stop") - } - lines = append(lines, line) - return nil - }) - require.EqualError(t, err, "Please stop") - require.Equal(t, []string{"first line", "second line"}, lines) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/regexputil/regexputil.go b/vendor/github.com/bitrise-io/go-utils/regexputil/regexputil.go deleted file mode 100644 index 5a5f501c..00000000 --- a/vendor/github.com/bitrise-io/go-utils/regexputil/regexputil.go +++ /dev/null @@ -1,18 +0,0 @@ -package regexputil - -import "regexp" - -// NamedFindStringSubmatch ... -func NamedFindStringSubmatch(rexp *regexp.Regexp, text string) (map[string]string, bool) { - match := rexp.FindStringSubmatch(text) - if match == nil { - return nil, false - } - result := map[string]string{} - for i, name := range rexp.SubexpNames() { - if i != 0 { - result[name] = match[i] - } - } - return result, true -} diff --git a/vendor/github.com/bitrise-io/go-utils/regexputil/regexputil_test.go b/vendor/github.com/bitrise-io/go-utils/regexputil/regexputil_test.go deleted file mode 100644 index b0368f81..00000000 --- a/vendor/github.com/bitrise-io/go-utils/regexputil/regexputil_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package regexputil - -import ( - "regexp" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNamedFindStringSubmatch(t *testing.T) { - t.Log("Both the name and age group are required") - rexp := regexp.MustCompile(`(?P[a-zA-Z]+) (?P[0-9]+)`) - - t.Log("Simple name+age example") - { - results, isFound := NamedFindStringSubmatch(rexp, "MyName 42") - require.Equal(t, true, isFound) - require.Equal(t, map[string]string{ - "name": "MyName", - "age": "42", - }, results) - } - - t.Log("Includes an additional name at the end") - { - results, isFound := NamedFindStringSubmatch(rexp, "MyName 42 AnotherName") - require.Equal(t, true, isFound) - require.Equal(t, map[string]string{ - "name": "MyName", - "age": "42", - }, results) - } - - t.Log("Includes an additional name at the start") - { - results, isFound := NamedFindStringSubmatch(rexp, "AnotherName MyName 42") - require.Equal(t, true, isFound) - require.Equal(t, map[string]string{ - "name": "MyName", - "age": "42", - }, results) - } - - t.Log("Missing name group - should error") - { - results, isFound := NamedFindStringSubmatch(rexp, " 42") - require.Equal(t, false, isFound) - require.Equal(t, map[string]string(nil), results) - } - - t.Log("Missing age group - should error") - { - results, isFound := NamedFindStringSubmatch(rexp, "MyName ") - require.Equal(t, false, isFound) - require.Equal(t, map[string]string(nil), results) - } - - t.Log("Missing both groups - should error") - { - results, isFound := NamedFindStringSubmatch(rexp, "") - require.Equal(t, false, isFound) - require.Equal(t, map[string]string(nil), results) - } - - t.Log("Optional name part") - rexp = regexp.MustCompile(`(?P[a-zA-Z]*) (?P[0-9]+)`) - - t.Log("Name can now be empty - but should be included in the result!") - { - results, isFound := NamedFindStringSubmatch(rexp, " 42") - require.Equal(t, true, isFound) - require.Equal(t, map[string]string{ - "name": "", - "age": "42", - }, results) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/retry/retry_test.go b/vendor/github.com/bitrise-io/go-utils/retry/retry_test.go deleted file mode 100644 index 172785b3..00000000 --- a/vendor/github.com/bitrise-io/go-utils/retry/retry_test.go +++ /dev/null @@ -1,149 +0,0 @@ -package retry - -import ( - "errors" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestRetry(t *testing.T) { - t.Log("it does not retryies if no error") - { - retryCnt := 0 - - err := Times(2).Try(func(attempt uint) error { - retryCnt++ - return nil - }) - - require.NoError(t, err) - require.Equal(t, 1, retryCnt) - } - - t.Log("it does retry if error") - { - attemptCnt := 0 - err := Times(2).Try(func(attempt uint) error { - attemptCnt++ - return errors.New("error") - }) - - require.Error(t, err) - require.Equal(t, "error", err.Error()) - require.Equal(t, 3, attemptCnt) - } - - t.Log("it does not retry if Times=0") - { - attemptCnt := 0 - - err := Times(0).Try(func(attempt uint) error { - attemptCnt++ - return errors.New("error") - }) - - require.Error(t, err) - require.Equal(t, "error", err.Error()) - require.Equal(t, 1, attemptCnt) - } - - t.Log("it does a total attempt of 2 if Times=1") - { - attemptCnt := 0 - - err := Times(1).Try(func(attempt uint) error { - attemptCnt++ - return errors.New("error") - }) - - require.Error(t, err) - require.Equal(t, "error", err.Error()) - require.Equal(t, 2, attemptCnt) - } - - t.Log("it does a total attempt of 5 if Times=4") - { - attemptCnt := 0 - - err := Times(4).Try(func(attempt uint) error { - attemptCnt++ - return errors.New("error") - }) - - require.Error(t, err) - require.Equal(t, "error", err.Error()) - require.Equal(t, 5, attemptCnt) - } - - t.Log("it does not wait before first execution") - { - attemptCnt := 0 - startTime := time.Now() - - err := Times(1).Wait(3 * time.Second).Try(func(attempt uint) error { - attemptCnt++ - return errors.New("error") - }) - - duration := time.Now().Sub(startTime) - - require.Error(t, err) - require.Equal(t, "error", err.Error()) - require.Equal(t, 2, attemptCnt) - if duration >= time.Duration(4)*time.Second { - t.Fatalf("Should take no more than 4 sec, but got: %s", duration) - } - } - - t.Log("it waits before second execution") - { - attemptCnt := 0 - startTime := time.Now() - - err := Times(1).Wait(4 * time.Second).Try(func(attempt uint) error { - attemptCnt++ - return errors.New("error") - }) - - duration := time.Now().Sub(startTime) - - require.Error(t, err) - require.Equal(t, "error", err.Error()) - require.Equal(t, 2, attemptCnt) - if duration < time.Duration(3)*time.Second { - t.Fatalf("Should take at least 3 sec, but got: %s", duration) - } - } -} - -func TestWait(t *testing.T) { - t.Log("it creates retry model with wait time") - { - helper := Wait(3 * time.Second) - require.Equal(t, 3*time.Second, helper.waitTime) - } - - t.Log("it creates retry model with wait time") - { - helper := Wait(3 * time.Second) - helper.Wait(5 * time.Second) - require.Equal(t, 5*time.Second, helper.waitTime) - } -} - -func TestTimes(t *testing.T) { - t.Log("it creates retry model with retry times") - { - helper := Times(3) - require.Equal(t, uint(3), helper.retry) - } - - t.Log("it sets retry times") - { - helper := Times(3) - helper.Times(5) - require.Equal(t, uint(5), helper.retry) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/sliceutil/sliceutil.go b/vendor/github.com/bitrise-io/go-utils/sliceutil/sliceutil.go deleted file mode 100644 index 9f51cb50..00000000 --- a/vendor/github.com/bitrise-io/go-utils/sliceutil/sliceutil.go +++ /dev/null @@ -1,32 +0,0 @@ -package sliceutil - -// UniqueStringSlice - returns a cleaned up list, -// where every item is unique. -// Does NOT guarantee any ordering, the result can -// be in any order! -func UniqueStringSlice(strs []string) []string { - lookupMap := map[string]interface{}{} - for _, aStr := range strs { - lookupMap[aStr] = 1 - } - uniqueStrs := []string{} - for k := range lookupMap { - uniqueStrs = append(uniqueStrs, k) - } - return uniqueStrs -} - -// IndexOfStringInSlice ... -func IndexOfStringInSlice(searchFor string, searchIn []string) int { - for idx, anItm := range searchIn { - if anItm == searchFor { - return idx - } - } - return -1 -} - -// IsStringInSlice ... -func IsStringInSlice(searchFor string, searchIn []string) bool { - return IndexOfStringInSlice(searchFor, searchIn) >= 0 -} diff --git a/vendor/github.com/bitrise-io/go-utils/sliceutil/sliceutil_test.go b/vendor/github.com/bitrise-io/go-utils/sliceutil/sliceutil_test.go deleted file mode 100644 index e4f776d0..00000000 --- a/vendor/github.com/bitrise-io/go-utils/sliceutil/sliceutil_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package sliceutil - -import ( - "testing" - - "github.com/bitrise-io/go-utils/testutil" - "github.com/stretchr/testify/require" -) - -func TestUniqueStringSlice(t *testing.T) { - require.Equal(t, []string{}, UniqueStringSlice([]string{})) - require.Equal(t, []string{"one"}, UniqueStringSlice([]string{"one"})) - testutil.EqualSlicesWithoutOrder(t, - []string{"one", "two"}, - UniqueStringSlice([]string{"one", "two"})) - testutil.EqualSlicesWithoutOrder(t, - []string{"one", "two", "three"}, - UniqueStringSlice([]string{"one", "two", "three", "two", "one"})) -} - -func TestIndexOfStringInSlice(t *testing.T) { - t.Log("Empty slice") - require.Equal(t, -1, IndexOfStringInSlice("abc", []string{})) - - testSlice := []string{"abc", "def", "123", "456", "123"} - - t.Log("Find item") - require.Equal(t, 0, IndexOfStringInSlice("abc", testSlice)) - require.Equal(t, 1, IndexOfStringInSlice("def", testSlice)) - require.Equal(t, 3, IndexOfStringInSlice("456", testSlice)) - - t.Log("Find first item, if multiple") - require.Equal(t, 2, IndexOfStringInSlice("123", testSlice)) - - t.Log("Item is not in the slice") - require.Equal(t, -1, IndexOfStringInSlice("cba", testSlice)) -} - -func TestIsStringInSlice(t *testing.T) { - t.Log("Empty slice") - require.Equal(t, false, IsStringInSlice("abc", []string{})) - - testSlice := []string{"abc", "def", "123", "456", "123"} - - t.Log("Find item") - require.Equal(t, true, IsStringInSlice("abc", testSlice)) - require.Equal(t, true, IsStringInSlice("def", testSlice)) - require.Equal(t, true, IsStringInSlice("456", testSlice)) - - t.Log("Find first item, if multiple") - require.Equal(t, true, IsStringInSlice("123", testSlice)) - - t.Log("Item is not in the slice") - require.Equal(t, false, IsStringInSlice("cba", testSlice)) -} diff --git a/vendor/github.com/bitrise-io/go-utils/stringutil/stringutil.go b/vendor/github.com/bitrise-io/go-utils/stringutil/stringutil.go deleted file mode 100644 index ed439c8e..00000000 --- a/vendor/github.com/bitrise-io/go-utils/stringutil/stringutil.go +++ /dev/null @@ -1,92 +0,0 @@ -package stringutil - -import ( - "bufio" - "fmt" - "strings" -) - -// ReadFirstLine ... -func ReadFirstLine(s string, isIgnoreLeadingEmptyLines bool) string { - scanner := bufio.NewScanner(strings.NewReader(s)) - firstLine := "" - for scanner.Scan() { - firstLine = scanner.Text() - if !isIgnoreLeadingEmptyLines || firstLine != "" { - break - } - } - return firstLine -} - -// CaseInsensitiveEquals ... -func CaseInsensitiveEquals(a, b string) bool { - a, b = strings.ToLower(a), strings.ToLower(b) - return a == b -} - -// CaseInsensitiveContains ... -func CaseInsensitiveContains(s, substr string) bool { - s, substr = strings.ToLower(s), strings.ToLower(substr) - return strings.Contains(s, substr) -} - -// MaxLastChars returns the last maxCharCount characters, -// or in case maxCharCount is more than or equal to the string's length -// it'll just return the whole string. -func MaxLastChars(inStr string, maxCharCount int) string { - return genericTrim(inStr, maxCharCount, true, false) -} - -// MaxLastCharsWithDots ... -func MaxLastCharsWithDots(inStr string, maxCharCount int) string { - return genericTrim(inStr, maxCharCount, true, true) -} - -// MaxFirstChars ... -func MaxFirstChars(inStr string, maxCharCount int) string { - return genericTrim(inStr, maxCharCount, false, false) -} - -// MaxFirstCharsWithDots ... -func MaxFirstCharsWithDots(inStr string, maxCharCount int) string { - return genericTrim(inStr, maxCharCount, false, true) -} - -func genericTrim(inStr string, maxCharCount int, trimmAtStart, appendDots bool) string { - retStr := inStr - strLen := len(inStr) - - if maxCharCount >= strLen { - return retStr - } - - if appendDots { - if maxCharCount < 4 { - fmt.Println("Append dots mode, but string length < 4") - return "" - } - } - if trimmAtStart { - if appendDots { - retStr = inStr[strLen-(maxCharCount-3):] - } else { - retStr = inStr[strLen-maxCharCount:] - } - } else { - if appendDots { - retStr = inStr[:maxCharCount-3] - } else { - retStr = inStr[:maxCharCount] - } - } - - if appendDots { - if trimmAtStart { - retStr = "..." + retStr - } else { - retStr = retStr + "..." - } - } - return retStr -} diff --git a/vendor/github.com/bitrise-io/go-utils/stringutil/stringutil_test.go b/vendor/github.com/bitrise-io/go-utils/stringutil/stringutil_test.go deleted file mode 100644 index da59739e..00000000 --- a/vendor/github.com/bitrise-io/go-utils/stringutil/stringutil_test.go +++ /dev/null @@ -1,169 +0,0 @@ -package stringutil - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestReadFirstLine(t *testing.T) { - t.Log("Empty input") - { - require.Equal(t, "", ReadFirstLine("", false)) - require.Equal(t, "", ReadFirstLine("", true)) - } - - t.Log("Multiline empty input - ignore-empty-lines:false") - { - firstLine := ReadFirstLine(` - - -`, false) - require.Equal(t, "", firstLine) - } - - t.Log("Multiline empty input - ignore-empty-lines:true") - { - firstLine := ReadFirstLine(` - - -`, true) - require.Equal(t, "", firstLine) - } - - t.Log("Multiline non empty input - ignore-empty-lines:false") - { - firstLine := ReadFirstLine(`first line - -second line`, false) - require.Equal(t, "first line", firstLine) - } - - t.Log("Multiline empty input - ignore-empty-lines:true") - { - firstLine := ReadFirstLine(`first line - -second line`, true) - require.Equal(t, "first line", firstLine) - } - - t.Log("Multiline non empty input, with leading empty line - ignore-empty-lines:false") - { - firstLine := ReadFirstLine(` - -first line - -second line`, false) - require.Equal(t, "", firstLine) - } - - t.Log("Multiline non empty input, with leading empty line - ignore-empty-lines:true") - { - firstLine := ReadFirstLine(` - -first line - -second line`, true) - require.Equal(t, "first line", firstLine) - } -} - -func TestCaseInsensitiveEquals(t *testing.T) { - var emptyStr string // "" - - require.Equal(t, true, CaseInsensitiveEquals(emptyStr, emptyStr)) - require.Equal(t, true, CaseInsensitiveEquals("", "")) - - require.Equal(t, true, CaseInsensitiveEquals(emptyStr, "")) - require.Equal(t, true, CaseInsensitiveEquals("", emptyStr)) - - require.Equal(t, false, CaseInsensitiveEquals(emptyStr, "a")) - require.Equal(t, false, CaseInsensitiveEquals("a", emptyStr)) - - require.Equal(t, true, CaseInsensitiveEquals("a", "a")) - require.Equal(t, true, CaseInsensitiveEquals("a", "A")) - - require.Equal(t, true, CaseInsensitiveEquals("ab", "Ab")) - - require.Equal(t, false, CaseInsensitiveEquals("ab", "ba")) - require.Equal(t, false, CaseInsensitiveEquals("ab", "Ba")) -} - -func TestCaseInsensitiveContains(t *testing.T) { - var emptyStr string // "" - - require.Equal(t, true, CaseInsensitiveContains(emptyStr, emptyStr)) - require.Equal(t, true, CaseInsensitiveContains("", "")) - - require.Equal(t, true, CaseInsensitiveContains(emptyStr, "")) - require.Equal(t, true, CaseInsensitiveContains("", emptyStr)) - - require.Equal(t, false, CaseInsensitiveContains(emptyStr, "a")) - require.Equal(t, true, CaseInsensitiveContains("a", emptyStr)) - - require.Equal(t, true, CaseInsensitiveContains("a", "a")) - require.Equal(t, true, CaseInsensitiveContains("A", "a")) - - require.Equal(t, true, CaseInsensitiveContains("abc", "a")) - require.Equal(t, true, CaseInsensitiveContains("abc", "B")) - require.Equal(t, true, CaseInsensitiveContains("abc", "BC")) - require.Equal(t, true, CaseInsensitiveContains("abc", "ABC")) - - require.Equal(t, false, CaseInsensitiveContains("abc", "d")) - require.Equal(t, false, CaseInsensitiveContains("abc", "ba")) - require.Equal(t, false, CaseInsensitiveContains("abc", "BAC")) -} - -func TestGenericTrim(t *testing.T) { - require.Equal(t, "", genericTrim("", 4, false, false)) - require.Equal(t, "", genericTrim("", 4, false, true)) - require.Equal(t, "", genericTrim("", 4, true, false)) - require.Equal(t, "", genericTrim("", 4, true, true)) - - require.Equal(t, "1234", genericTrim("123456789", 4, false, false)) - require.Equal(t, "1...", genericTrim("123456789", 4, false, true)) - require.Equal(t, "6789", genericTrim("123456789", 4, true, false)) - require.Equal(t, "...9", genericTrim("123456789", 4, true, true)) -} - -func TestMaxLastChars(t *testing.T) { - require.Equal(t, "", MaxLastChars("", 10)) - require.Equal(t, "a", MaxLastChars("a", 1)) - require.Equal(t, "a", MaxLastChars("ba", 1)) - require.Equal(t, "ba", MaxLastChars("ba", 10)) - require.Equal(t, "a", MaxLastChars("cba", 1)) - require.Equal(t, "cba", MaxLastChars("cba", 10)) - - require.Equal(t, "llo world!", MaxLastChars("hello world!", 10)) -} - -func TestMaxLastCharsWithDots(t *testing.T) { - require.Equal(t, "", MaxLastCharsWithDots("", 10)) - require.Equal(t, "", MaxLastCharsWithDots("1234", 1)) - require.Equal(t, "...56", MaxLastCharsWithDots("123456", 5)) - require.Equal(t, "123456", MaxFirstCharsWithDots("123456", 6)) - require.Equal(t, "123456", MaxLastCharsWithDots("123456", 10)) - - require.Equal(t, "... world!", MaxLastCharsWithDots("hello world!", 10)) -} - -func TestMaxFirstChars(t *testing.T) { - require.Equal(t, "", MaxFirstChars("", 10)) - require.Equal(t, "a", MaxFirstChars("a", 1)) - require.Equal(t, "b", MaxFirstChars("ba", 1)) - require.Equal(t, "ba", MaxFirstChars("ba", 10)) - require.Equal(t, "c", MaxFirstChars("cba", 1)) - require.Equal(t, "cba", MaxFirstChars("cba", 10)) - - require.Equal(t, "hello worl", MaxFirstChars("hello world!", 10)) -} - -func TestMaxFirstCharsWithDots(t *testing.T) { - require.Equal(t, "", MaxFirstCharsWithDots("", 10)) - require.Equal(t, "", MaxFirstCharsWithDots("1234", 1)) - require.Equal(t, "12...", MaxFirstCharsWithDots("123456", 5)) - require.Equal(t, "123456", MaxFirstCharsWithDots("123456", 6)) - require.Equal(t, "123456", MaxFirstCharsWithDots("123456", 10)) - - require.Equal(t, "hello w...", MaxFirstCharsWithDots("hello world!", 10)) -} diff --git a/vendor/github.com/bitrise-io/go-utils/stringutil/text.go b/vendor/github.com/bitrise-io/go-utils/stringutil/text.go deleted file mode 100644 index 49c0ed34..00000000 --- a/vendor/github.com/bitrise-io/go-utils/stringutil/text.go +++ /dev/null @@ -1,49 +0,0 @@ -package stringutil - -import ( - "bufio" - "math" - "strings" -) - -// IndentTextWithMaxLength ... -func IndentTextWithMaxLength(text, indent string, maxTextLineCharWidth int, isIndentFirstLine bool) string { - if maxTextLineCharWidth < 1 { - return "" - } - - formattedText := "" - - addLine := func(line string) { - isFirstLine := (formattedText == "") - if isFirstLine && !isIndentFirstLine { - formattedText = line - } else { - if !isFirstLine { - formattedText += "\n" - } - formattedText += indent + line - } - } - - scanner := bufio.NewScanner(strings.NewReader(text)) - for scanner.Scan() { - line := scanner.Text() - lineLength := len(line) - if lineLength > maxTextLineCharWidth { - lineCnt := math.Ceil(float64(lineLength) / float64(maxTextLineCharWidth)) - for i := 0; i < int(lineCnt); i++ { - startIdx := i * maxTextLineCharWidth - endIdx := startIdx + maxTextLineCharWidth - if endIdx > lineLength { - endIdx = lineLength - } - addLine(line[startIdx:endIdx]) - } - } else { - addLine(line) - } - } - - return formattedText -} diff --git a/vendor/github.com/bitrise-io/go-utils/stringutil/text_test.go b/vendor/github.com/bitrise-io/go-utils/stringutil/text_test.go deleted file mode 100644 index 1f05a75e..00000000 --- a/vendor/github.com/bitrise-io/go-utils/stringutil/text_test.go +++ /dev/null @@ -1,116 +0,0 @@ -package stringutil - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestIndentTextWithMaxLength(t *testing.T) { - t.Log("Empty") - { - input := "" - output := IndentTextWithMaxLength(input, "", 80, true) - require.Equal(t, "", output) - } - - t.Log("One liner") - { - input := "one liner" - output := IndentTextWithMaxLength(input, "", 80, true) - require.Equal(t, "one liner", output) - } - - t.Log("One liner - with indent") - { - input := "one liner" - output := IndentTextWithMaxLength(input, " => ", 76, true) - require.Equal(t, " => one liner", output) - } - - t.Log("One liner - max width") - { - input := "one" - output := IndentTextWithMaxLength(input, "", 3, true) - require.Equal(t, "one", output) - } - - t.Log("One liner - longer than max width") - { - input := "onetwo" - output := IndentTextWithMaxLength(input, "", 3, true) - require.Equal(t, "one\ntwo", output) - } - - t.Log("One liner - max width - with indent") - { - input := "one" - require.Equal(t, " on\n e", IndentTextWithMaxLength(input, " ", 2, true)) - require.Equal(t, "on\n e", IndentTextWithMaxLength(input, " ", 2, false)) - } - - t.Log("One liner - max width - with first-line indent false") - { - input := "one" - output := IndentTextWithMaxLength(input, " ", 2, false) - require.Equal(t, "on\n e", output) - } - - t.Log("One liner - longer than max width - with indent") - { - input := "onetwo" - require.Equal(t, " on\n et\n wo", IndentTextWithMaxLength(input, " ", 2, true)) - require.Equal(t, "on\n et\n wo", IndentTextWithMaxLength(input, " ", 2, false)) - } - - t.Log("Two lines, shorter than max") - { - input := `first line -second line` - output := IndentTextWithMaxLength(input, "", 80, true) - require.Equal(t, `first line -second line`, output) - } - - t.Log("Two lines, shorter than max - with indent") - { - input := `first line -second line` - - require.Equal(t, ` first line - second line`, IndentTextWithMaxLength(input, " ", 78, true)) - require.Equal(t, `first line - second line`, IndentTextWithMaxLength(input, " ", 78, false)) - } - - t.Log("Two lines, longer than max") - { - input := `firstline -secondline` - output := IndentTextWithMaxLength(input, "", 5, true) - require.Equal(t, `first -line -secon -dline`, output) - } - - t.Log("Max length = 0") - { - input := "Indent is longer than max length" - require.Equal(t, "", IndentTextWithMaxLength(input, "...", 0, true)) - require.Equal(t, "", IndentTextWithMaxLength(input, "...", 0, false)) - require.Equal(t, "", IndentTextWithMaxLength(input, "", 0, true)) - require.Equal(t, "", IndentTextWithMaxLength(input, "", 0, false)) - } - - t.Log("Max length = 0 - multi-line") - { - input := `Indent is longer -than max -length` - require.Equal(t, "", IndentTextWithMaxLength(input, "...", 0, true)) - require.Equal(t, "", IndentTextWithMaxLength(input, "...", 0, false)) - require.Equal(t, "", IndentTextWithMaxLength(input, "", 0, true)) - require.Equal(t, "", IndentTextWithMaxLength(input, "", 0, false)) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/templateutil/templateutil.go b/vendor/github.com/bitrise-io/go-utils/templateutil/templateutil.go deleted file mode 100644 index e9861549..00000000 --- a/vendor/github.com/bitrise-io/go-utils/templateutil/templateutil.go +++ /dev/null @@ -1,61 +0,0 @@ -package templateutil - -import ( - "bytes" - "text/template" -) - -// evaluateTemplate ... -// -// templateOptions: https://golang.org/pkg/text/template/#Template.Option -func evaluateTemplate( - templateContent string, - inventory interface{}, - funcs template.FuncMap, - delimLeft, delimRight string, - templateOptions []string, -) (string, error) { - tmpl := template.New("").Funcs(funcs).Delims(delimLeft, delimRight) - if len(templateOptions) > 0 { - tmpl = tmpl.Option(templateOptions...) - } - tmpl, err := tmpl.Parse(templateContent) - if err != nil { - return "", err - } - - var resBuffer bytes.Buffer - if err := tmpl.Execute(&resBuffer, inventory); err != nil { - return "", err - } - - return resBuffer.String(), nil -} - -// EvaluateTemplateStringToStringWithDelimiterAndOpts ... -// -// templateOptions: https://golang.org/pkg/text/template/#Template.Option -func EvaluateTemplateStringToStringWithDelimiterAndOpts( - templateContent string, - inventory interface{}, - funcs template.FuncMap, - delimLeft, delimRight string, - templateOptions []string, -) (string, error) { - return evaluateTemplate(templateContent, inventory, funcs, delimLeft, delimRight, templateOptions) -} - -// EvaluateTemplateStringToStringWithDelimiter ... -func EvaluateTemplateStringToStringWithDelimiter( - templateContent string, - inventory interface{}, - funcs template.FuncMap, - delimLeft, delimRight string, -) (string, error) { - return evaluateTemplate(templateContent, inventory, funcs, delimLeft, delimRight, []string{}) -} - -// EvaluateTemplateStringToString ... -func EvaluateTemplateStringToString(templateContent string, inventory interface{}, funcs template.FuncMap) (string, error) { - return EvaluateTemplateStringToStringWithDelimiter(templateContent, inventory, funcs, "", "") -} diff --git a/vendor/github.com/bitrise-io/go-utils/templateutil/templateutil_test.go b/vendor/github.com/bitrise-io/go-utils/templateutil/templateutil_test.go deleted file mode 100644 index 907762a9..00000000 --- a/vendor/github.com/bitrise-io/go-utils/templateutil/templateutil_test.go +++ /dev/null @@ -1,141 +0,0 @@ -package templateutil - -import ( - "testing" - - "text/template" - - "github.com/stretchr/testify/require" -) - -type EmptyInventory struct { -} - -type Inventory struct { - Material string - Count uint -} - -func TestEvaluateTemplateStringToString(t *testing.T) { - t.Log("Empty") - result, err := EvaluateTemplateStringToString("", EmptyInventory{}, template.FuncMap{}) - require.NoError(t, err) - require.Equal(t, "", result) - // - result, err = EvaluateTemplateStringToString("", Inventory{"wool", 17}, template.FuncMap{}) - require.NoError(t, err) - require.Equal(t, "", result) - // - result, err = EvaluateTemplateStringToString("no template string", Inventory{"wool", 17}, template.FuncMap{}) - require.NoError(t, err) - require.Equal(t, "no template string", result) - - t.Log("Empty inventory - missing argument/property (error)") - result, err = EvaluateTemplateStringToString("{{.Count}} items are made of {{.Material}}", - EmptyInventory{}, template.FuncMap{}) - require.Error(t, err) - - // - var templateFuncMap = template.FuncMap{ - "isOne": func(i int) bool { - return i == 1 - }, - } - - t.Log("Simple") - inv := Inventory{"wool", 17} - result, err = EvaluateTemplateStringToString("{{.Count}} items are made of {{.Material}}", - inv, template.FuncMap{}) - require.NoError(t, err) - require.Equal(t, "17 items are made of wool", result) - - inv = Inventory{"glass", 18} - result, err = EvaluateTemplateStringToString("{{.Count}} items are made of {{.Material}}", - inv, templateFuncMap) - require.NoError(t, err) - require.Equal(t, "18 items are made of glass", result) -} - -func TestEvaluateTemplateStringToStringWithDelimiter(t *testing.T) { - // custom delimiter - { - inv := Inventory{"wool", 17} - result, err := EvaluateTemplateStringToStringWithDelimiter("<<.Count>> items are made of <<.Material>>", - inv, template.FuncMap{}, "<<", ">>") - require.NoError(t, err) - require.Equal(t, "17 items are made of wool", result) - } - - // custom delimiter - but defalt used in template - { - inv := Inventory{"wool", 17} - result, err := EvaluateTemplateStringToStringWithDelimiter("{{.Count}} items are made of {{.Material}}", - inv, template.FuncMap{}, "<<", ">>") - require.NoError(t, err) - require.Equal(t, "{{.Count}} items are made of {{.Material}}", result) - } -} - -func Test_evaluateTemplate(t *testing.T) { - t.Log("No options") - { - inv := Inventory{"wool", 17} - result, err := evaluateTemplate("<<.Count>> items are made of <<.Material>>", - inv, template.FuncMap{}, "<<", ">>", - []string{}) - require.NoError(t, err) - require.Equal(t, "17 items are made of wool", result) - } - - t.Log("Template options - error on missing") - { - inv := Inventory{"wool", 17} - result, err := evaluateTemplate("<<.Undefined>> items are made of <<.Material>>", - inv, template.FuncMap{}, "<<", ">>", - []string{"missingkey=error"}) - require.EqualError(t, err, `template: :1:2: executing "" at <.Undefined>: can't evaluate field Undefined in type templateutil.Inventory`) - require.Equal(t, "", result) - } - - t.Log("Template options - error on missing; default delimiters") - { - inv := Inventory{"wool", 17} - result, err := evaluateTemplate("{{.UndefinedDefDelim}} items are made of {{.Material}}", - inv, template.FuncMap{}, "", "", - []string{"missingkey=error"}) - require.EqualError(t, err, `template: :1:2: executing "" at <.UndefinedDefDelim>: can't evaluate field UndefinedDefDelim in type templateutil.Inventory`) - require.Equal(t, "", result) - } -} - -func TestEvaluateTemplateStringToStringWithDelimiterAndOpts(t *testing.T) { - t.Log("No options") - { - inv := Inventory{"wool", 17} - result, err := EvaluateTemplateStringToStringWithDelimiterAndOpts("<<.Count>> items are made of <<.Material>>", - inv, template.FuncMap{}, "<<", ">>", - []string{}) - require.NoError(t, err) - require.Equal(t, "17 items are made of wool", result) - } - - t.Log("Template options - error on missing") - { - inv := Inventory{"wool", 17} - result, err := EvaluateTemplateStringToStringWithDelimiterAndOpts("<<.Undefined>> items are made of <<.Material>>", - inv, template.FuncMap{}, "<<", ">>", - []string{"missingkey=error"}) - require.EqualError(t, err, `template: :1:2: executing "" at <.Undefined>: can't evaluate field Undefined in type templateutil.Inventory`) - require.Equal(t, "", result) - } - - t.Log("Template options - error on missing; default delimiters") - { - inv := Inventory{"wool", 17} - result, err := EvaluateTemplateStringToStringWithDelimiterAndOpts("{{.UndefinedDefDelim}} items are made of {{.Material}}", - inv, template.FuncMap{}, "", "", - []string{"missingkey=error"}) - require.EqualError(t, err, `template: :1:2: executing "" at <.UndefinedDefDelim>: can't evaluate field UndefinedDefDelim in type templateutil.Inventory`) - require.Equal(t, "", result) - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/testutil/testutil.go b/vendor/github.com/bitrise-io/go-utils/testutil/testutil.go deleted file mode 100644 index 28a827f3..00000000 --- a/vendor/github.com/bitrise-io/go-utils/testutil/testutil.go +++ /dev/null @@ -1,37 +0,0 @@ -package testutil - -import ( - "fmt" - "testing" - - "github.com/bitrise-io/go-utils/builtinutil" - "github.com/stretchr/testify/require" -) - -// EqualAndNoError ... -func EqualAndNoError(t *testing.T, expected, actual interface{}, err error, msgAndArgs ...interface{}) { - require.NoError(t, err, msgAndArgs...) - require.Equal(t, expected, actual, msgAndArgs...) -} - -func equalSlicesWithoutOrder(t *testing.T, expected, actual []interface{}, msgAndArgs ...interface{}) { - if !builtinutil.DeepEqualSlices(expected, actual) { - require.FailNow(t, fmt.Sprintf("Not equal: %#v (expected)\n"+ - " != %#v (actual)", expected, actual), msgAndArgs...) - } -} - -// EqualSlicesWithoutOrder - regardless the order, but same items -func EqualSlicesWithoutOrder(t *testing.T, expected, actual interface{}, msgAndArgs ...interface{}) { - castedExpected, err := builtinutil.CastInterfaceToInterfaceSlice(expected) - if err != nil { - require.FailNow(t, fmt.Sprintf("'expected' is not a slice: %#v", expected), msgAndArgs...) - } - - castedActual, err := builtinutil.CastInterfaceToInterfaceSlice(actual) - if err != nil { - require.FailNow(t, fmt.Sprintf("'actual' is not a slice: %#v", actual), msgAndArgs...) - } - - equalSlicesWithoutOrder(t, castedExpected, castedActual, msgAndArgs...) -} diff --git a/vendor/github.com/bitrise-io/go-utils/testutil/testutil_test.go b/vendor/github.com/bitrise-io/go-utils/testutil/testutil_test.go deleted file mode 100644 index 110b2e6a..00000000 --- a/vendor/github.com/bitrise-io/go-utils/testutil/testutil_test.go +++ /dev/null @@ -1 +0,0 @@ -package testutil diff --git a/vendor/github.com/bitrise-io/go-utils/urlutil/urlutil_test.go b/vendor/github.com/bitrise-io/go-utils/urlutil/urlutil_test.go deleted file mode 100644 index af9d411d..00000000 --- a/vendor/github.com/bitrise-io/go-utils/urlutil/urlutil_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package urlutil - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -type testElem struct { - testParts []string - expectedJoined string -} - -func TestJoin(t *testing.T) { - for _, currTestElem := range []testElem{ - testElem{[]string{"https://bitrise.io", "something"}, "https://bitrise.io/something"}, - testElem{[]string{"https://bitrise.io", "something/a"}, "https://bitrise.io/something/a"}, - testElem{[]string{"https://bitrise.io", "something/a/b"}, "https://bitrise.io/something/a/b"}, - testElem{[]string{"https://bitrise.io", "something/a/b/"}, "https://bitrise.io/something/a/b/"}, - - testElem{[]string{"https://bitrise.io", "/something"}, "https://bitrise.io/something"}, - testElem{[]string{"https://bitrise.io", "/something/a"}, "https://bitrise.io/something/a"}, - testElem{[]string{"https://bitrise.io", "/something/a/b"}, "https://bitrise.io/something/a/b"}, - testElem{[]string{"https://bitrise.io", "/something/a/b/"}, "https://bitrise.io/something/a/b/"}, - - testElem{[]string{"https://bitrise.io/", "/something"}, "https://bitrise.io/something"}, - testElem{[]string{"https://bitrise.io/", "/something/a"}, "https://bitrise.io/something/a"}, - testElem{[]string{"https://bitrise.io/", "/something/a/b"}, "https://bitrise.io/something/a/b"}, - testElem{[]string{"https://bitrise.io/", "/something/a/b/"}, "https://bitrise.io/something/a/b/"}, - - testElem{[]string{"https://bitrise.io//", "//something"}, "https://bitrise.io/something"}, - testElem{[]string{"https://bitrise.io//", "//something/a"}, "https://bitrise.io/something/a"}, - testElem{[]string{"https://bitrise.io//", "//something/a/b"}, "https://bitrise.io/something/a/b"}, - testElem{[]string{"https://bitrise.io//", "//something/a/b/"}, "https://bitrise.io/something/a/b/"}, - - testElem{[]string{"https://bitrise-steplib-collection.s3.amazonaws.com/steps", "activate-ssh-key", "assets", "icon.svg"}, "https://bitrise-steplib-collection.s3.amazonaws.com/steps/activate-ssh-key/assets/icon.svg"}, - testElem{[]string{"https://bitrise-steplib-collection.s3.amazonaws.com/steps/", "activate-ssh-key", "assets", "icon.svg"}, "https://bitrise-steplib-collection.s3.amazonaws.com/steps/activate-ssh-key/assets/icon.svg"}, - testElem{[]string{"https://bitrise-steplib-collection.s3.amazonaws.com/steps/", "/activate-ssh-key", "assets", "icon.svg"}, "https://bitrise-steplib-collection.s3.amazonaws.com/steps/activate-ssh-key/assets/icon.svg"}, - testElem{[]string{"https://bitrise-steplib-collection.s3.amazonaws.com/steps/", "/activate-ssh-key", "/assets", "icon.svg"}, "https://bitrise-steplib-collection.s3.amazonaws.com/steps/activate-ssh-key/assets/icon.svg"}, - testElem{[]string{"https://bitrise-steplib-collection.s3.amazonaws.com/steps/", "/activate-ssh-key", "/assets", "/icon.svg"}, "https://bitrise-steplib-collection.s3.amazonaws.com/steps/activate-ssh-key/assets/icon.svg"}, - } { - url, err := Join(currTestElem.testParts...) - require.Equal(t, nil, err) - require.Equal(t, currTestElem.expectedJoined, url) - } - - elems := []string{"https://", "bitrise.io"} - url, err := Join(elems...) - require.Equal(t, "No Host defined", err.Error()) - require.Equal(t, "", url) - - elems = []string{} - url, err = Join(elems...) - require.Equal(t, "No elements defined to Join", err.Error()) - require.Equal(t, "", url) -} diff --git a/vendor/github.com/bitrise-io/go-utils/versions/versions.go b/vendor/github.com/bitrise-io/go-utils/versions/versions.go deleted file mode 100644 index 44811548..00000000 --- a/vendor/github.com/bitrise-io/go-utils/versions/versions.go +++ /dev/null @@ -1,100 +0,0 @@ -package versions - -import ( - "log" - "strconv" - "strings" -) - -// CompareVersions ... -// semantic version (X.Y.Z) -// 1 if version 2 is greater then version 1, -1 if not -// -2 & error if can't compare (if not supported component found) -func CompareVersions(version1, version2 string) (int, error) { - version1Slice := strings.Split(version1, ".") - version2Slice := strings.Split(version2, ".") - - lenDiff := len(version1Slice) - len(version2Slice) - if lenDiff != 0 { - makeDefVerComps := func(compLen int) []string { - comps := make([]string, compLen, compLen) - for idx := len(comps) - 1; idx >= 0; idx-- { - comps[idx] = "0" - } - return comps - } - if lenDiff > 0 { - // v1 slice is longer - version2Slice = append(version2Slice, makeDefVerComps(lenDiff)...) - } else { - // v2 slice is longer - version1Slice = append(version1Slice, makeDefVerComps(-lenDiff)...) - } - } - - cnt := len(version1Slice) - for i, num := range version1Slice { - num1, err := strconv.ParseInt(num, 0, 64) - if err != nil { - log.Println("Failed to parse int:", err) - return -2, err - } - - num2, err2 := strconv.ParseInt(version2Slice[i], 0, 64) - if err2 != nil { - log.Println("Failed to parse int:", err2) - return -2, err - } - - if num2 > num1 { - return 1, nil - } else if num2 < num1 { - return -1, nil - } - - if i == cnt-1 { - // last one - if num2 == num1 { - return 0, nil - } - } - } - return -1, nil -} - -// IsVersionBetween ... -// returns true if it's between the lower and upper limit -// or in case it matches the lower or the upper limit -func IsVersionBetween(verBase, verLower, verUpper string) (bool, error) { - r1, err := CompareVersions(verBase, verLower) - if err != nil { - return false, err - } - if r1 == 1 { - return false, nil - } - - r2, err := CompareVersions(verBase, verUpper) - if err != nil { - return false, err - } - if r2 == -1 { - return false, nil - } - - return true, nil -} - -// IsVersionGreaterOrEqual ... -// returns true if verBase is greater or equal to verLower -func IsVersionGreaterOrEqual(verBase, verLower string) (bool, error) { - r1, err := CompareVersions(verBase, verLower) - if err != nil { - return false, err - } - if r1 == 1 { - return false, nil - } - - return true, nil -} diff --git a/vendor/github.com/bitrise-io/go-utils/versions/versions_test.go b/vendor/github.com/bitrise-io/go-utils/versions/versions_test.go deleted file mode 100644 index 00e19876..00000000 --- a/vendor/github.com/bitrise-io/go-utils/versions/versions_test.go +++ /dev/null @@ -1,207 +0,0 @@ -package versions - -import ( - "testing" - - "github.com/bitrise-io/go-utils/testutil" -) - -func TestCompareVersions(t *testing.T) { - res, err := CompareVersions("1.0.0", "1.0.1") - testutil.EqualAndNoError(t, 1, res, err, "Trivial compare") - - res, err = CompareVersions("1.0.2", "1.0.1") - testutil.EqualAndNoError(t, -1, res, err, "Reverse compare") - - res, err = CompareVersions("1.0.2", "1.0.2") - testutil.EqualAndNoError(t, 0, res, err, "Equal compare") - - t.Log("1.0.0 <-> 0.9.8") - if res, err := CompareVersions("1.0.0", "0.9.8"); res != -1 || err != nil { - t.Fatal("Failed, res:", res, "| err:", err) - } - t.Log("0.9.8 <-> 1.0.0") - if res, err := CompareVersions("0.9.8", "1.0.0"); res != 1 || err != nil { - t.Fatal("Failed, res:", res, "| err:", err) - } - - t.Log("Missing last num in first") - if res, err := CompareVersions("7.0", "7.0.2"); res != 1 || err != nil { - t.Fatal("Failed, res:", res, "| err:", err) - } - t.Log("Missing last num in first - eql") - if res, err := CompareVersions("7.0", "7.0.0"); res != 0 || err != nil { - t.Fatal("Failed, res:", res, "| err:", err) - } - t.Log("Missing last num in second") - if res, err := CompareVersions("7.0.2", "7.0"); res != -1 || err != nil { - t.Fatal("Failed, res:", res, "| err:", err) - } - t.Log("Missing last num in second - eql") - if res, err := CompareVersions("7.0.0", "7.0"); res != 0 || err != nil { - t.Fatal("Failed, res:", res, "| err:", err) - } - t.Log("Missing double-last num in first") - if res, err := CompareVersions("7", "7.0.2"); res != 1 || err != nil { - t.Fatal("Failed, res:", res, "| err:", err) - } - t.Log("Missing double-last num in first - eql") - if res, err := CompareVersions("7", "7.0.0"); res != 0 || err != nil { - t.Fatal("Failed, res:", res, "| err:", err) - } - t.Log("Missing double-last num in second") - if res, err := CompareVersions("7.0.2", "7"); res != -1 || err != nil { - t.Fatal("Failed, res:", res, "| err:", err) - } - t.Log("Missing double-last num in second - eql") - if res, err := CompareVersions("7.0.0", "7"); res != 0 || err != nil { - t.Fatal("Failed, res:", res, "| err:", err) - } - - // specials are not handled but should not cause any issue / panic - t.Log("Special / non number component") - if res, err := CompareVersions("7.x.1.2.3", "7.0.1.x"); err == nil { - t.Fatal("Not supported compare should return an error!") - } else { - t.Log("[expected] Failed, res:", res, "| err:", err) - } -} - -func TestIsVersionGreaterOrEqual(t *testing.T) { - t.Log("Yes - Trivial") - isGreaterOrEql, err := IsVersionGreaterOrEqual("1.1", "1.0") - if err != nil { - t.Fatal("Unexpected error:", err) - } - if !isGreaterOrEql { - t.Fatal("Invalid result") - } - - t.Log("Yes - Trivial - eq") - isGreaterOrEql, err = IsVersionGreaterOrEqual("1.0", "1.0") - if err != nil { - t.Fatal("Unexpected error:", err) - } - if !isGreaterOrEql { - t.Fatal("Invalid result") - } - - t.Log("No - Trivial") - isGreaterOrEql, err = IsVersionGreaterOrEqual("1.0", "1.1") - if err != nil { - t.Fatal("Unexpected error:", err) - } - if isGreaterOrEql { - t.Fatal("Invalid result") - } - - t.Log("No - 1.0.0<->0.9.8") - isGreaterOrEql, err = IsVersionGreaterOrEqual("1.0.0", "0.9.8") - if err != nil { - t.Fatal("Unexpected error:", err) - } - if !isGreaterOrEql { - t.Fatal("Invalid result") - } - - t.Log("No - 0.9.8<->1.0.0") - isGreaterOrEql, err = IsVersionGreaterOrEqual("0.9.8", "1.0.0") - if err != nil { - t.Fatal("Unexpected error:", err) - } - if isGreaterOrEql { - t.Fatal("Invalid result") - } - - t.Log("Yes - bit more complex - eq") - isGreaterOrEql, err = IsVersionGreaterOrEqual("1.0.0", "1.0") - if err != nil { - t.Fatal("Unexpected error:", err) - } - if !isGreaterOrEql { - t.Fatal("Invalid result") - } - - t.Log("Yes - bit more complex") - isGreaterOrEql, err = IsVersionGreaterOrEqual("1.0.1", "1.0") - if err != nil { - t.Fatal("Unexpected error:", err) - } - if !isGreaterOrEql { - t.Fatal("Invalid result") - } - - t.Log("No - bit more complex") - isGreaterOrEql, err = IsVersionGreaterOrEqual("0.9.1", "1.0") - if err != nil { - t.Fatal("Unexpected error:", err) - } - if isGreaterOrEql { - t.Fatal("Invalid result") - } -} - -func TestIsVersionBetween(t *testing.T) { - t.Log("Yes - Trivial") - isBetween, err := IsVersionBetween("1.1", "1.0", "1.2") - if err != nil { - t.Fatal("Unexpected error:", err) - } - if !isBetween { - t.Fatal("Invalid result") - } - - t.Log("No - Trivial") - isBetween, err = IsVersionBetween("1.3", "1.0", "1.2") - if err != nil { - t.Fatal("Unexpected error:", err) - } - if isBetween { - t.Fatal("Invalid result") - } - - t.Log("Yes - eq lower") - isBetween, err = IsVersionBetween("1.0", "1.0", "1.2") - if err != nil { - t.Fatal("Unexpected error:", err) - } - if !isBetween { - t.Fatal("Invalid result") - } - - t.Log("Yes - eq upper") - isBetween, err = IsVersionBetween("1.2", "1.0", "1.2") - if err != nil { - t.Fatal("Unexpected error:", err) - } - if !isBetween { - t.Fatal("Invalid result") - } - - t.Log("Yes - Bit more complex") - isBetween, err = IsVersionBetween("1.0.1", "1.0", "1.2") - if err != nil { - t.Fatal("Unexpected error:", err) - } - if !isBetween { - t.Fatal("Invalid result") - } - - t.Log("Yes - Bit more complex - eq") - isBetween, err = IsVersionBetween("1.2.0", "1.0", "1.2") - if err != nil { - t.Fatal("Unexpected error:", err) - } - if !isBetween { - t.Fatal("Invalid result") - } - - t.Log("No - Bit more complex") - isBetween, err = IsVersionBetween("1.2.1", "1.0", "1.2") - if err != nil { - t.Fatal("Unexpected error:", err) - } - if isBetween { - t.Fatal("Invalid result") - } -} diff --git a/vendor/github.com/bitrise-io/go-utils/ziputil/ziputil_test.go b/vendor/github.com/bitrise-io/go-utils/ziputil/ziputil_test.go deleted file mode 100644 index bd0502dd..00000000 --- a/vendor/github.com/bitrise-io/go-utils/ziputil/ziputil_test.go +++ /dev/null @@ -1,214 +0,0 @@ -package ziputil - -import ( - "os" - "path/filepath" - "testing" - - "github.com/bitrise-io/go-utils/fileutil" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/stretchr/testify/require" -) - -func TestZip(t *testing.T) { - t.Log("create zip from file") - { - tmpDir, err := pathutil.NormalizedOSTempDirPath("test") - require.NoError(t, err) - - sourceFile := filepath.Join(tmpDir, "sourceFile") - require.NoError(t, fileutil.WriteStringToFile(sourceFile, "")) - - destinationZip := filepath.Join(tmpDir, "destinationFile.zip") - require.NoError(t, ZipFile(sourceFile, destinationZip)) - - exist, err := pathutil.IsPathExists(destinationZip) - require.NoError(t, err) - require.Equal(t, true, exist) - } - - t.Log("create zip from dir") - { - tmpDir, err := pathutil.NormalizedOSTempDirPath("test") - require.NoError(t, err) - - sourceDir := filepath.Join(tmpDir, "sourceDir") - require.NoError(t, os.MkdirAll(sourceDir, 0777)) - - destinationZip := filepath.Join(tmpDir, "destinationDir.zip") - require.NoError(t, ZipDir(sourceDir, destinationZip, false)) - - exist, err := pathutil.IsPathExists(destinationZip) - require.NoError(t, err) - require.Equal(t, true, exist, destinationZip) - } - - t.Log("zip content of dir") - { - tmpDir, err := pathutil.NormalizedOSTempDirPath("test") - require.NoError(t, err) - - contentOfDirToZip := filepath.Join(tmpDir, "source") - require.NoError(t, os.MkdirAll(contentOfDirToZip, 0777)) - - sourceDir := filepath.Join(contentOfDirToZip, "sourceDir") - require.NoError(t, os.MkdirAll(sourceDir, 0777)) - - sourceFile := filepath.Join(contentOfDirToZip, "sourceFile") - require.NoError(t, fileutil.WriteStringToFile(sourceFile, "")) - - destinationZip := filepath.Join(tmpDir, "destinationFile.zip") - require.NoError(t, ZipDir(contentOfDirToZip, destinationZip, true)) - } -} - -func TestUnZip(t *testing.T) { - t.Log("unzip zipped file") - { - tmpDir, err := pathutil.NormalizedOSTempDirPath("test") - require.NoError(t, err) - - // create file to zip tmp/source/sourceFile - contentOfDirToZip := filepath.Join(tmpDir, "source") - require.NoError(t, os.MkdirAll(contentOfDirToZip, 0777)) - - sourceFile := filepath.Join(contentOfDirToZip, "sourceFile") - require.NoError(t, fileutil.WriteStringToFile(sourceFile, "")) - - // create zip at tmp/destinationFile.zip - destinationZip := filepath.Join(tmpDir, "destinationFile.zip") - require.NoError(t, ZipFile(sourceFile, destinationZip)) - - // unzip into tmp/ - require.NoError(t, UnZip(destinationZip, tmpDir)) - - // tmp/sourceFile should exist - content, err := fileutil.ReadStringFromFile(filepath.Join(tmpDir, "sourceFile")) - require.NoError(t, err) - require.Equal(t, "", content) - } - - t.Log("unzip zipped dir") - { - tmpDir, err := pathutil.NormalizedOSTempDirPath("test") - require.NoError(t, err) - - // create dir to zip tmp/source/sourceDir - contentOfDirToZip := filepath.Join(tmpDir, "source") - require.NoError(t, os.MkdirAll(contentOfDirToZip, 0777)) - - sourceDir := filepath.Join(tmpDir, "sourceDir") - require.NoError(t, os.MkdirAll(sourceDir, 0777)) - - // create zip at tmp/destinationDir.zip - destinationZip := filepath.Join(contentOfDirToZip, "destinationDir.zip") - require.NoError(t, ZipDir(sourceDir, destinationZip, false)) - - // unzip into tmp/ - require.NoError(t, UnZip(destinationZip, tmpDir)) - - // tmp/sourceDir should exist - isDir, err := pathutil.IsDirExists(filepath.Join(tmpDir, "sourceDir")) - require.NoError(t, err) - require.Equal(t, true, isDir) - } - - t.Log("unzip zipped content of dir") - { - tmpDir, err := pathutil.NormalizedOSTempDirPath("test") - require.NoError(t, err) - - // create dir to zip tmp/source/sourceDir - contentOfDirToZip := filepath.Join(tmpDir, "source") - require.NoError(t, os.MkdirAll(contentOfDirToZip, 0777)) - - sourceDir := filepath.Join(contentOfDirToZip, "sourceDir") - require.NoError(t, os.MkdirAll(sourceDir, 0777)) - - // create file to zip tmp/source/sourceFile - sourceFile := filepath.Join(contentOfDirToZip, "sourceFile") - require.NoError(t, fileutil.WriteStringToFile(sourceFile, "")) - - // create zip at tmp/destinationDir.zip - destinationZip := filepath.Join(tmpDir, "destinationFile.zip") - require.NoError(t, ZipDir(contentOfDirToZip, destinationZip, true)) - - // remove tmp/source, since this path would be the unzip destination - require.NoError(t, os.RemoveAll(contentOfDirToZip)) - - // unzip into tmp/ - require.NoError(t, UnZip(destinationZip, tmpDir)) - - // tmp/sourceDir should exist - isDir, err := pathutil.IsDirExists(filepath.Join(tmpDir, "sourceDir")) - require.NoError(t, err) - require.Equal(t, true, isDir) - - // tmp/sourceFile should exist - content, err := fileutil.ReadStringFromFile(filepath.Join(tmpDir, "sourceFile")) - require.NoError(t, err) - require.Equal(t, "", content) - } - - t.Log("unzip into different dir") - { - // create zip at tmp dir (tmp1) - sourceTmpDir, err := pathutil.NormalizedOSTempDirPath("__1__") - require.NoError(t, err) - - sourceFile := filepath.Join(sourceTmpDir, "sourceFile") - require.NoError(t, fileutil.WriteStringToFile(sourceFile, "")) - - destinationZip := filepath.Join(sourceTmpDir, "destinationFile.zip") - require.NoError(t, ZipFile(sourceFile, destinationZip)) - // --- - - // unzip into another tmp dir (tmp2) - destTmpDir, err := pathutil.NormalizedOSTempDirPath("__2__") - require.NoError(t, err) - - require.NoError(t, UnZip(destinationZip, destTmpDir)) - exist, err := pathutil.IsPathExists(filepath.Join(destTmpDir, "sourceFile")) - require.NoError(t, err) - require.Equal(t, true, exist) - // --- - } - - t.Log("relative path") - { - // create zip at tmp dir (tmp1) - using relative path - sourceTmpDir, err := pathutil.NormalizedOSTempDirPath("__1__") - require.NoError(t, err) - - revokeFn, err := pathutil.RevokableChangeDir(sourceTmpDir) - require.NoError(t, err) - defer func() { - require.NoError(t, revokeFn()) - }() - - sourceFile := filepath.Join(sourceTmpDir, "sourceFile") - require.NoError(t, fileutil.WriteStringToFile(sourceFile, "")) - - require.NoError(t, ZipFile("./sourceFile", "./destinationFile.zip")) - // --- - - // unzip into the same tmp dir (tmp1) - require.NoError(t, UnZip("./destinationFile.zip", "./unzipped")) - exist, err := pathutil.IsPathExists("./unzipped/sourceFile") - require.NoError(t, err) - require.Equal(t, true, exist) - // --- - - // unzip into another tmp dir (tmp2) - destTmpDir, err := pathutil.NormalizedOSTempDirPath("__2__") - require.NoError(t, err) - - require.NoError(t, UnZip("./destinationFile.zip", destTmpDir)) - exist, err = pathutil.IsPathExists(filepath.Join(destTmpDir, "sourceFile")) - require.NoError(t, err) - require.Equal(t, true, exist) - - require.NoError(t, revokeFn()) - // --- - } -} diff --git a/vendor/github.com/bitrise-io/go-xcode/certificateutil/filter.go b/vendor/github.com/bitrise-io/go-xcode/certificateutil/filter.go new file mode 100644 index 00000000..0a55b41c --- /dev/null +++ b/vendor/github.com/bitrise-io/go-xcode/certificateutil/filter.go @@ -0,0 +1,34 @@ +package certificateutil + +// FilterCertificateInfoModelsByFilterFunc ... +func FilterCertificateInfoModelsByFilterFunc(certificates []CertificateInfoModel, filterFunc func(certificate CertificateInfoModel) bool) []CertificateInfoModel { + filteredCertificates := []CertificateInfoModel{} + + for _, certificate := range certificates { + if filterFunc(certificate) { + filteredCertificates = append(filteredCertificates, certificate) + } + } + + return filteredCertificates +} + +// FilterValidCertificateInfos ... +func FilterValidCertificateInfos(certificateInfos []CertificateInfoModel) []CertificateInfoModel { + certificateInfosByName := map[string]CertificateInfoModel{} + + for _, certificateInfo := range certificateInfos { + if certificateInfo.CheckValidity() == nil { + activeCertificate, ok := certificateInfosByName[certificateInfo.CommonName] + if !ok || certificateInfo.EndDate.After(activeCertificate.EndDate) { + certificateInfosByName[certificateInfo.CommonName] = certificateInfo + } + } + } + + validCertificates := []CertificateInfoModel{} + for _, validCertificate := range certificateInfosByName { + validCertificates = append(validCertificates, validCertificate) + } + return validCertificates +} diff --git a/vendor/github.com/bitrise-tools/go-xcode/certificateutil/innfo_model.go b/vendor/github.com/bitrise-io/go-xcode/certificateutil/info_model.go similarity index 59% rename from vendor/github.com/bitrise-tools/go-xcode/certificateutil/innfo_model.go rename to vendor/github.com/bitrise-io/go-xcode/certificateutil/info_model.go index e8a3f6a0..941bb488 100644 --- a/vendor/github.com/bitrise-tools/go-xcode/certificateutil/innfo_model.go +++ b/vendor/github.com/bitrise-io/go-xcode/certificateutil/info_model.go @@ -3,9 +3,12 @@ package certificateutil import ( "crypto/sha1" "crypto/x509" + "encoding/json" "fmt" "strings" "time" + + "github.com/bitrise-io/go-utils/log" ) // CertificateInfoModel ... @@ -22,18 +25,48 @@ type CertificateInfoModel struct { certificate x509.Certificate } +// String ... +func (info CertificateInfoModel) String() string { + printable := map[string]interface{}{} + printable["name"] = info.CommonName + printable["serial"] = info.Serial + printable["team"] = fmt.Sprintf("%s (%s)", info.TeamName, info.TeamID) + printable["expire"] = info.EndDate.String() + + errors := []string{} + if err := info.CheckValidity(); err != nil { + errors = append(errors, err.Error()) + } + if len(errors) > 0 { + printable["errors"] = errors + } + + data, err := json.MarshalIndent(printable, "", "\t") + if err != nil { + log.Errorf("Failed to marshal: %v, error: %s", printable, err) + return "" + } + + return string(data) +} + // CheckValidity ... -func (info CertificateInfoModel) CheckValidity() error { +func CheckValidity(certificate x509.Certificate) error { timeNow := time.Now() - if !timeNow.After(info.StartDate) { - return fmt.Errorf("Certificate is not yet valid - validity starts at: %s", info.StartDate) + if !timeNow.After(certificate.NotBefore) { + return fmt.Errorf("Certificate is not yet valid - validity starts at: %s", certificate.NotBefore) } - if !timeNow.Before(info.EndDate) { - return fmt.Errorf("Certificate is not valid anymore - validity ended at: %s", info.EndDate) + if !timeNow.Before(certificate.NotAfter) { + return fmt.Errorf("Certificate is not valid anymore - validity ended at: %s", certificate.NotAfter) } return nil } +// CheckValidity ... +func (info CertificateInfoModel) CheckValidity() error { + return CheckValidity(info.certificate) +} + // NewCertificateInfo ... func NewCertificateInfo(certificate x509.Certificate) CertificateInfoModel { fingerprint := sha1.Sum(certificate.Raw) @@ -82,22 +115,16 @@ func InstalledCodesigningCertificateInfos() ([]CertificateInfoModel, error) { return CertificateInfos(certificates), nil } -// FilterValidCertificateInfos ... -func FilterValidCertificateInfos(certificateInfos []CertificateInfoModel) []CertificateInfoModel { - certificateInfosByName := map[string]CertificateInfoModel{} - - for _, certificateInfo := range certificateInfos { - if certificateInfo.CheckValidity() == nil { - activeCertificate, ok := certificateInfosByName[certificateInfo.CommonName] - if !ok || certificateInfo.EndDate.After(activeCertificate.EndDate) { - certificateInfosByName[certificateInfo.CommonName] = certificateInfo - } - } +// InstalledInstallerCertificateInfos ... +func InstalledInstallerCertificateInfos() ([]CertificateInfoModel, error) { + certificates, err := InstalledMacAppStoreCertificates() + if err != nil { + return nil, err } - validCertificates := []CertificateInfoModel{} - for _, validCertificate := range certificateInfosByName { - validCertificates = append(validCertificates, validCertificate) - } - return validCertificates + installerCertificates := FilterCertificateInfoModelsByFilterFunc(CertificateInfos(certificates), func(cert CertificateInfoModel) bool { + return strings.Contains(cert.CommonName, "Installer") + }) + + return installerCertificates, nil } diff --git a/vendor/github.com/bitrise-tools/go-xcode/certificateutil/util.go b/vendor/github.com/bitrise-io/go-xcode/certificateutil/util.go similarity index 82% rename from vendor/github.com/bitrise-tools/go-xcode/certificateutil/util.go rename to vendor/github.com/bitrise-io/go-xcode/certificateutil/util.go index 03134b5c..3e450849 100644 --- a/vendor/github.com/bitrise-tools/go-xcode/certificateutil/util.go +++ b/vendor/github.com/bitrise-io/go-xcode/certificateutil/util.go @@ -86,6 +86,16 @@ func InstalledCodesigningCertificateNames() ([]string, error) { return installedCodesigningCertificateNamesFromOutput(out) } +// InstalledMacAppStoreCertificateNames ... +func InstalledMacAppStoreCertificateNames() ([]string, error) { + cmd := command.New("security", "find-identity", "-v", "-p", "macappstore") + out, err := cmd.RunAndReturnTrimmedCombinedOutput() + if err != nil { + return nil, commandError(cmd.PrintableCommandArgs(), out, err) + } + return installedCodesigningCertificateNamesFromOutput(out) +} + func normalizeFindCertificateOut(out string) ([]string, error) { certificateContents := []string{} pattern := `(?s)(-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----)` @@ -113,7 +123,19 @@ func InstalledCodesigningCertificates() ([]*x509.Certificate, error) { if err != nil { return nil, err } + return getInstalledCertificatesByNameSlice(certificateNames) +} + +// InstalledMacAppStoreCertificates ... +func InstalledMacAppStoreCertificates() ([]*x509.Certificate, error) { + certificateNames, err := InstalledMacAppStoreCertificateNames() + if err != nil { + return nil, err + } + return getInstalledCertificatesByNameSlice(certificateNames) +} +func getInstalledCertificatesByNameSlice(certificateNames []string) ([]*x509.Certificate, error) { certificates := []*x509.Certificate{} for _, name := range certificateNames { cmd := command.New("security", "find-certificate", "-c", name, "-p", "-a") diff --git a/vendor/github.com/bitrise-tools/go-xcode/exportoptions/appstore_options.go b/vendor/github.com/bitrise-io/go-xcode/exportoptions/appstore_options.go similarity index 84% rename from vendor/github.com/bitrise-tools/go-xcode/exportoptions/appstore_options.go rename to vendor/github.com/bitrise-io/go-xcode/exportoptions/appstore_options.go index b92e28f7..413cbe9d 100644 --- a/vendor/github.com/bitrise-tools/go-xcode/exportoptions/appstore_options.go +++ b/vendor/github.com/bitrise-io/go-xcode/exportoptions/appstore_options.go @@ -11,7 +11,9 @@ type AppStoreOptionsModel struct { TeamID string BundleIDProvisioningProfileMapping map[string]string SigningCertificate string + InstallerSigningCertificate string SigningStyle string + ICloudContainerEnvironment ICloudContainerEnvironment // for app-store exports UploadBitcode bool @@ -39,12 +41,18 @@ func (options AppStoreOptionsModel) Hash() map[string]interface{} { if options.UploadSymbols != UploadSymbolsDefault { hash[UploadSymbolsKey] = options.UploadSymbols } + if options.ICloudContainerEnvironment != "" { + hash[ICloudContainerEnvironmentKey] = options.ICloudContainerEnvironment + } if len(options.BundleIDProvisioningProfileMapping) > 0 { hash[ProvisioningProfilesKey] = options.BundleIDProvisioningProfileMapping } if options.SigningCertificate != "" { hash[SigningCertificateKey] = options.SigningCertificate } + if options.InstallerSigningCertificate != "" { + hash[InstallerSigningCertificateKey] = options.InstallerSigningCertificate + } if options.SigningStyle != "" { hash[SigningStyleKey] = options.SigningStyle } diff --git a/vendor/github.com/bitrise-tools/go-xcode/exportoptions/exportoptions.go b/vendor/github.com/bitrise-io/go-xcode/exportoptions/exportoptions.go similarity index 100% rename from vendor/github.com/bitrise-tools/go-xcode/exportoptions/exportoptions.go rename to vendor/github.com/bitrise-io/go-xcode/exportoptions/exportoptions.go diff --git a/vendor/github.com/bitrise-tools/go-xcode/exportoptions/non_appstore_options.go b/vendor/github.com/bitrise-io/go-xcode/exportoptions/non_appstore_options.go similarity index 90% rename from vendor/github.com/bitrise-tools/go-xcode/exportoptions/non_appstore_options.go rename to vendor/github.com/bitrise-io/go-xcode/exportoptions/non_appstore_options.go index 3cb25832..5cbfb4c8 100644 --- a/vendor/github.com/bitrise-tools/go-xcode/exportoptions/non_appstore_options.go +++ b/vendor/github.com/bitrise-io/go-xcode/exportoptions/non_appstore_options.go @@ -13,11 +13,11 @@ type NonAppStoreOptionsModel struct { BundleIDProvisioningProfileMapping map[string]string SigningCertificate string SigningStyle string + ICloudContainerEnvironment ICloudContainerEnvironment // for non app-store exports CompileBitcode bool EmbedOnDemandResourcesAssetPacksInBundle bool - ICloudContainerEnvironment ICloudContainerEnvironment Manifest Manifest OnDemandResourcesAssetPacksBaseURL string Thinning string @@ -29,8 +29,7 @@ func NewNonAppStoreOptions(method Method) NonAppStoreOptionsModel { Method: method, CompileBitcode: CompileBitcodeDefault, EmbedOnDemandResourcesAssetPacksInBundle: EmbedOnDemandResourcesAssetPacksInBundleDefault, - ICloudContainerEnvironment: ICloudContainerEnvironmentDefault, - Thinning: ThinningDefault, + Thinning: ThinningDefault, } } @@ -49,7 +48,7 @@ func (options NonAppStoreOptionsModel) Hash() map[string]interface{} { if options.EmbedOnDemandResourcesAssetPacksInBundle != EmbedOnDemandResourcesAssetPacksInBundleDefault { hash[EmbedOnDemandResourcesAssetPacksInBundleKey] = options.EmbedOnDemandResourcesAssetPacksInBundle } - if options.ICloudContainerEnvironment != ICloudContainerEnvironmentDefault { + if options.ICloudContainerEnvironment != "" { hash[ICloudContainerEnvironmentKey] = options.ICloudContainerEnvironment } if !options.Manifest.IsEmpty() { diff --git a/vendor/github.com/bitrise-tools/go-xcode/exportoptions/properties.go b/vendor/github.com/bitrise-io/go-xcode/exportoptions/properties.go similarity index 94% rename from vendor/github.com/bitrise-tools/go-xcode/exportoptions/properties.go rename to vendor/github.com/bitrise-io/go-xcode/exportoptions/properties.go index c24c93ec..7ab2a90c 100644 --- a/vendor/github.com/bitrise-tools/go-xcode/exportoptions/properties.go +++ b/vendor/github.com/bitrise-io/go-xcode/exportoptions/properties.go @@ -22,8 +22,6 @@ const ( ICloudContainerEnvironmentDevelopment ICloudContainerEnvironment = "Development" // ICloudContainerEnvironmentProduction ... ICloudContainerEnvironmentProduction ICloudContainerEnvironment = "Production" - // ICloudContainerEnvironmentDefault ... - ICloudContainerEnvironmentDefault ICloudContainerEnvironment = ICloudContainerEnvironmentDevelopment ) // ICloudContainerEnvironment ... @@ -79,8 +77,6 @@ func (manifest Manifest) ToHash() map[string]string { const MethodKey = "method" const ( - // MethodNone ... - MethodNone Method = "none" // MethodAppStore ... MethodAppStore Method = "app-store" // MethodAdHoc ... @@ -116,7 +112,7 @@ func ParseMethod(method string) (Method, error) { case "developer-id": return MethodDeveloperID, nil default: - return MethodNone, fmt.Errorf("unkown method (%s)", method) + return Method(""), fmt.Errorf("unkown method (%s)", method) } } @@ -156,5 +152,8 @@ const ProvisioningProfilesKey = "provisioningProfiles" // SigningCertificateKey ... const SigningCertificateKey = "signingCertificate" +// InstallerSigningCertificateKey ... +const InstallerSigningCertificateKey = "installerSigningCertificate" + // SigningStyleKey ... const SigningStyleKey = "signingStyle" diff --git a/vendor/github.com/bitrise-tools/go-xcode/ipa/ipa.go b/vendor/github.com/bitrise-io/go-xcode/ipa/ipa.go similarity index 97% rename from vendor/github.com/bitrise-tools/go-xcode/ipa/ipa.go rename to vendor/github.com/bitrise-io/go-xcode/ipa/ipa.go index b67f1018..16f173ca 100644 --- a/vendor/github.com/bitrise-tools/go-xcode/ipa/ipa.go +++ b/vendor/github.com/bitrise-io/go-xcode/ipa/ipa.go @@ -7,7 +7,7 @@ import ( "github.com/bitrise-io/go-utils/pathutil" "github.com/bitrise-io/go-utils/ziputil" - "github.com/bitrise-tools/go-xcode/utility" + "github.com/bitrise-io/go-xcode/utility" ) func findFileInPayloadAppDir(payloadPth, preferedAppName, fileName string) (string, error) { diff --git a/vendor/github.com/bitrise-tools/go-xcode/models/models.go b/vendor/github.com/bitrise-io/go-xcode/models/models.go similarity index 100% rename from vendor/github.com/bitrise-tools/go-xcode/models/models.go rename to vendor/github.com/bitrise-io/go-xcode/models/models.go diff --git a/vendor/github.com/bitrise-tools/go-xcode/plistutil/plistutil.go b/vendor/github.com/bitrise-io/go-xcode/plistutil/plistutil.go similarity index 75% rename from vendor/github.com/bitrise-tools/go-xcode/plistutil/plistutil.go rename to vendor/github.com/bitrise-io/go-xcode/plistutil/plistutil.go index e1993362..39691ca2 100644 --- a/vendor/github.com/bitrise-tools/go-xcode/plistutil/plistutil.go +++ b/vendor/github.com/bitrise-io/go-xcode/plistutil/plistutil.go @@ -1,6 +1,7 @@ package plistutil import ( + "errors" "time" "github.com/bitrise-io/go-utils/fileutil" @@ -57,6 +58,20 @@ func (data PlistData) GetUInt64(forKey string) (uint64, bool) { return casted, true } +// GetFloat64 ... +func (data PlistData) GetFloat64(forKey string) (float64, bool) { + value, ok := data[forKey] + if !ok { + return 0, false + } + + casted, ok := value.(float64) + if !ok { + return 0, false + } + return casted, true +} + // GetBool ... func (data PlistData) GetBool(forKey string) (bool, bool) { value, ok := data[forKey] @@ -182,3 +197,34 @@ func (data PlistData) GetMapStringInterface(forKey string) (PlistData, bool) { } return nil, false } + +func castToMapStringInterfaceArray(obj interface{}) ([]PlistData, error) { + array, ok := obj.([]interface{}) + if !ok { + return nil, errors.New("failed to cast to []interface{}") + } + + var casted []PlistData + for _, item := range array { + mapStringInterface, ok := item.(map[string]interface{}) + if !ok { + return nil, errors.New("failed to cast to map[string]interface{}") + } + casted = append(casted, mapStringInterface) + } + + return casted, nil +} + +// GetMapStringInterfaceArray ... +func (data PlistData) GetMapStringInterfaceArray(forKey string) ([]PlistData, bool) { + value, ok := data[forKey] + if !ok { + return nil, false + } + mapStringInterfaceArray, err := castToMapStringInterfaceArray(value) + if err != nil { + return nil, false + } + return mapStringInterfaceArray, true +} diff --git a/vendor/github.com/bitrise-tools/go-xcode/plistutil/plistutil_test_file_content.go b/vendor/github.com/bitrise-io/go-xcode/plistutil/plistutil_test_file_content.go similarity index 87% rename from vendor/github.com/bitrise-tools/go-xcode/plistutil/plistutil_test_file_content.go rename to vendor/github.com/bitrise-io/go-xcode/plistutil/plistutil_test_file_content.go index 2b0c2362..17f15038 100644 --- a/vendor/github.com/bitrise-tools/go-xcode/plistutil/plistutil_test_file_content.go +++ b/vendor/github.com/bitrise-io/go-xcode/plistutil/plistutil_test_file_content.go @@ -293,3 +293,39 @@ const enterpriseProfileContent = ` Version 1 ` + +const paritalTestSummariesContent = ` + + + + Duration + 0.34774100780487061 + Subtests + + + TestIdentifier + ios_simple_objcTests/testExample + TestStatus + Success + + + TestIdentifier + ios_simple_objcTests/testExample2 + TestStatus + Success + + + TestIdentifier + ios_simple_objcTests + TestName + ios_simple_objcTests + TestObjectClass + IDESchemeActionTestSummaryGroup + +TestIdentifier +ios-simple-objcTests.xctest +TestName +ios-simple-objcTests.xctest +TestObjectClass +IDESchemeActionTestSummaryGroup +` diff --git a/vendor/github.com/bitrise-io/go-xcode/profileutil/capabilities.go b/vendor/github.com/bitrise-io/go-xcode/profileutil/capabilities.go new file mode 100644 index 00000000..7bc709b3 --- /dev/null +++ b/vendor/github.com/bitrise-io/go-xcode/profileutil/capabilities.go @@ -0,0 +1,63 @@ +package profileutil + +import ( + "github.com/bitrise-io/go-xcode/plistutil" +) + +// MatchTargetAndProfileEntitlements ... +func MatchTargetAndProfileEntitlements(targetEntitlements plistutil.PlistData, profileEntitlements plistutil.PlistData, profileType ProfileType) []string { + missingEntitlements := []string{} + + for key := range targetEntitlements { + _, known := KnownProfileCapabilitiesMap[profileType][key] + if !known { + continue + } + _, found := profileEntitlements[key] + if !found { + missingEntitlements = append(missingEntitlements, key) + } + } + + return missingEntitlements +} + +// KnownProfileCapabilitiesMap ... +var KnownProfileCapabilitiesMap = map[ProfileType]map[string]bool{ + ProfileTypeMacOs: map[string]bool{ + "com.apple.developer.networking.networkextension": true, + "com.apple.developer.icloud-container-environment": true, + "com.apple.developer.icloud-container-development-container-identifiers": true, + "com.apple.developer.aps-environment": true, + "keychain-access-groups": true, + "com.apple.developer.icloud-services": true, + "com.apple.developer.icloud-container-identifiers": true, + "com.apple.developer.networking.vpn.api": true, + "com.apple.developer.ubiquity-kvstore-identifier": true, + "com.apple.developer.ubiquity-container-identifiers": true, + "com.apple.developer.game-center": true, + "com.apple.application-identifier": true, + "com.apple.developer.team-identifier": true, + "com.apple.developer.maps": true, + }, + ProfileTypeIos: map[string]bool{ + "com.apple.developer.in-app-payments": true, + "com.apple.security.application-groups": true, + "com.apple.developer.default-data-protection": true, + "com.apple.developer.healthkit": true, + "com.apple.developer.homekit": true, + "com.apple.developer.networking.HotspotConfiguration": true, + "inter-app-audio": true, + "keychain-access-groups": true, + "com.apple.developer.networking.multipath": true, + "com.apple.developer.nfc.readersession.formats": true, + "com.apple.developer.networking.networkextension": true, + "aps-environment": true, + "com.apple.developer.associated-domains": true, + "com.apple.developer.siri": true, + "com.apple.developer.networking.vpn.api": true, + "com.apple.external-accessory.wireless-configuration": true, + "com.apple.developer.pass-type-identifiers": true, + "com.apple.developer.icloud-container-identifiers": true, + }, +} diff --git a/vendor/github.com/bitrise-tools/go-xcode/profileutil/info_model.go b/vendor/github.com/bitrise-io/go-xcode/profileutil/info_model.go similarity index 61% rename from vendor/github.com/bitrise-tools/go-xcode/profileutil/info_model.go rename to vendor/github.com/bitrise-io/go-xcode/profileutil/info_model.go index 3ad13960..907f5c2a 100644 --- a/vendor/github.com/bitrise-tools/go-xcode/profileutil/info_model.go +++ b/vendor/github.com/bitrise-io/go-xcode/profileutil/info_model.go @@ -2,14 +2,16 @@ package profileutil import ( "crypto/x509" + "encoding/json" "errors" "fmt" "strings" "time" - "github.com/bitrise-tools/go-xcode/certificateutil" - "github.com/bitrise-tools/go-xcode/exportoptions" - "github.com/bitrise-tools/go-xcode/plistutil" + "github.com/bitrise-io/go-utils/log" + "github.com/bitrise-io/go-xcode/certificateutil" + "github.com/bitrise-io/go-xcode/exportoptions" + "github.com/bitrise-io/go-xcode/plistutil" "github.com/fullsailor/pkcs7" "howett.net/plist" ) @@ -28,11 +30,67 @@ type ProvisioningProfileInfoModel struct { ExpirationDate time.Time Entitlements plistutil.PlistData ProvisionsAllDevices bool + Type ProfileType +} + +// PrintableProvisioningProfileInfo ... +func (info ProvisioningProfileInfoModel) String(installedCertificates ...certificateutil.CertificateInfoModel) string { + printable := map[string]interface{}{} + printable["name"] = fmt.Sprintf("%s (%s)", info.Name, info.UUID) + printable["export_type"] = string(info.ExportType) + printable["team"] = fmt.Sprintf("%s (%s)", info.TeamName, info.TeamID) + printable["bundle_id"] = info.BundleID + printable["expire"] = info.ExpirationDate.String() + printable["is_xcode_managed"] = info.IsXcodeManaged() + if info.ProvisionedDevices != nil { + printable["devices"] = info.ProvisionedDevices + } + + certificates := []map[string]interface{}{} + for _, certificateInfo := range info.DeveloperCertificates { + certificate := map[string]interface{}{} + certificate["name"] = certificateInfo.CommonName + certificate["serial"] = certificateInfo.Serial + certificate["team_id"] = certificateInfo.TeamID + certificates = append(certificates, certificate) + } + printable["certificates"] = certificates + + errors := []string{} + if installedCertificates != nil && !info.HasInstalledCertificate(installedCertificates) { + errors = append(errors, "none of the profile's certificates are installed") + } + if err := info.CheckValidity(); err != nil { + errors = append(errors, err.Error()) + } + if len(errors) > 0 { + printable["errors"] = errors + } + + data, err := json.MarshalIndent(printable, "", "\t") + if err != nil { + log.Errorf("Failed to marshal: %v, error: %s", printable, err) + return "" + } + + return string(data) } // IsXcodeManaged ... func IsXcodeManaged(profileName string) bool { - return strings.HasPrefix(profileName, "XC") || (strings.HasPrefix(profileName, "iOS Team") && strings.Contains(profileName, "Provisioning Profile")) + if strings.HasPrefix(profileName, "XC") { + return true + } + if strings.HasPrefix(profileName, "iOS Team") && strings.Contains(profileName, "Provisioning Profile") { + return true + } + if strings.HasPrefix(profileName, "tvOS Team") && strings.Contains(profileName, "Provisioning Profile") { + return true + } + if strings.HasPrefix(profileName, "Mac Team") && strings.Contains(profileName, "Provisioning Profile") { + return true + } + return false } // IsXcodeManaged ... @@ -64,12 +122,20 @@ func (info ProvisioningProfileInfoModel) HasInstalledCertificate(installedCertif } // NewProvisioningProfileInfo ... -func NewProvisioningProfileInfo(provisioningProfile pkcs7.PKCS7, profileType ...ProfileType) (ProvisioningProfileInfoModel, error) { +func NewProvisioningProfileInfo(provisioningProfile pkcs7.PKCS7) (ProvisioningProfileInfoModel, error) { var data plistutil.PlistData if _, err := plist.Unmarshal(provisioningProfile.Content, &data); err != nil { return ProvisioningProfileInfoModel{}, err } + platform, _ := data.GetStringArray("Platform") + profileType := ProfileTypeMacOs + if len(platform) != 0 { + if strings.ToLower(platform[0]) == string(ProfileTypeIos) { + profileType = ProfileTypeIos + } + } + profile := PlistData(data) info := ProvisioningProfileInfoModel{ UUID: profile.GetUUID(), @@ -80,9 +146,10 @@ func NewProvisioningProfileInfo(provisioningProfile pkcs7.PKCS7, profileType ... CreationDate: profile.GetCreationDate(), ExpirationDate: profile.GetExpirationDate(), ProvisionsAllDevices: profile.GetProvisionsAllDevices(), + Type: profileType, } - info.ExportType = profile.GetExportMethod(profileType...) + info.ExportType = profile.GetExportMethod() if devicesList := profile.GetProvisionedDevices(); devicesList != nil { info.ProvisionedDevices = devicesList @@ -127,7 +194,7 @@ func InstalledProvisioningProfileInfos(profileType ProfileType) ([]ProvisioningP infos := []ProvisioningProfileInfoModel{} for _, provisioningProfile := range provisioningProfiles { if provisioningProfile != nil { - info, err := NewProvisioningProfileInfo(*provisioningProfile, profileType) + info, err := NewProvisioningProfileInfo(*provisioningProfile) if err != nil { return nil, err } diff --git a/vendor/github.com/bitrise-tools/go-xcode/profileutil/plist_data.go b/vendor/github.com/bitrise-io/go-xcode/profileutil/plist_data.go similarity index 83% rename from vendor/github.com/bitrise-tools/go-xcode/profileutil/plist_data.go rename to vendor/github.com/bitrise-io/go-xcode/profileutil/plist_data.go index 8ced74fd..4a4c5d19 100644 --- a/vendor/github.com/bitrise-tools/go-xcode/profileutil/plist_data.go +++ b/vendor/github.com/bitrise-io/go-xcode/profileutil/plist_data.go @@ -4,8 +4,8 @@ import ( "strings" "time" - "github.com/bitrise-tools/go-xcode/exportoptions" - "github.com/bitrise-tools/go-xcode/plistutil" + "github.com/bitrise-io/go-xcode/exportoptions" + "github.com/bitrise-io/go-xcode/plistutil" "howett.net/plist" ) @@ -80,11 +80,14 @@ func (profile PlistData) GetBundleIdentifier() string { } // GetExportMethod ... -func (profile PlistData) GetExportMethod(profileType ...ProfileType) exportoptions.Method { +func (profile PlistData) GetExportMethod() exportoptions.Method { data := plistutil.PlistData(profile) + entitlements, _ := data.GetMapStringInterface("Entitlements") + platform, _ := data.GetStringArray("Platform") - if len(profileType) > 0 { - if profileType[0] == ProfileTypeMacOs { + if len(platform) != 0 { + switch strings.ToLower(platform[0]) { + case "osx": _, ok := data.GetStringArray("ProvisionedDevices") if !ok { if allDevices, ok := data.GetBool("ProvisionsAllDevices"); ok && allDevices { @@ -93,25 +96,21 @@ func (profile PlistData) GetExportMethod(profileType ...ProfileType) exportoptio return exportoptions.MethodAppStore } return exportoptions.MethodDevelopment + case "ios", "tvos": + _, ok := data.GetStringArray("ProvisionedDevices") + if !ok { + if allDevices, ok := data.GetBool("ProvisionsAllDevices"); ok && allDevices { + return exportoptions.MethodEnterprise + } + return exportoptions.MethodAppStore + } + if allow, ok := entitlements.GetBool("get-task-allow"); ok && allow { + return exportoptions.MethodDevelopment + } + return exportoptions.MethodAdHoc } } - _, ok := data.GetStringArray("ProvisionedDevices") - if !ok { - if allDevices, ok := data.GetBool("ProvisionsAllDevices"); ok && allDevices { - return exportoptions.MethodEnterprise - } - return exportoptions.MethodAppStore - } - - entitlements, ok := data.GetMapStringInterface("Entitlements") - if ok { - if allow, ok := entitlements.GetBool("get-task-allow"); ok && allow { - return exportoptions.MethodDevelopment - } - return exportoptions.MethodAdHoc - } - return exportoptions.MethodDefault } diff --git a/vendor/github.com/bitrise-tools/go-xcode/profileutil/util.go b/vendor/github.com/bitrise-io/go-xcode/profileutil/util.go similarity index 95% rename from vendor/github.com/bitrise-tools/go-xcode/profileutil/util.go rename to vendor/github.com/bitrise-io/go-xcode/profileutil/util.go index e29bda85..e39de140 100644 --- a/vendor/github.com/bitrise-tools/go-xcode/profileutil/util.go +++ b/vendor/github.com/bitrise-io/go-xcode/profileutil/util.go @@ -5,6 +5,7 @@ import ( "github.com/bitrise-io/go-utils/fileutil" "github.com/bitrise-io/go-utils/pathutil" + "github.com/bitrise-io/go-xcode/utility" "github.com/fullsailor/pkcs7" ) @@ -46,7 +47,7 @@ func InstalledProvisioningProfiles(profileType ProfileType) ([]*pkcs7.PKCS7, err return nil, err } - pattern := filepath.Join(absProvProfileDirPath, "*"+ext) + pattern := filepath.Join(utility.EscapeGlobPath(absProvProfileDirPath), "*"+ext) pths, err := filepath.Glob(pattern) if err != nil { return nil, err diff --git a/vendor/github.com/bitrise-io/go-xcode/utility/glob.go b/vendor/github.com/bitrise-io/go-xcode/utility/glob.go new file mode 100644 index 00000000..1333c6f4 --- /dev/null +++ b/vendor/github.com/bitrise-io/go-xcode/utility/glob.go @@ -0,0 +1,13 @@ +package utility + +// EscapeGlobPath escapes a partial path, determined at runtime, used as a parameter for filepath.Glob +func EscapeGlobPath(path string) string { + var escaped string + for _, ch := range path { + if ch == '[' || ch == ']' || ch == '-' || ch == '*' || ch == '?' || ch == '\\' { + escaped += "\\" + } + escaped += string(ch) + } + return escaped +} diff --git a/vendor/github.com/bitrise-tools/go-xcode/utility/path.go b/vendor/github.com/bitrise-io/go-xcode/utility/path.go similarity index 100% rename from vendor/github.com/bitrise-tools/go-xcode/utility/path.go rename to vendor/github.com/bitrise-io/go-xcode/utility/path.go diff --git a/vendor/github.com/bitrise-tools/go-xcode/utility/utility.go b/vendor/github.com/bitrise-io/go-xcode/utility/utility.go similarity index 97% rename from vendor/github.com/bitrise-tools/go-xcode/utility/utility.go rename to vendor/github.com/bitrise-io/go-xcode/utility/utility.go index c9f94c6e..5d605c59 100644 --- a/vendor/github.com/bitrise-tools/go-xcode/utility/utility.go +++ b/vendor/github.com/bitrise-io/go-xcode/utility/utility.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-tools/go-xcode/models" + "github.com/bitrise-io/go-xcode/models" ) func getXcodeVersionFromXcodebuildOutput(outStr string) (models.XcodebuildVersionModel, error) { diff --git a/vendor/github.com/bitrise-io/stepman/LICENSE b/vendor/github.com/bitrise-io/stepman/LICENSE new file mode 100644 index 00000000..a6a5c39a --- /dev/null +++ b/vendor/github.com/bitrise-io/stepman/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Bitrise + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/bitrise-io/stepman/_tests/integration/test-step/LICENSE b/vendor/github.com/bitrise-io/stepman/_tests/integration/test-step/LICENSE new file mode 100755 index 00000000..121e544d --- /dev/null +++ b/vendor/github.com/bitrise-io/stepman/_tests/integration/test-step/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 bitrise-steplib + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/vendor/github.com/bitrise-io/stepman/models/models.go b/vendor/github.com/bitrise-io/stepman/models/models.go new file mode 100644 index 00000000..e68b2549 --- /dev/null +++ b/vendor/github.com/bitrise-io/stepman/models/models.go @@ -0,0 +1,190 @@ +package models + +import ( + "time" + + envmanModels "github.com/bitrise-io/envman/models" +) + +// StepSourceModel ... +type StepSourceModel struct { + Git string `json:"git,omitempty" yaml:"git,omitempty"` + Commit string `json:"commit,omitempty" yaml:"commit,omitempty"` +} + +// DependencyModel ... +type DependencyModel struct { + Manager string `json:"manager,omitempty" yaml:"manager,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} + +// BrewDepModel ... +type BrewDepModel struct { + // Name is the package name for Brew + Name string `json:"name,omitempty" yaml:"name,omitempty"` + // BinName is the binary's name, if it doesn't match the package's name. + // Can be used for e.g. calling `which`. + // E.g. in case of "AWS CLI" the package is `awscli` and the binary is `aws`. + // If BinName is empty Name will be used as BinName too. + BinName string `json:"bin_name,omitempty" yaml:"bin_name,omitempty"` +} + +// AptGetDepModel ... +type AptGetDepModel struct { + // Name is the package name for Apt-get + Name string `json:"name,omitempty" yaml:"name,omitempty"` + // BinName is the binary's name, if it doesn't match the package's name. + // Can be used for e.g. calling `which`. + // E.g. in case of "AWS CLI" the package is `awscli` and the binary is `aws`. + // If BinName is empty Name will be used as BinName too. + BinName string `json:"bin_name,omitempty" yaml:"bin_name,omitempty"` +} + +// CheckOnlyDepModel ... +type CheckOnlyDepModel struct { + Name string `json:"name,omitempty" yaml:"name,omitempty"` +} + +// DepsModel ... +type DepsModel struct { + Brew []BrewDepModel `json:"brew,omitempty" yaml:"brew,omitempty"` + AptGet []AptGetDepModel `json:"apt_get,omitempty" yaml:"apt_get,omitempty"` + CheckOnly []CheckOnlyDepModel `json:"check_only,omitempty" yaml:"check_only,omitempty"` +} + +// BashStepToolkitModel ... +type BashStepToolkitModel struct { + EntryFile string `json:"entry_file,omitempty" yaml:"entry_file,omitempty"` +} + +// GoStepToolkitModel ... +type GoStepToolkitModel struct { + // PackageName - required + PackageName string `json:"package_name" yaml:"package_name"` +} + +// StepToolkitModel ... +type StepToolkitModel struct { + Bash *BashStepToolkitModel `json:"bash,omitempty" yaml:"bash,omitempty"` + Go *GoStepToolkitModel `json:"go,omitempty" yaml:"go,omitempty"` +} + +// StepModel ... +type StepModel struct { + Title *string `json:"title,omitempty" yaml:"title,omitempty"` + Summary *string `json:"summary,omitempty" yaml:"summary,omitempty"` + Description *string `json:"description,omitempty" yaml:"description,omitempty"` + // + Website *string `json:"website,omitempty" yaml:"website,omitempty"` + SourceCodeURL *string `json:"source_code_url,omitempty" yaml:"source_code_url,omitempty"` + SupportURL *string `json:"support_url,omitempty" yaml:"support_url,omitempty"` + // auto-generated at share + PublishedAt *time.Time `json:"published_at,omitempty" yaml:"published_at,omitempty"` + Source *StepSourceModel `json:"source,omitempty" yaml:"source,omitempty"` + AssetURLs map[string]string `json:"asset_urls,omitempty" yaml:"asset_urls,omitempty"` + // + HostOsTags []string `json:"host_os_tags,omitempty" yaml:"host_os_tags,omitempty"` + ProjectTypeTags []string `json:"project_type_tags,omitempty" yaml:"project_type_tags,omitempty"` + TypeTags []string `json:"type_tags,omitempty" yaml:"type_tags,omitempty"` + Dependencies []DependencyModel `json:"dependencies,omitempty" yaml:"dependencies,omitempty"` + Toolkit *StepToolkitModel `json:"toolkit,omitempty" yaml:"toolkit,omitempty"` + Deps *DepsModel `json:"deps,omitempty" yaml:"deps,omitempty"` + IsRequiresAdminUser *bool `json:"is_requires_admin_user,omitempty" yaml:"is_requires_admin_user,omitempty"` + // IsAlwaysRun : if true then this step will always run, + // even if a previous step fails. + IsAlwaysRun *bool `json:"is_always_run,omitempty" yaml:"is_always_run,omitempty"` + // IsSkippable : if true and this step fails the build will still continue. + // If false then the build will be marked as failed and only those + // steps will run which are marked with IsAlwaysRun. + IsSkippable *bool `json:"is_skippable,omitempty" yaml:"is_skippable,omitempty"` + // RunIf : only run the step if the template example evaluates to true + RunIf *string `json:"run_if,omitempty" yaml:"run_if,omitempty"` + Timeout *int `json:"timeout,omitempty" yaml:"timeout,omitempty"` + Meta map[string]interface{} `json:"meta,omitempty" yaml:"meta,omitempty"` + // + Inputs []envmanModels.EnvironmentItemModel `json:"inputs,omitempty" yaml:"inputs,omitempty"` + Outputs []envmanModels.EnvironmentItemModel `json:"outputs,omitempty" yaml:"outputs,omitempty"` +} + +// StepVersionModel ... +type StepVersionModel struct { + Step StepModel + Version string + LatestAvailableVersion string +} + +// StepGroupInfoModel ... +type StepGroupInfoModel struct { + RemovalDate string `json:"removal_date,omitempty" yaml:"removal_date,omitempty"` + DeprecateNotes string `json:"deprecate_notes,omitempty" yaml:"deprecate_notes,omitempty"` + AssetURLs map[string]string `json:"asset_urls,omitempty" yaml:"asset_urls,omitempty"` +} + +// StepGroupModel ... +type StepGroupModel struct { + Info StepGroupInfoModel `json:"info,omitempty" yaml:"info,omitempty"` + LatestVersionNumber string `json:"latest_version_number,omitempty" yaml:"latest_version_number,omitempty"` + Versions map[string]StepModel `json:"versions,omitempty" yaml:"versions,omitempty"` +} + +// LatestVersion ... +func (stepGroup StepGroupModel) LatestVersion() (StepModel, bool) { + step, found := stepGroup.Versions[stepGroup.LatestVersionNumber] + if !found { + return StepModel{}, false + } + return step, true +} + +// StepHash ... +type StepHash map[string]StepGroupModel + +// DownloadLocationModel ... +type DownloadLocationModel struct { + Type string `json:"type"` + Src string `json:"src"` +} + +// StepCollectionModel ... +type StepCollectionModel struct { + FormatVersion string `json:"format_version" yaml:"format_version"` + GeneratedAtTimeStamp int64 `json:"generated_at_timestamp" yaml:"generated_at_timestamp"` + SteplibSource string `json:"steplib_source" yaml:"steplib_source"` + DownloadLocations []DownloadLocationModel `json:"download_locations" yaml:"download_locations"` + AssetsDownloadBaseURI string `json:"assets_download_base_uri" yaml:"assets_download_base_uri"` + Steps StepHash `json:"steps" yaml:"steps"` +} + +// EnvInfoModel ... +type EnvInfoModel struct { + Key string `json:"key,omitempty" yaml:"key,omitempty"` + Title string `json:"title,omitempty" yaml:"title,omitempty"` + Description string `json:"description,omitempty" yaml:"description,omitempty"` + ValueOptions []string `json:"value_options,omitempty" yaml:"value_options,omitempty"` + DefaultValue string `json:"default_value,omitempty" yaml:"default_value,omitempty"` + IsExpand bool `json:"is_expand" yaml:"is_expand"` + IsSensitive bool `json:"is_sensitive" yaml:"is_sensitive"` +} + +// StepInfoModel ... +type StepInfoModel struct { + Library string `json:"library,omitempty" yaml:"library,omitempty"` + ID string `json:"id,omitempty" yaml:"id,omitempty"` + Version string `json:"version,omitempty" yaml:"version,omitempty"` + LatestVersion string `json:"latest_version,omitempty" yaml:"latest_version,omitempty"` + GroupInfo StepGroupInfoModel `json:"info,omitempty" yaml:"info,omitempty"` + Step StepModel `json:"step,omitempty" yaml:"step,omitempty"` + DefinitionPth string `json:"definition_pth,omitempty" yaml:"definition_pth,omitempty"` +} + +// StepListModel ... +type StepListModel struct { + StepLib string `json:"steplib,omitempty" yaml:"steplib,omitempty"` + Steps []string `json:"steps,omitempty" yaml:"steps,omitempty"` +} + +// SteplibInfoModel ... +type SteplibInfoModel struct { + URI string `json:"uri,omitempty" yaml:"uri,omitempty"` + SpecPath string `json:"spec_path,omitempty" yaml:"spec_path,omitempty"` +} diff --git a/vendor/github.com/bitrise-io/stepman/models/models_methods.go b/vendor/github.com/bitrise-io/stepman/models/models_methods.go new file mode 100644 index 00000000..3a849ba8 --- /dev/null +++ b/vendor/github.com/bitrise-io/stepman/models/models_methods.go @@ -0,0 +1,350 @@ +package models + +import ( + "encoding/json" + "errors" + "fmt" + "strings" + "time" + + envmanModels "github.com/bitrise-io/envman/models" + "github.com/bitrise-io/go-utils/colorstring" + "github.com/bitrise-io/go-utils/fileutil" + "github.com/bitrise-io/go-utils/pointers" +) + +const ( + // DefaultIsAlwaysRun ... + DefaultIsAlwaysRun = false + // DefaultIsRequiresAdminUser ... + DefaultIsRequiresAdminUser = false + // DefaultIsSkippable ... + DefaultIsSkippable = false + // DefaultTimeout ... + DefaultTimeout = 0 +) + +// String ... +func (stepInfo StepInfoModel) String() string { + str := "" + if stepInfo.GroupInfo.DeprecateNotes != "" { + str += colorstring.Red("This step is deprecated") + + if stepInfo.GroupInfo.RemovalDate != "" { + str += colorstring.Redf(" and will be removed: %s", stepInfo.GroupInfo.RemovalDate) + } + str += "\n" + } + str += fmt.Sprintf("%s %s\n", colorstring.Blue("Library:"), stepInfo.Library) + str += fmt.Sprintf("%s %s\n", colorstring.Blue("ID:"), stepInfo.ID) + str += fmt.Sprintf("%s %s\n", colorstring.Blue("Version:"), stepInfo.Version) + str += fmt.Sprintf("%s %s\n", colorstring.Blue("LatestVersion:"), stepInfo.LatestVersion) + str += fmt.Sprintf("%s\n\n", colorstring.Blue("Definition:")) + + definition, err := fileutil.ReadStringFromFile(stepInfo.DefinitionPth) + if err != nil { + str += colorstring.Redf("Failed to read step definition, error: %s", err) + return str + } + + str += definition + return str +} + +// JSON ... +func (stepInfo StepInfoModel) JSON() string { + bytes, err := json.Marshal(stepInfo) + if err != nil { + return fmt.Sprintf(`"Failed to marshal step info (%#v), err: %s"`, stepInfo, err) + } + return string(bytes) +} + +// CreateFromJSON ... +func (stepInfo StepInfoModel) CreateFromJSON(jsonStr string) (StepInfoModel, error) { + info := StepInfoModel{} + if err := json.Unmarshal([]byte(jsonStr), &info); err != nil { + return StepInfoModel{}, err + } + return info, nil +} + +// ValidateSource ... +func (source StepSourceModel) validateSource() error { + if source.Git == "" { + return errors.New("Invalid step: missing or empty required 'source.git' property") + } + + if !strings.HasPrefix(source.Git, "http://") && !strings.HasPrefix(source.Git, "https://") { + return errors.New("Invalid step: step source should start with http:// or https://") + } + if !strings.HasSuffix(source.Git, ".git") { + return errors.New("Invalid step: step source should end with .git") + } + + if source.Commit == "" { + return errors.New("Invalid step: missing or empty required 'source.commit' property") + } + return nil +} + +// Normalize ... +func (step *StepModel) Normalize() error { + for _, input := range step.Inputs { + if err := input.Normalize(); err != nil { + return err + } + } + + for _, output := range step.Outputs { + if err := output.Normalize(); err != nil { + return err + } + } + + normalizedMeta, err := JSONMarshallable(step.Meta) + if err != nil { + return err + } + step.Meta = normalizedMeta + + return nil +} + +// ValidateInputAndOutputEnvs ... +func (step *StepModel) ValidateInputAndOutputEnvs(checkRequiredFields bool) error { + validateEnvs := func(envs []envmanModels.EnvironmentItemModel) error { + for _, env := range envs { + key, _, err := env.GetKeyValuePair() + if err != nil { + return fmt.Errorf("Invalid environment (%v), err: %s", env, err) + } + + if err := env.Validate(); err != nil { + return fmt.Errorf("Invalid environment (%s), err: %s", key, err) + } + + if checkRequiredFields { + options, err := env.GetOptions() + if err != nil { + return fmt.Errorf("Invalid environment (%s), err: %s", key, err) + } + + if options.Title == nil || *options.Title == "" { + return fmt.Errorf("Invalid environment (%s), err: missing or empty title", key) + } + + isSensitive := options.IsSensitive + if isSensitive == nil { + isSensitive = pointers.NewBoolPtr(envmanModels.DefaultIsSensitive) + } + + isExpand := options.IsExpand + if isExpand == nil { + isExpand = pointers.NewBoolPtr(envmanModels.DefaultIsExpand) + } + + if *isSensitive && !(*isExpand) { + return fmt.Errorf("Invalid environment (%s), err: is_sensitive option is true but is_expand option is not. For sensitive inputs direct value is not allowed", key) + } + } + } + return nil + } + + return validateEnvs(append(step.Inputs, step.Outputs...)) +} + +// AuditBeforeShare ... +func (step *StepModel) AuditBeforeShare() error { + if step.Title == nil || *step.Title == "" { + return errors.New("Invalid step: missing or empty required 'title' property") + } + if step.Summary == nil || *step.Summary == "" { + return errors.New("Invalid step: missing or empty required 'summary' property") + } + if step.Website == nil || *step.Website == "" { + return errors.New("Invalid step: missing or empty required 'website' property") + } + + if step.Timeout != nil && *step.Timeout < 0 { + return errors.New("Invalid step: timeout less then 0") + } + + return step.ValidateInputAndOutputEnvs(true) +} + +// Audit ... +func (step *StepModel) Audit() error { + if err := step.AuditBeforeShare(); err != nil { + return err + } + + if step.PublishedAt == nil || (*step.PublishedAt).Equal(time.Time{}) { + return errors.New("Invalid step: missing or empty required 'PublishedAt' property") + } + if step.Source == nil { + return errors.New("Invalid step: missing or empty required 'Source' property") + } + return step.Source.validateSource() +} + +// FillMissingDefaults ... +func (step *StepModel) FillMissingDefaults() error { + if step.Title == nil { + step.Title = pointers.NewStringPtr("") + } + if step.Description == nil { + step.Description = pointers.NewStringPtr("") + } + if step.Summary == nil { + step.Summary = pointers.NewStringPtr("") + } + if step.Website == nil { + step.Website = pointers.NewStringPtr("") + } + if step.SourceCodeURL == nil { + step.SourceCodeURL = pointers.NewStringPtr("") + } + if step.SupportURL == nil { + step.SupportURL = pointers.NewStringPtr("") + } + if step.IsRequiresAdminUser == nil { + step.IsRequiresAdminUser = pointers.NewBoolPtr(DefaultIsRequiresAdminUser) + } + if step.IsAlwaysRun == nil { + step.IsAlwaysRun = pointers.NewBoolPtr(DefaultIsAlwaysRun) + } + if step.IsSkippable == nil { + step.IsSkippable = pointers.NewBoolPtr(DefaultIsSkippable) + } + if step.RunIf == nil { + step.RunIf = pointers.NewStringPtr("") + } + if step.Timeout == nil { + step.Timeout = pointers.NewIntPtr(DefaultTimeout) + } + + for _, input := range step.Inputs { + err := input.FillMissingDefaults() + if err != nil { + return err + } + } + for _, output := range step.Outputs { + err := output.FillMissingDefaults() + if err != nil { + return err + } + } + return nil +} + +// IsStepExist ... +func (collection StepCollectionModel) IsStepExist(id, version string) bool { + _, stepFound, versionFound := collection.GetStep(id, version) + return (stepFound && versionFound) +} + +// GetStep ... +func (collection StepCollectionModel) GetStep(id, version string) (StepModel, bool, bool) { + stepVer, isStepFound, isVersionFound := collection.GetStepVersion(id, version) + return stepVer.Step, isStepFound, isVersionFound +} + +// GetStepVersion ... +func (collection StepCollectionModel) GetStepVersion(id, version string) (StepVersionModel, bool, bool) { + stepHash := collection.Steps + stepVersions, stepFound := stepHash[id] + + if !stepFound { + return StepVersionModel{}, stepFound, false + } + + if version == "" { + version = stepVersions.LatestVersionNumber + } + + step, versionFound := stepVersions.Versions[version] + + if !stepFound || !versionFound { + return StepVersionModel{}, stepFound, versionFound + } + + return StepVersionModel{ + Step: step, + Version: version, + LatestAvailableVersion: stepVersions.LatestVersionNumber, + }, true, true +} + +// GetDownloadLocations ... +func (collection StepCollectionModel) GetDownloadLocations(id, version string) ([]DownloadLocationModel, error) { + step, stepFound, versionFound := collection.GetStep(id, version) + if !stepFound { + return []DownloadLocationModel{}, fmt.Errorf("Collection (%s) doesn't contains step with id: %s", collection.SteplibSource, id) + } + if !versionFound { + return []DownloadLocationModel{}, fmt.Errorf("Collection (%s) doesn't contains step (%s) with version: %s", collection.SteplibSource, id, version) + } + + if step.Source == nil { + return []DownloadLocationModel{}, errors.New("Missing Source property") + } + + locations := []DownloadLocationModel{} + for _, downloadLocation := range collection.DownloadLocations { + switch downloadLocation.Type { + case "zip": + url := downloadLocation.Src + id + "/" + version + "/step.zip" + location := DownloadLocationModel{ + Type: downloadLocation.Type, + Src: url, + } + locations = append(locations, location) + case "git": + location := DownloadLocationModel{ + Type: downloadLocation.Type, + Src: step.Source.Git, + } + locations = append(locations, location) + default: + return []DownloadLocationModel{}, fmt.Errorf("Invalid download location (%#v) for step (%#v)", downloadLocation, id) + } + } + if len(locations) < 1 { + return []DownloadLocationModel{}, fmt.Errorf("No download location found for step (%#v)", id) + } + return locations, nil +} + +// GetLatestStepVersion ... +func (collection StepCollectionModel) GetLatestStepVersion(id string) (string, error) { + stepHash := collection.Steps + stepGroup, found := stepHash[id] + if !found { + return "", fmt.Errorf("Collection (%s) doesn't contains step (%s)", collection.SteplibSource, id) + } + + if stepGroup.LatestVersionNumber == "" { + return "", fmt.Errorf("Failed to find latest version of step %s", id) + } + + return stepGroup.LatestVersionNumber, nil +} + +// GetBinaryName ... +func (brewDep BrewDepModel) GetBinaryName() string { + if brewDep.BinName != "" { + return brewDep.BinName + } + return brewDep.Name +} + +// GetBinaryName ... +func (aptGetDep AptGetDepModel) GetBinaryName() string { + if aptGetDep.BinName != "" { + return aptGetDep.BinName + } + return aptGetDep.Name +} diff --git a/vendor/github.com/bitrise-io/stepman/models/parse_util.go b/vendor/github.com/bitrise-io/stepman/models/parse_util.go new file mode 100644 index 00000000..88f75278 --- /dev/null +++ b/vendor/github.com/bitrise-io/stepman/models/parse_util.go @@ -0,0 +1,64 @@ +package models + +import ( + "fmt" +) + +// JSONMarshallable replaces map[interface{}]interface{} with map[string]string recursively +// map[interface{}]interface{} is usually returned by parser go-yaml/v2 +func JSONMarshallable(source map[string]interface{}) (map[string]interface{}, error) { + target, err := recursiveJSONMarshallable(source) + if err != nil { + return nil, err + } + castedTarget, ok := target.(map[string]interface{}) + if !ok { + return nil, fmt.Errorf("could not cast to map[string]interface{}") + } + return castedTarget, nil +} + +func recursiveJSONMarshallable(source interface{}) (interface{}, error) { + if array, ok := source.([]interface{}); ok { + var convertedArray []interface{} + for _, element := range array { + convertedValue, err := recursiveJSONMarshallable(element) + if err != nil { + return nil, err + } + convertedArray = append(convertedArray, convertedValue) + } + return convertedArray, nil + } + + if interfaceToInterfaceMap, ok := source.(map[interface{}]interface{}); ok { + target := map[string]interface{}{} + for key, value := range interfaceToInterfaceMap { + strKey, ok := key.(string) + if !ok { + return nil, fmt.Errorf("failed to convert map key from type interface{} to string") + } + + convertedValue, err := recursiveJSONMarshallable(value) + if err != nil { + return nil, err + } + target[strKey] = convertedValue + } + return target, nil + } + + if stringToInterfaceMap, ok := source.(map[string]interface{}); ok { + target := map[string]interface{}{} + for key, value := range stringToInterfaceMap { + convertedValue, err := recursiveJSONMarshallable(value) + if err != nil { + return nil, err + } + target[key] = convertedValue + } + return target, nil + } + + return source, nil +} diff --git a/vendor/github.com/bitrise-tools/go-android/.gitignore b/vendor/github.com/bitrise-tools/go-android/.gitignore deleted file mode 100644 index 299858c3..00000000 --- a/vendor/github.com/bitrise-tools/go-android/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.gows* -.bitrise* diff --git a/vendor/github.com/bitrise-tools/go-android/README.md b/vendor/github.com/bitrise-tools/go-android/README.md deleted file mode 100644 index 14610027..00000000 --- a/vendor/github.com/bitrise-tools/go-android/README.md +++ /dev/null @@ -1 +0,0 @@ -# go-android diff --git a/vendor/github.com/bitrise-tools/go-android/_tests/integration/integration_test.go b/vendor/github.com/bitrise-tools/go-android/_tests/integration/integration_test.go deleted file mode 100644 index 8460d60a..00000000 --- a/vendor/github.com/bitrise-tools/go-android/_tests/integration/integration_test.go +++ /dev/null @@ -1,338 +0,0 @@ -package integration - -import ( - "bufio" - "fmt" - "path/filepath" - "regexp" - "strings" - "testing" - "time" - - "os" - - "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-io/go-utils/log" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/bitrise-io/go-utils/sliceutil" - "github.com/bitrise-tools/go-android/adbmanager" - "github.com/bitrise-tools/go-android/avdmanager" - "github.com/bitrise-tools/go-android/emulatormanager" - "github.com/bitrise-tools/go-android/sdk" - "github.com/bitrise-tools/go-android/sdkcomponent" - "github.com/bitrise-tools/go-android/sdkmanager" - "github.com/stretchr/testify/require" -) - -const ( - testEmulatorName = "test_emu_name" - testEmulatorSkin = "768x1280" -) - -type emulator struct { - platform string - tag string - abi string - runOptions []string - isSupportedByLegacyStack bool -} - -func TestIsLegacyAVDManager(t *testing.T) { - _, err := avdmanager.IsLegacyAVDManager(os.Getenv("ANDROID_HOME")) - require.NoError(t, err) -} - -func TestCreateAndStartEmulator(t *testing.T) { - isLegacyStack, _ := avdmanager.IsLegacyAVDManager(os.Getenv("ANDROID_HOME")) - - for _, emu := range getEmulatorConfigList() { - if isLegacyStack && !emu.isSupportedByLegacyStack { - continue - } - createEmulator(t, emu.platform, emu.tag, emu.abi) - startEmulator(t, emu.runOptions) - } -} - -func getEmulatorConfigList() []emulator { - googleApis25RanchuOptions := []string{"-kernel", os.Getenv("ANDROID_HOME") + "/system-images/android-25/google_apis/arm64-v8a/kernel-qemu"} - return []emulator{ - emulator{platform: "android-24", tag: "google_apis", abi: "armeabi-v7a", runOptions: []string{}, isSupportedByLegacyStack: true}, - emulator{platform: "android-25", tag: "android-wear", abi: "armeabi-v7a", runOptions: []string{}, isSupportedByLegacyStack: true}, - emulator{platform: "android-23", tag: "android-tv", abi: "armeabi-v7a", runOptions: []string{}, isSupportedByLegacyStack: true}, - emulator{platform: "android-19", tag: "default", abi: "armeabi-v7a", runOptions:[]string{}, isSupportedByLegacyStack: true}, - emulator{platform: "android-17", tag: "default", abi: "mips", runOptions: []string{}, isSupportedByLegacyStack: true}, - emulator{platform: "android-25", tag: "google_apis", abi: "arm64-v8a", runOptions: googleApis25RanchuOptions, isSupportedByLegacyStack: false}, - } -} - -func createEmulator(t *testing.T, platform string, tag string, abi string) { - t.Logf("Create emulator: %s - %s - %s", platform, tag, abi) - - androidSdk, err := sdk.New(os.Getenv("ANDROID_HOME")) - require.NoError(t, err) - - manager, err := sdkmanager.New(androidSdk) - require.NoError(t, err) - - platformComponent := sdkcomponent.Platform{ - Version: platform, - } - - platformInstalled, err := manager.IsInstalled(platformComponent) - require.NoError(t, err) - - if !platformInstalled { - t.Logf("Installing platform: %s", platform) - - installCmd := manager.InstallCommand(platformComponent) - installCmd.SetStdin(strings.NewReader("y")) - - t.Logf("$ %s", installCmd.PrintableCommandArgs()) - - out, err := installCmd.RunAndReturnTrimmedCombinedOutput() - require.NoError(t, err, out) - - installed, err := manager.IsInstalled(platformComponent) - require.NoError(t, err) - require.Equal(t, true, installed) - } - - systemImageComponent := sdkcomponent.SystemImage{ - Platform: platform, - Tag: tag, - ABI: abi, - } - - systemImageInstalled, err := manager.IsInstalled(systemImageComponent) - require.NoError(t, err) - - if !systemImageInstalled { - t.Logf("Installing system image (platform: %s abi: %s tag: %s)", systemImageComponent.Platform, systemImageComponent.ABI, systemImageComponent.Tag) - - installCmd := manager.InstallCommand(systemImageComponent) - installCmd.SetStdin(strings.NewReader("y")) - - t.Logf("$ %s", installCmd.PrintableCommandArgs()) - - out, err := installCmd.RunAndReturnTrimmedCombinedOutput() - require.NoError(t, err, out) - - installed, err := manager.IsInstalled(systemImageComponent) - require.NoError(t, err) - require.Equal(t, true, installed) - } - - avdManager, err := avdmanager.New(androidSdk) - require.NoError(t, err) - - cmd := avdManager.CreateAVDCommand(testEmulatorName, systemImageComponent) - cmd.SetStdin(strings.NewReader("n")) - - t.Logf("$ %s", cmd.PrintableCommandArgs()) - - out, err := cmd.RunAndReturnTrimmedCombinedOutput() - require.NoError(t, err, out) -} - -func startEmulator(t *testing.T, runOptions []string) { - t.Logf("Start emulator") - - avdImages, err := listAVDImages() - require.NoError(t, err) - - if !sliceutil.IsStringInSlice(testEmulatorName, avdImages) { - require.FailNow(t, "No emulator found with name: " + testEmulatorName) - } - - androidSdk, err := sdk.New(os.Getenv("ANDROID_HOME")) - require.NoError(t, err) - - adb, err := adbmanager.New(androidSdk) - require.NoError(t, err) - - deviceStateMap, err := runningDeviceInfos(*adb) - require.NoError(t, err) - - emulator, err := emulatormanager.New(androidSdk) - require.NoError(t, err) - - options := []string{"-no-boot-anim", "-no-window"} - options = append(options, runOptions...) - - startEmulatorCommand := emulator.StartEmulatorCommand(testEmulatorName, testEmulatorSkin, options...) - startEmulatorCmd := startEmulatorCommand.GetCmd() - - e := make(chan error) - - stdoutReader, err := startEmulatorCmd.StdoutPipe() - require.NoError(t, err) - - outScanner := bufio.NewScanner(stdoutReader) - go func() { - for outScanner.Scan() { - line := outScanner.Text() - fmt.Println(line) - } - }() - err = outScanner.Err() - require.NoError(t, err) - - stderrReader, err := startEmulatorCmd.StderrPipe() - require.NoError(t, err) - - errScanner := bufio.NewScanner(stderrReader) - go func() { - for errScanner.Scan() { - line := errScanner.Text() - log.Warnf(line) - } - }() - err = errScanner.Err() - require.NoError(t, err) - - serial := "" - - go func() { - t.Logf("$ %s", command.PrintableCommandArgs(false, startEmulatorCmd.Args)) - - if err := startEmulatorCommand.Run(); err != nil { - e <- err - return - } - }() - - go func() { - t.Logf("Checking for started device serial...") - for len(serial) == 0 { - time.Sleep(5 * time.Second) - - currentDeviceStateMap, err := runningDeviceInfos(*adb) - if err != nil { - e <- err - return - } - - serial = currentlyStartedDeviceSerial(deviceStateMap, currentDeviceStateMap) - } - t.Logf("Started device serial: %s", serial) - - bootInProgress := true - t.Log("Wait for emulator to boot...") - for bootInProgress { - time.Sleep(5 * time.Second) - - booted, err := adb.IsDeviceBooted(serial) - if err != nil { - e <- err - return - } - - bootInProgress = !booted - } - - err := adb.UnlockDevice(serial) - require.NoError(t, err) - - log.Donef("Emulator booted") - - e <- nil - }() - - timeout := 600 - - select { - case <-time.After(time.Duration(timeout) * time.Second): - err := startEmulatorCmd.Process.Kill() - if err != nil { - t.Logf("failed to kill process: %s", err) - } - require.FailNow(t, "Boot timed out...") - - case err := <-e: - require.NoError(t, err) - } - - err = startEmulatorCmd.Process.Kill() - if err != nil { - t.Logf("failed to kill process: %s", err) - } -} - -func listAVDImages() ([]string, error) { - homeDir := pathutil.UserHomeDir() - avdDir := filepath.Join(homeDir, ".android", "avd") - - avdImagePattern := filepath.Join(avdDir, "*.ini") - avdImages, err := filepath.Glob(avdImagePattern) - if err != nil { - return []string{}, fmt.Errorf("glob failed with pattern (%s), error: %s", avdImagePattern, err) - } - - avdImageNames := []string{} - - for _, avdImage := range avdImages { - imageName := filepath.Base(avdImage) - imageName = strings.TrimSuffix(imageName, filepath.Ext(avdImage)) - avdImageNames = append(avdImageNames, imageName) - } - - return avdImageNames, nil -} - -func avdImageDir(name string) string { - homeDir := pathutil.UserHomeDir() - return filepath.Join(homeDir, ".android", "avd", name+".avd") -} - -func currentlyStartedDeviceSerial(alreadyRunningDeviceInfos, currentlyRunningDeviceInfos map[string]string) string { - startedSerial := "" - - for serial := range currentlyRunningDeviceInfos { - _, found := alreadyRunningDeviceInfos[serial] - if !found { - startedSerial = serial - break - } - } - - if len(startedSerial) > 0 { - state := currentlyRunningDeviceInfos[startedSerial] - if state == "device" { - return startedSerial - } - } - - return "" -} - -func runningDeviceInfos(adb adbmanager.Model) (map[string]string, error) { - cmd := adb.DevicesCmd() - out, err := cmd.RunAndReturnTrimmedCombinedOutput() - if err != nil { - return map[string]string{}, fmt.Errorf("command failed, error: %s", err) - } - - deviceListItemPattern := `^(?Pemulator-\d*)[\s+](?P.*)` - deviceListItemRegexp := regexp.MustCompile(deviceListItemPattern) - - deviceStateMap := map[string]string{} - - scanner := bufio.NewScanner(strings.NewReader(out)) - for scanner.Scan() { - line := scanner.Text() - matches := deviceListItemRegexp.FindStringSubmatch(line) - if len(matches) == 3 { - serial := matches[1] - state := matches[2] - - deviceStateMap[serial] = state - } - - } - if scanner.Err() != nil { - return map[string]string{}, fmt.Errorf("scanner failed, error: %s", err) - } - - return deviceStateMap, nil -} diff --git a/vendor/github.com/bitrise-tools/go-android/adbmanager/adbmanager.go b/vendor/github.com/bitrise-tools/go-android/adbmanager/adbmanager.go deleted file mode 100644 index fe68858a..00000000 --- a/vendor/github.com/bitrise-tools/go-android/adbmanager/adbmanager.go +++ /dev/null @@ -1,68 +0,0 @@ -package adbmanager - -import ( - "fmt" - "path/filepath" - - "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/bitrise-tools/go-android/sdk" -) - -// Model ... -type Model struct { - binPth string -} - -// New ... -func New(sdk sdk.AndroidSdkInterface) (*Model, error) { - binPth := filepath.Join(sdk.GetAndroidHome(), "platform-tools", "adb") - if exist, err := pathutil.IsPathExists(binPth); err != nil { - return nil, fmt.Errorf("failed to check if adb exist, error: %s", err) - } else if !exist { - return nil, fmt.Errorf("adb not exist at: %s", binPth) - } - - return &Model{ - binPth: binPth, - }, nil -} - -// DevicesCmd ... -func (model Model) DevicesCmd() *command.Model { - return command.New(model.binPth, "devices") -} - -// IsDeviceBooted ... -func (model Model) IsDeviceBooted(serial string) (bool, error) { - devBootCmd := command.New(model.binPth, "-s", serial, "shell", "getprop dev.bootcomplete") - devBootOut, err := devBootCmd.RunAndReturnTrimmedCombinedOutput() - if err != nil { - return false, err - } - - sysBootCmd := command.New(model.binPth, "-s", serial, "shell", "getprop sys.boot_completed") - sysBootOut, err := sysBootCmd.RunAndReturnTrimmedCombinedOutput() - if err != nil { - return false, err - } - - bootAnimCmd := command.New(model.binPth, "-s", serial, "shell", "getprop init.svc.bootanim") - bootAnimOut, err := bootAnimCmd.RunAndReturnTrimmedCombinedOutput() - if err != nil { - return false, err - } - - return (devBootOut == "1" && sysBootOut == "1" && bootAnimOut == "stopped"), nil -} - -// UnlockDevice ... -func (model Model) UnlockDevice(serial string) error { - keyEvent82Cmd := command.New(model.binPth, "-s", serial, "shell", "input", "82", "&") - if err := keyEvent82Cmd.Run(); err != nil { - return err - } - - keyEvent1Cmd := command.New(model.binPth, "-s", serial, "shell", "input", "1", "&") - return keyEvent1Cmd.Run() -} diff --git a/vendor/github.com/bitrise-tools/go-android/avdmanager/avdmanager.go b/vendor/github.com/bitrise-tools/go-android/avdmanager/avdmanager.go deleted file mode 100644 index 813282aa..00000000 --- a/vendor/github.com/bitrise-tools/go-android/avdmanager/avdmanager.go +++ /dev/null @@ -1,98 +0,0 @@ -package avdmanager - -import ( - "fmt" - "os" - "path/filepath" - - "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-io/go-utils/log" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/bitrise-tools/go-android/sdk" - "github.com/bitrise-tools/go-android/sdkcomponent" - "github.com/bitrise-tools/go-android/sdkmanager" -) - -// Model ... -type Model struct { - legacy bool - binPth string -} - -// IsLegacyAVDManager ... -func IsLegacyAVDManager(androidHome string) (bool, error) { - exist, err := pathutil.IsPathExists(filepath.Join(androidHome, "tools", "bin", "avdmanager")) - return !exist, err -} - -// New ... -func New(sdk sdk.AndroidSdkInterface) (*Model, error) { - binPth := filepath.Join(sdk.GetAndroidHome(), "tools", "bin", "avdmanager") - - legacySdk, err := sdkmanager.IsLegacySDKManager(sdk.GetAndroidHome()) - if err != nil { - return nil, err - } - - legacyAvd, err := IsLegacyAVDManager(sdk.GetAndroidHome()) - if err != nil { - return nil, err - } else if legacyAvd && legacySdk { - binPth = filepath.Join(sdk.GetAndroidHome(), "tools", "android") - } else if legacyAvd && !legacySdk { - fmt.Println() - log.Warnf("Found sdkmanager but no avdmanager, updating SDK Tools...") - binPth = filepath.Join(sdk.GetAndroidHome(), "tools", "android") - sdkManager, err := sdkmanager.New(sdk) - if err == nil { - sdkToolComponent := sdkcomponent.SDKTool{} - updateCmd := sdkManager.InstallCommand(sdkToolComponent) - updateCmd.SetStderr(os.Stderr) - updateCmd.SetStdout(os.Stdout) - if err := updateCmd.Run(); err == nil { - legacyAvd, err = IsLegacyAVDManager(sdk.GetAndroidHome()) - if err == nil && !legacyAvd { - log.Printf("- avdmanager successfully installed") - binPth = filepath.Join(sdk.GetAndroidHome(), "tools", "bin", "avdmanager") - } else if legacyAvd { - log.Printf("- updating SDK tools was unsuccessful, continuing with legacy avd manager...") - } - } else { - log.Errorf("Failed to run command:") - fmt.Println() - log.Donef("$ %s", updateCmd.PrintableCommandArgs()) - fmt.Println() - log.Warnf("- continuing with legacy avd manager") - } - } - } - - if exist, err := pathutil.IsPathExists(binPth); err != nil { - return nil, err - } else if !exist { - return nil, fmt.Errorf("no avd manager tool found at: %s", binPth) - } - - return &Model{ - legacy: legacyAvd, - binPth: binPth, - }, nil -} - -// CreateAVDCommand ... -func (model Model) CreateAVDCommand(name string, systemImage sdkcomponent.SystemImage, options ...string) *command.Model { - args := []string{"--verbose", "create", "avd", "--force", "--name", name, "--abi", systemImage.ABI} - - if model.legacy { - args = append(args, "--target", systemImage.Platform) - } else { - args = append(args, "--package", systemImage.GetSDKStylePath()) - } - - if systemImage.Tag != "" && systemImage.Tag != "default" { - args = append(args, "--tag", systemImage.Tag) - } - - args = append(args, options...) - return command.New(model.binPth, args...) -} diff --git a/vendor/github.com/bitrise-tools/go-android/avdmanager/avdmanager_test.go b/vendor/github.com/bitrise-tools/go-android/avdmanager/avdmanager_test.go deleted file mode 100644 index 50e59a48..00000000 --- a/vendor/github.com/bitrise-tools/go-android/avdmanager/avdmanager_test.go +++ /dev/null @@ -1 +0,0 @@ -package avdmanager diff --git a/vendor/github.com/bitrise-tools/go-android/bitrise.yml b/vendor/github.com/bitrise-tools/go-android/bitrise.yml deleted file mode 100644 index 2c09fe16..00000000 --- a/vendor/github.com/bitrise-tools/go-android/bitrise.yml +++ /dev/null @@ -1,84 +0,0 @@ -format_version: 1.4.0 -default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git - -workflows: - ci: - before_run: - - _install_test_tools - - test - - integration-test - - test: - steps: - - script: - title: Export go files to test - inputs: - - content: |- - #!/bin/bash - set -ex - - no_vendor_paths="$(go list ./... | grep -v vendor)" - envman add --key GOLIST_WITHOUT_VENDOR --value "$no_vendor_paths" - - script: - title: Err check - inputs: - - content: |- - #!/bin/bash - set -ex - - errcheck -asserts=true -blank=true $GOLIST_WITHOUT_VENDOR - - script: - title: Go lint - inputs: - - content: |- - #!/bin/bash - set -ex - - while read -r line; do - echo "-> Linting: $line" - golint_out="$(golint $line)" - if [[ "${golint_out}" != "" ]] ; then - echo "=> Golint issues found:" - echo "${golint_out}" - exit 1 - fi - done <<< "$GOLIST_WITHOUT_VENDOR" - - script: - title: Go test - inputs: - - content: |- - #!/bin/bash - set -ex - - go test ./... - - _install_test_tools: - steps: - - script: - title: Install required testing tools - inputs: - - content: |- - #!/bin/bash - set -ex - - # Check for unhandled errors - go get -u -v github.com/kisielk/errcheck - - # Go lint - go get -u -v github.com/golang/lint/golint - - go get -u -v github.com/stretchr/testify/require - go get -u -v github.com/bitrise-io/go-utils/pathutil - go get -u -v github.com/bitrise-io/go-utils/command - go get -u -v github.com/hashicorp/go-version - - integration-test: - steps: - - script: - title: Run integration tests - inputs: - - content: |- - #!/bin/bash - echo "Running integration tests ..." - set -ex - go test -v ./_tests/integration/... -timeout 120m \ No newline at end of file diff --git a/vendor/github.com/bitrise-tools/go-android/emulatormanager/emulatormanager.go b/vendor/github.com/bitrise-tools/go-android/emulatormanager/emulatormanager.go deleted file mode 100644 index b3e177e7..00000000 --- a/vendor/github.com/bitrise-tools/go-android/emulatormanager/emulatormanager.go +++ /dev/null @@ -1,158 +0,0 @@ -package emulatormanager - -import ( - "fmt" - "path/filepath" - "runtime" - "strings" - "io/ioutil" - "os/user" - - "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-io/go-utils/log" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/bitrise-tools/go-android/sdk" -) - -// Model ... -type Model struct { - binPth string - envs []string -} - -// IsLegacyEmulator ... -func IsLegacyEmulator(androidHome string) (bool, error) { - exist, err := pathutil.IsPathExists(filepath.Join(androidHome, "emulator", "emulator")) - return !exist, err -} - -func emulatorBinPth(androidHome string, legacyEmulator bool) (string, error) { - emulatorDir := filepath.Join(androidHome, "emulator") - if legacyEmulator { - emulatorDir = filepath.Join(androidHome, "tools") - } - - binPth := filepath.Join(emulatorDir, "emulator") - if exist, err := pathutil.IsPathExists(binPth); err != nil { - return "", err - } else if !exist { - message := "no emulator binary found in $ANDROID_HOME/emulator" - if legacyEmulator { - message = "no emulator binary found in $ANDROID_HOME/tools" - } - return "", fmt.Errorf(message) - } - return binPth, nil -} - -func lib64Env(androidHome, hostOSName string, legacyEmulator bool) (string, error) { - envKey := "" - - if hostOSName == "linux" { - envKey = "LD_LIBRARY_PATH" - } else if hostOSName == "darwin" { - envKey = "DYLD_LIBRARY_PATH" - } else { - return "", fmt.Errorf("unsupported os %s", hostOSName) - } - - emulatorDir := filepath.Join(androidHome, "emulator") - - if legacyEmulator { - emulatorDir = filepath.Join(androidHome, "tools") - libPth := filepath.Join(emulatorDir, "lib64") - if exist, err := pathutil.IsPathExists(libPth); err != nil { - return "", err - } else if !exist { - return "", fmt.Errorf("lib64 does not exist at: %s", libPth) - } - return envKey + "=" + libPth, nil - } - - qtLibPth := filepath.Join(emulatorDir, "lib64", "qt", "lib") - - if exist, err := pathutil.IsPathExists(qtLibPth); err != nil { - return "", err - } else if !exist { - return "", fmt.Errorf("qt lib does not exist at: %s", qtLibPth) - } - - libPth := filepath.Join(emulatorDir, "lib64") - - return envKey + "=" + libPth + ":" + qtLibPth, nil -} - -// New ... -func New(sdk sdk.AndroidSdkInterface) (*Model, error) { - legacyEmulator, err := IsLegacyEmulator(sdk.GetAndroidHome()) - if err != nil { - return nil, err - } - - binPth, err := emulatorBinPth(sdk.GetAndroidHome(), legacyEmulator) - if err != nil { - return nil, err - } - - envs := []string{} - if strings.HasSuffix(binPth, "emulator") { - env, err := lib64Env(sdk.GetAndroidHome(), runtime.GOOS, legacyEmulator) - if err != nil { - log.Warnf("failed to get lib64 qt lib path, error: %s", err) - } else { - envs = append(envs, env) - } - } - if legacyEmulator { - bashPath := "/bin/bash" - if exist, err := pathutil.IsPathExists(bashPath); err != nil { - log.Warnf("Failed to determine if bash binary exists, error: %s", err) - } else if !exist { - log.Warnf("Bash binary does not exist at: %s", bashPath) - } - envs = append(envs, "SHELL=" + bashPath) - } - - return &Model{ - binPth: binPth, - envs: envs, - }, nil -} - -func isAVDarmeabiv7a(name string) bool { - user, err := user.Current() - if err != nil { - log.Warnf("Failed to determine AVD ABI, could not get current user, error: %s", err) - return false - } - content, err := ioutil.ReadFile(user.HomeDir + "/.android/avd/" + name + ".avd/config.ini") - if err != nil { - log.Warnf("Failed to determine AVD ABI, could not read AVD config file, error: %s", err) - return false - } - return strings.Contains(string(content), "abi.type=armeabi-v7") -} - -// StartEmulatorCommand ... -func (model Model) StartEmulatorCommand(name, skin string, options ...string) *command.Model { - if isAVDarmeabiv7a(name) { - model.binPth += "64-arm" - if exist, err := pathutil.IsPathExists(model.binPth); err != nil { - log.Warnf("Failed to determine whether emulator binary exists, error: %s", err) - } else if !exist { - log.Warnf("Emulator binary does not exist at: %s", model.binPth) - } - } - - args := []string{model.binPth, "-avd", name} - if len(skin) == 0 { - args = append(args, "-noskin") - } else { - args = append(args, "-skin", skin) - } - args = append(args, options...) - - commandModel := command.New(args[0], args[1:]...).AppendEnvs(model.envs...) - - return commandModel -} diff --git a/vendor/github.com/bitrise-tools/go-android/emulatormanager/emulatormanager_test.go b/vendor/github.com/bitrise-tools/go-android/emulatormanager/emulatormanager_test.go deleted file mode 100644 index 13fdc55e..00000000 --- a/vendor/github.com/bitrise-tools/go-android/emulatormanager/emulatormanager_test.go +++ /dev/null @@ -1,137 +0,0 @@ -package emulatormanager - -import ( - "os" - "path/filepath" - "strings" - "testing" - - "github.com/bitrise-io/go-utils/fileutil" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/stretchr/testify/require" -) - -func TestEmulatorBinPth(t *testing.T) { - tmpDir, err := pathutil.NormalizedOSTempDirPath("") - require.NoError(t, err) - - emulatorDir := filepath.Join(tmpDir, "emulator") - require.NoError(t, os.MkdirAll(emulatorDir, 0700)) - - emulatorPth := filepath.Join(emulatorDir, "emulator") - require.NoError(t, fileutil.WriteStringToFile(emulatorPth, "")) - - t.Log("fail if no emulator bin found") - { - require.NoError(t, os.RemoveAll(emulatorPth)) - pth, err := emulatorBinPth(tmpDir, false) - require.EqualError(t, err, "no emulator binary found in $ANDROID_HOME/emulator") - require.Equal(t, "", pth) - } -} - -func TestLegacyEmulatorBinPth(t *testing.T) { - tmpDir, err := pathutil.NormalizedOSTempDirPath("") - require.NoError(t, err) - - emulatorDir := filepath.Join(tmpDir, "tools") - require.NoError(t, os.MkdirAll(emulatorDir, 0700)) - - emulatorPth := filepath.Join(emulatorDir, "emulator") - require.NoError(t, fileutil.WriteStringToFile(emulatorPth, "")) - - t.Log("fail if no emulator bin found") - { - require.NoError(t, os.RemoveAll(emulatorPth)) - pth, err := emulatorBinPth(tmpDir, true) - require.EqualError(t, err, "no emulator binary found in $ANDROID_HOME/tools") - require.Equal(t, "", pth) - } -} - -func TestLib64Env(t *testing.T) { - tmpDir, err := pathutil.NormalizedOSTempDirPath("") - require.NoError(t, err) - - lib64Dir := filepath.Join(tmpDir, "emulator", "lib64") - require.NoError(t, os.MkdirAll(lib64Dir, 0700)) - - lib64QTLibDir := filepath.Join(tmpDir, "emulator", "lib64", "qt", "lib") - require.NoError(t, os.MkdirAll(lib64QTLibDir, 0700)) - - t.Log("lib env on linux") - { - env, err := lib64Env(tmpDir, "linux", false) - require.NoError(t, err) - require.Equal(t, true, strings.HasPrefix(env, "LD_LIBRARY_PATH="), env) - require.Equal(t, true, strings.Contains(env, "emulator/lib64:"), env) - require.Equal(t, true, strings.HasSuffix(env, "emulator/lib64/qt/lib"), env) - } - - t.Log("lib env on osx") - { - env, err := lib64Env(tmpDir, "darwin", false) - require.NoError(t, err) - require.Equal(t, true, strings.HasPrefix(env, "DYLD_LIBRARY_PATH="), env) - require.Equal(t, true, strings.Contains(env, "emulator/lib64:"), env) - require.Equal(t, true, strings.HasSuffix(env, "emulator/lib64/qt/lib"), env) - } - - t.Log("lib qt missing") - { - require.NoError(t, os.RemoveAll(lib64QTLibDir)) - - env, err := lib64Env(tmpDir, "linux", false) - require.Error(t, err) - require.Equal(t, true, strings.HasPrefix(err.Error(), "qt lib does not exist at:")) - require.Equal(t, "", env) - - env, err = lib64Env(tmpDir, "darwin", false) - require.Error(t, err) - require.Equal(t, true, strings.HasPrefix(err.Error(), "qt lib does not exist at:")) - require.Equal(t, "", env) - } - - t.Log("unspported os") - { - env, err := lib64Env(tmpDir, "windows", false) - require.Error(t, err) - require.EqualError(t, err, "unsupported os windows") - require.Equal(t, "", env) - } -} - -func TestLegacyLibEnv(t *testing.T) { - tmpDir, err := pathutil.NormalizedOSTempDirPath("") - require.NoError(t, err) - - lib64Dir := filepath.Join(tmpDir, "tools", "lib64") - require.NoError(t, os.MkdirAll(lib64Dir, 0700)) - - lib64QTLibDir := filepath.Join(tmpDir, "tools", "lib64", "qt", "lib") - require.NoError(t, os.MkdirAll(lib64QTLibDir, 0700)) - - t.Log("lib env on linux") - { - env, err := lib64Env(tmpDir, "linux", true) - require.NoError(t, err) - require.Equal(t, true, strings.HasPrefix(env, "LD_LIBRARY_PATH="), env) - require.Equal(t, true, strings.HasSuffix(env, "tools/lib64"), env) - } - - t.Log("lib env on osx") - { - env, err := lib64Env(tmpDir, "darwin", true) - require.NoError(t, err) - require.Equal(t, true, strings.HasPrefix(env, "DYLD_LIBRARY_PATH="), env) - require.Equal(t, true, strings.HasSuffix(env, "tools/lib64"), env) - } - - t.Log("unspported os") - { - env, err := lib64Env(tmpDir, "windows", true) - require.Error(t, err) - require.EqualError(t, err, "unsupported os windows") - require.Equal(t, "", env) - } -} diff --git a/vendor/github.com/bitrise-tools/go-android/gows.yml b/vendor/github.com/bitrise-tools/go-android/gows.yml deleted file mode 100644 index 07909f9e..00000000 --- a/vendor/github.com/bitrise-tools/go-android/gows.yml +++ /dev/null @@ -1 +0,0 @@ -package_name: github.com/bitrise-tools/go-android diff --git a/vendor/github.com/bitrise-tools/go-android/sdk/sdk_test.go b/vendor/github.com/bitrise-tools/go-android/sdk/sdk_test.go deleted file mode 100644 index f5fb3689..00000000 --- a/vendor/github.com/bitrise-tools/go-android/sdk/sdk_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package sdk - -import ( - "os" - "testing" - - "path/filepath" - - "strings" - - "github.com/bitrise-io/go-utils/fileutil" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/stretchr/testify/require" -) - -func TestLatestBuildToolsDir(t *testing.T) { - tmpDir, err := pathutil.NormalizedOSTempDirPath("") - require.NoError(t, err) - - buildToolsVersions := []string{"25.0.2", "25.0.3", "22.0.4"} - for _, buildToolsVersion := range buildToolsVersions { - buildToolsVersionPth := filepath.Join(tmpDir, "build-tools", buildToolsVersion) - require.NoError(t, os.MkdirAll(buildToolsVersionPth, 0700)) - } - - sdk, err := New(tmpDir) - require.NoError(t, err) - - latestBuildToolsDir, err := sdk.LatestBuildToolsDir() - require.NoError(t, err) - require.Equal(t, true, strings.Contains(latestBuildToolsDir, filepath.Join("build-tools", "25.0.3")), latestBuildToolsDir) -} - -func TestLatestBuildToolPath(t *testing.T) { - tmpDir, err := pathutil.NormalizedOSTempDirPath("") - require.NoError(t, err) - - buildToolsVersions := []string{"25.0.2", "25.0.3", "22.0.4"} - for _, buildToolsVersion := range buildToolsVersions { - buildToolsVersionPth := filepath.Join(tmpDir, "build-tools", buildToolsVersion) - require.NoError(t, os.MkdirAll(buildToolsVersionPth, 0700)) - } - - latestBuildToolsVersions := filepath.Join(tmpDir, "build-tools", "25.0.3") - zipalignPth := filepath.Join(latestBuildToolsVersions, "zipalign") - require.NoError(t, fileutil.WriteStringToFile(zipalignPth, "")) - - sdk, err := New(tmpDir) - require.NoError(t, err) - - t.Log("zipalign - exist") - { - pth, err := sdk.LatestBuildToolPath("zipalign") - require.NoError(t, err) - require.Equal(t, true, strings.Contains(pth, filepath.Join("build-tools", "25.0.3", "zipalign")), pth) - } - - t.Log("aapt - NOT exist") - { - pth, err := sdk.LatestBuildToolPath("aapt") - require.Equal(t, true, strings.Contains(err.Error(), "tool (aapt) not found at:")) - require.Equal(t, "", pth) - } - -} diff --git a/vendor/github.com/bitrise-tools/go-android/sdkcomponent/sdkcomponent.go b/vendor/github.com/bitrise-tools/go-android/sdkcomponent/sdkcomponent.go deleted file mode 100644 index 25cda720..00000000 --- a/vendor/github.com/bitrise-tools/go-android/sdkcomponent/sdkcomponent.go +++ /dev/null @@ -1,260 +0,0 @@ -package sdkcomponent - -import ( - "fmt" - "path/filepath" - "strings" -) - -// Model ... -type Model interface { - GetSDKStylePath() string - GetLegacySDKStylePath() string - InstallPathInAndroidHome() string - InstallationIndicatorFile() string -} - -// SDKTool ... -type SDKTool struct { - SDKStylePath string - LegacySDKStylePath string -} - -// GetSDKStylePath ... -func (component SDKTool) GetSDKStylePath() string { - if component.SDKStylePath != "" { - return component.SDKStylePath - } - return "tools" -} - -// GetLegacySDKStylePath ... -func (component SDKTool) GetLegacySDKStylePath() string { - if component.LegacySDKStylePath != "" { - return component.LegacySDKStylePath - } - return "tools" -} - -// InstallPathInAndroidHome ... -func (component SDKTool) InstallPathInAndroidHome() string { - return "tools" -} - -// InstallationIndicatorFile ... -func (component SDKTool) InstallationIndicatorFile() string { - return "" -} - -// BuildTool ... -type BuildTool struct { - Version string - - SDKStylePath string - LegacySDKStylePath string -} - -// GetSDKStylePath ... -func (component BuildTool) GetSDKStylePath() string { - if component.SDKStylePath != "" { - return component.SDKStylePath - } - return fmt.Sprintf("build-tools;%s", component.Version) -} - -// GetLegacySDKStylePath ... -func (component BuildTool) GetLegacySDKStylePath() string { - if component.LegacySDKStylePath != "" { - return component.LegacySDKStylePath - } - return fmt.Sprintf("build-tools-%s", component.Version) -} - -// InstallPathInAndroidHome ... -func (component BuildTool) InstallPathInAndroidHome() string { - return filepath.Join("build-tools", component.Version) -} - -// InstallationIndicatorFile ... -func (component BuildTool) InstallationIndicatorFile() string { - return "" -} - -// Platform ... -type Platform struct { - Version string - - SDKStylePath string - LegacySDKStylePath string -} - -// GetSDKStylePath ... -func (component Platform) GetSDKStylePath() string { - if component.SDKStylePath != "" { - return component.SDKStylePath - } - return fmt.Sprintf("platforms;%s", component.Version) -} - -// GetLegacySDKStylePath ... -func (component Platform) GetLegacySDKStylePath() string { - if component.LegacySDKStylePath != "" { - return component.LegacySDKStylePath - } - return component.Version -} - -// InstallPathInAndroidHome ... -func (component Platform) InstallPathInAndroidHome() string { - return filepath.Join("platforms", component.Version) -} - -// InstallationIndicatorFile ... -func (component Platform) InstallationIndicatorFile() string { - return "" -} - -// SystemImage ... -type SystemImage struct { - Platform string - ABI string - Tag string - - SDKStylePath string - LegacySDKStylePath string -} - -// GetSDKStylePath ... -func (component SystemImage) GetSDKStylePath() string { - if component.SDKStylePath != "" { - return component.SDKStylePath - } - - tag := "default" - if component.Tag != "" { - tag = component.Tag - } - - return fmt.Sprintf("system-images;%s;%s;%s", component.Platform, tag, component.ABI) -} - -// GetLegacySDKStylePath ... -func (component SystemImage) GetLegacySDKStylePath() string { - if component.LegacySDKStylePath != "" { - return component.LegacySDKStylePath - } - - platform := component.Platform - if component.Tag != "" && component.Tag != "default" { - split := strings.Split(component.Platform, "-") - if len(split) == 2 { - platform = component.Tag + "-" + split[1] - } - } - - return fmt.Sprintf("sys-img-%s-%s", component.ABI, platform) -} - -// InstallPathInAndroidHome ... -func (component SystemImage) InstallPathInAndroidHome() string { - componentTag := "default" - if component.Tag != "" { - componentTag = component.Tag - } - - return filepath.Join("system-images", component.Platform, componentTag, component.ABI) -} - -// InstallationIndicatorFile ... -func (component SystemImage) InstallationIndicatorFile() string { - return "system.img" -} - -// Extras ... -type Extras struct { - Provider string - PackageName string - - SDKStylePath string - LegacySDKStylePath string -} - -// GooglePlayServicesInstallComponents ... -func GooglePlayServicesInstallComponents() []Extras { - return []Extras{ - Extras{ - Provider: "google", - PackageName: "m2repository", - }, - Extras{ - Provider: "google", - PackageName: "google_play_services", - }, - } -} - -// LegacyGooglePlayServicesInstallComponents ... -func LegacyGooglePlayServicesInstallComponents() []Extras { - return []Extras{ - Extras{ - Provider: "google", - PackageName: "m2repository", - }, - Extras{ - Provider: "google", - PackageName: "google_play_services", - }, - } -} - -// SupportLibraryInstallComponents ... -func SupportLibraryInstallComponents() []Extras { - return []Extras{ - Extras{ - Provider: "android", - PackageName: "m2repository", - }, - // Extras{ - // Provider: "android", - // PackageName: "support", - // }, - } -} - -// LegacySupportLibraryInstallComponents ... -func LegacySupportLibraryInstallComponents() []Extras { - return []Extras{ - Extras{ - Provider: "android", - PackageName: "m2repository", - }, - } -} - -// GetSDKStylePath ... -func (component Extras) GetSDKStylePath() string { - if component.SDKStylePath != "" { - return component.SDKStylePath - } - - return fmt.Sprintf("extras;%s;%s", component.Provider, component.PackageName) -} - -// GetLegacySDKStylePath ... -func (component Extras) GetLegacySDKStylePath() string { - if component.LegacySDKStylePath != "" { - return component.LegacySDKStylePath - } - - return fmt.Sprintf("extra-%s-%s", component.Provider, component.PackageName) -} - -// InstallPathInAndroidHome ... -func (component Extras) InstallPathInAndroidHome() string { - return filepath.Join("extras", component.Provider, component.PackageName) -} - -// InstallationIndicatorFile ... -func (component Extras) InstallationIndicatorFile() string { - return "" -} diff --git a/vendor/github.com/bitrise-tools/go-android/sdkcomponent/sdkcomponent_test.go b/vendor/github.com/bitrise-tools/go-android/sdkcomponent/sdkcomponent_test.go deleted file mode 100644 index f76d304e..00000000 --- a/vendor/github.com/bitrise-tools/go-android/sdkcomponent/sdkcomponent_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package sdkcomponent - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestSystemImageComponent(t *testing.T) { - { - component := SystemImage{ - Platform: "android-24", - Tag: "", - ABI: "x86", - } - - require.Equal(t, "system-images;android-24;default;x86", component.GetSDKStylePath()) - require.Equal(t, "sys-img-x86-android-24", component.GetLegacySDKStylePath()) - require.Equal(t, "system-images/android-24/default/x86", component.InstallPathInAndroidHome()) - } - - { - component := SystemImage{ - Platform: "android-24", - Tag: "default", - ABI: "x86", - } - - require.Equal(t, "system-images;android-24;default;x86", component.GetSDKStylePath()) - require.Equal(t, "sys-img-x86-android-24", component.GetLegacySDKStylePath()) - require.Equal(t, "system-images/android-24/default/x86", component.InstallPathInAndroidHome()) - } - - { - component := SystemImage{ - Platform: "android-23", - Tag: "google_apis", - ABI: "armeabi-v7a", - } - - require.Equal(t, "system-images;android-23;google_apis;armeabi-v7a", component.GetSDKStylePath()) - require.Equal(t, "sys-img-armeabi-v7a-google_apis-23", component.GetLegacySDKStylePath()) - require.Equal(t, "system-images/android-23/google_apis/armeabi-v7a", component.InstallPathInAndroidHome()) - } - - { - component := SystemImage{ - Platform: "android-23", - Tag: "android-tv", - ABI: "armeabi-v7a", - } - - require.Equal(t, "system-images;android-23;android-tv;armeabi-v7a", component.GetSDKStylePath()) - require.Equal(t, "sys-img-armeabi-v7a-android-tv-23", component.GetLegacySDKStylePath()) - require.Equal(t, "system-images/android-23/android-tv/armeabi-v7a", component.InstallPathInAndroidHome()) - } -} - -func TestPlatformComponent(t *testing.T) { - component := Platform{ - Version: "android-23", - } - - require.Equal(t, "platforms;android-23", component.GetSDKStylePath()) - require.Equal(t, "android-23", component.GetLegacySDKStylePath()) - require.Equal(t, "platforms/android-23", component.InstallPathInAndroidHome()) -} - -func TestBuildToolComponent(t *testing.T) { - component := BuildTool{ - Version: "19.1.0", - } - - require.Equal(t, "build-tools;19.1.0", component.GetSDKStylePath()) - require.Equal(t, "build-tools-19.1.0", component.GetLegacySDKStylePath()) - require.Equal(t, "build-tools/19.1.0", component.InstallPathInAndroidHome()) -} diff --git a/vendor/github.com/bitrise-tools/go-android/sdkmanager/sdkmanager.go b/vendor/github.com/bitrise-tools/go-android/sdkmanager/sdkmanager.go deleted file mode 100644 index 052a16f2..00000000 --- a/vendor/github.com/bitrise-tools/go-android/sdkmanager/sdkmanager.go +++ /dev/null @@ -1,73 +0,0 @@ -package sdkmanager - -import ( - "fmt" - "path/filepath" - - "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/bitrise-tools/go-android/sdk" - "github.com/bitrise-tools/go-android/sdkcomponent" -) - -// Model ... -type Model struct { - androidHome string - legacy bool - binPth string -} - -// IsLegacySDKManager ... -func IsLegacySDKManager(androidHome string) (bool, error) { - exist, err := pathutil.IsPathExists(filepath.Join(androidHome, "tools", "bin", "sdkmanager")) - return !exist, err -} - -// New ... -func New(sdk sdk.AndroidSdkInterface) (*Model, error) { - binPth := filepath.Join(sdk.GetAndroidHome(), "tools", "bin", "sdkmanager") - - legacy, err := IsLegacySDKManager(sdk.GetAndroidHome()) - if err != nil { - return nil, err - } else if legacy { - binPth = filepath.Join(sdk.GetAndroidHome(), "tools", "android") - } - - if exist, err := pathutil.IsPathExists(binPth); err != nil { - return nil, err - } else if !exist { - return nil, fmt.Errorf("no sdk manager tool found at: %s", binPth) - } - - return &Model{ - androidHome: sdk.GetAndroidHome(), - legacy: legacy, - binPth: binPth, - }, nil -} - -// IsLegacySDK ... -func (model Model) IsLegacySDK() bool { - return model.legacy -} - -// IsInstalled ... -func (model Model) IsInstalled(component sdkcomponent.Model) (bool, error) { - relPth := component.InstallPathInAndroidHome() - indicatorFile := component.InstallationIndicatorFile() - installPth := filepath.Join(model.androidHome, relPth) - - if indicatorFile != "" { - installPth = filepath.Join(installPth, indicatorFile) - } - return pathutil.IsPathExists(installPth) -} - -// InstallCommand ... -func (model Model) InstallCommand(component sdkcomponent.Model) *command.Model { - if model.legacy { - return command.New(model.binPth, "update", "sdk", "--no-ui", "--all", "--filter", component.GetLegacySDKStylePath()) - } - return command.New(model.binPth, component.GetSDKStylePath()) -} diff --git a/vendor/github.com/bitrise-tools/go-android/sdkmanager/sdkmanager_test.go b/vendor/github.com/bitrise-tools/go-android/sdkmanager/sdkmanager_test.go deleted file mode 100644 index 689f4636..00000000 --- a/vendor/github.com/bitrise-tools/go-android/sdkmanager/sdkmanager_test.go +++ /dev/null @@ -1 +0,0 @@ -package sdkmanager diff --git a/vendor/github.com/bitrise-tools/go-steputils/.gitignore b/vendor/github.com/bitrise-tools/go-steputils/.gitignore deleted file mode 100644 index 4caef016..00000000 --- a/vendor/github.com/bitrise-tools/go-steputils/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -_tmp/ -_bin/ -.gows* \ No newline at end of file diff --git a/vendor/github.com/bitrise-tools/go-steputils/README.md b/vendor/github.com/bitrise-tools/go-steputils/README.md deleted file mode 100644 index 5d755f73..00000000 --- a/vendor/github.com/bitrise-tools/go-steputils/README.md +++ /dev/null @@ -1 +0,0 @@ -# go-steputils \ No newline at end of file diff --git a/vendor/github.com/bitrise-tools/go-steputils/bitrise.yml b/vendor/github.com/bitrise-tools/go-steputils/bitrise.yml deleted file mode 100644 index b5975dbf..00000000 --- a/vendor/github.com/bitrise-tools/go-steputils/bitrise.yml +++ /dev/null @@ -1,67 +0,0 @@ -format_version: 1.0.0 -default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git - -workflows: - # ---------------------------------------------------------------- - # --- workflows for Testing - ci: - before_run: - - _install-test-tools - - test - - test: - steps: - - script: - title: Export go files to test - inputs: - - content: |- - #!/bin/bash - set -ex - no_vendor_paths="$(go list ./... | grep -v vendor)" - envman add --key GOLIST_WITHOUT_VENDOR --value "$no_vendor_paths" - - script: - title: Err check - inputs: - - content: |- - #!/bin/bash - set -ex - errcheck -asserts=true -blank=true $GOLIST_WITHOUT_VENDOR - - script: - title: Go lint - inputs: - - content: |- - #!/bin/bash - set -ex - while read -r line; do - echo "-> Linting: $line" - golint_out="$(golint $line)" - if [[ "${golint_out}" != "" ]] ; then - echo "=> Golint issues found:" - echo "${golint_out}" - exit 1 - fi - done <<< "$GOLIST_WITHOUT_VENDOR" - - script: - title: Go test - inputs: - - content: |- - #!/bin/bash - set -ex - go test ./... - _install-test-tools: - steps: - - script: - title: Install required testing tools - inputs: - - content: |- - #!/bin/bash - set -ex - # Check for unhandled errors - go get -u -v github.com/kisielk/errcheck - # Go lint - go get -u -v github.com/golang/lint/golint - - go get -u github.com/stretchr/testify/require - go get -u github.com/bitrise-io/go-utils/command - go get -u github.com/bitrise-io/go-utils/pathutil - go get -u github.com/bitrise-io/go-utils/fileutil \ No newline at end of file diff --git a/vendor/github.com/bitrise-tools/go-steputils/cache/cache.go b/vendor/github.com/bitrise-tools/go-steputils/cache/cache.go deleted file mode 100644 index 69793ff3..00000000 --- a/vendor/github.com/bitrise-tools/go-steputils/cache/cache.go +++ /dev/null @@ -1,64 +0,0 @@ -package cache - -import "github.com/bitrise-tools/go-steputils/tools" -import "os" -import "strings" - -// GlobalCachePathsEnvironmentKey ... -const GlobalCachePathsEnvironmentKey = "BITRISE_CACHE_INCLUDE_PATHS" - -// GlobalCacheIgnorePathsEnvironmentKey ... -const GlobalCacheIgnorePathsEnvironmentKey = "BITRISE_CACHE_EXCLUDE_PATHS" - -// Cache ... -type Cache struct { - include []string - exclude []string -} - -// New ... -func New() Cache { - return Cache{} -} - -// IncludePath ... -func (cache *Cache) IncludePath(item string) { - cache.include = append(cache.include, item) -} - -// ExcludePath ... -func (cache *Cache) ExcludePath(item string) { - cache.exclude = append(cache.exclude, item) -} - -// Commit ... -func (cache *Cache) Commit() error { - err := appendCacheItem(cache.include) - if err != nil { - return err - } - err = appendCacheIgnoreItem(cache.exclude) - if err != nil { - return err - } - return nil -} - -func appendCacheItem(values []string) error { - return combineEnvContent(GlobalCachePathsEnvironmentKey, values) -} - -func appendCacheIgnoreItem(values []string) error { - return combineEnvContent(GlobalCacheIgnorePathsEnvironmentKey, values) -} - -func combineEnvContent(envVar string, values []string) error { - content := os.Getenv(envVar) - - content += "\n" + strings.Join(values, "\n") + "\n" - - if err := tools.ExportEnvironmentWithEnvman(envVar, content); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/bitrise-tools/go-steputils/cache/cache_test.go b/vendor/github.com/bitrise-tools/go-steputils/cache/cache_test.go deleted file mode 100644 index b34e490e..00000000 --- a/vendor/github.com/bitrise-tools/go-steputils/cache/cache_test.go +++ /dev/null @@ -1,94 +0,0 @@ -package cache - -import ( - "encoding/json" - "fmt" - "os" - "path/filepath" - "testing" - - "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-io/go-utils/fileutil" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/stretchr/testify/require" -) - -const testEnvVarContent = ` -/tmp/mypath -> /tmp/mypath/cachefile -/tmp/otherpath -/tmp/anotherpath -/tmp/othercache -/somewhere/else -` - -const testIgnoreEnvVarContent = ` -/*.log -/*.bin -/*.lock -` - -func TestCacheFunctions(t *testing.T) { - - t.Log("Init envman") - { - // envman requires an envstore path to use, or looks for default envstore path: ./.envstore.yml - workDir, err := pathutil.CurrentWorkingDirectoryAbsolutePath() - require.NoError(t, err) - defaultEnvstorePth := filepath.Join(workDir, ".envstore.yml") - require.NoError(t, fileutil.WriteStringToFile(defaultEnvstorePth, "")) - defer func() { - require.NoError(t, os.Remove(defaultEnvstorePth)) - }() - // - - { - // envstore should be clear - cmd := command.New("envman", "clear") - out, err := cmd.RunAndReturnTrimmedCombinedOutput() - require.NoError(t, err, out) - cmd = command.New("envman", "print") - out, err = cmd.RunAndReturnTrimmedCombinedOutput() - require.NoError(t, err, out) - require.Equal(t, "", out) - } - } - - t.Log("Test - cache") - { - cache := New() - cache.IncludePath("/tmp/mypath -> /tmp/mypath/cachefile") - cache.IncludePath("/tmp/otherpath") - cache.IncludePath("/tmp/anotherpath") - cache.IncludePath("/tmp/othercache") - cache.IncludePath("/somewhere/else") - cache.ExcludePath("/*.log") - cache.ExcludePath("/*.bin") - cache.ExcludePath("/*.lock") - err := cache.Commit() - require.NoError(t, err) - - content, err := getEnvironmentValueWithEnvman(GlobalCachePathsEnvironmentKey) - require.NoError(t, err) - require.Equal(t, testEnvVarContent, content) - - content, err = getEnvironmentValueWithEnvman(GlobalCacheIgnorePathsEnvironmentKey) - require.NoError(t, err) - require.Equal(t, testIgnoreEnvVarContent, content) - } -} - -func getEnvironmentValueWithEnvman(key string) (string, error) { - cmd := command.New("envman", "print", "--format", "json") - output, err := cmd.RunAndReturnTrimmedCombinedOutput() - if err != nil { - return "", fmt.Errorf("%s\n%s", output, err) - } - - var data map[string]string - err = json.Unmarshal([]byte(output), &data) - if err != nil { - return "", fmt.Errorf("%s\n%s", output, err) - } - - return data[key], nil -} diff --git a/vendor/github.com/bitrise-tools/go-steputils/gows.yml b/vendor/github.com/bitrise-tools/go-steputils/gows.yml deleted file mode 100644 index 7a3ee83d..00000000 --- a/vendor/github.com/bitrise-tools/go-steputils/gows.yml +++ /dev/null @@ -1 +0,0 @@ -package_name: github.com/bitrise-tools/go-steputils diff --git a/vendor/github.com/bitrise-tools/go-steputils/input/input.go b/vendor/github.com/bitrise-tools/go-steputils/input/input.go deleted file mode 100644 index 550b969d..00000000 --- a/vendor/github.com/bitrise-tools/go-steputils/input/input.go +++ /dev/null @@ -1,62 +0,0 @@ -package input - -import ( - "fmt" - - "github.com/bitrise-io/go-utils/pathutil" -) - -// ValidateIfNotEmpty ... -func ValidateIfNotEmpty(input string) error { - if input == "" { - return fmt.Errorf("parameter not specified") - } - return nil -} - -// ValidateWithOptions ... -func ValidateWithOptions(value string, options ...string) error { - if err := ValidateIfNotEmpty(value); err != nil { - return err - } - for _, option := range options { - if option == value { - return nil - } - } - return fmt.Errorf("invalid parameter: %s, available: %v", value, options) -} - -// ValidateIfPathExists ... -func ValidateIfPathExists(input string) error { - if err := ValidateIfNotEmpty(input); err != nil { - return err - } - if exist, err := pathutil.IsPathExists(input); err != nil { - return fmt.Errorf("failed to check if path exist at: %s, error: %s", input, err) - } else if !exist { - return fmt.Errorf("path not exist at: %s", input) - } - return nil -} - -// ValidateIfDirExists ... -func ValidateIfDirExists(input string) error { - if err := ValidateIfNotEmpty(input); err != nil { - return err - } - if exist, err := pathutil.IsDirExists(input); err != nil { - return fmt.Errorf("failed to check if dir exist at: %s, error: %s", input, err) - } else if !exist { - return fmt.Errorf("dir not exist at: %s", input) - } - return nil -} - -// SecureInput ... -func SecureInput(input string) string { - if input != "" { - return "***" - } - return "" -} diff --git a/vendor/github.com/bitrise-tools/go-steputils/input/input_test.go b/vendor/github.com/bitrise-tools/go-steputils/input/input_test.go deleted file mode 100644 index 91fdca69..00000000 --- a/vendor/github.com/bitrise-tools/go-steputils/input/input_test.go +++ /dev/null @@ -1,100 +0,0 @@ -package input - -import ( - "os" - "path/filepath" - "testing" - - "github.com/bitrise-io/go-utils/fileutil" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/stretchr/testify/require" -) - -func TestValidateWithOptions(t *testing.T) { - err := ValidateWithOptions("testinput", "tst0", "tst1", "testinput") - require.NoError(t, err) - - err = ValidateWithOptions("testinput", "test", "input") - require.EqualError(t, err, "invalid parameter: testinput, available: [test input]") - - err = ValidateWithOptions("testinput") - require.EqualError(t, err, "invalid parameter: testinput, available: []") - - err = ValidateWithOptions("", "param1", "param2") - require.EqualError(t, err, "parameter not specified") -} - -func TestValidateIfNotEmpty(t *testing.T) { - err := ValidateIfNotEmpty("testinput") - require.NoError(t, err) - - err = ValidateIfNotEmpty("") - require.EqualError(t, err, "parameter not specified") -} - -func TestSecureInput(t *testing.T) { - output := SecureInput("testinput") - require.Equal(t, "***", output) - - output = SecureInput("") - require.Equal(t, "", output) -} - -func TestValidateIfPathExists(t *testing.T) { - tmpDir, err := pathutil.NormalizedOSTempDirPath("test") - require.NoError(t, err) - defer func() { - require.NoError(t, os.RemoveAll(tmpDir)) - }() - - t.Log("no error - if dir exist") - { - err := ValidateIfPathExists(tmpDir) - require.NoError(t, err) - } - - t.Log("no error - if file exist") - { - pth := filepath.Join(tmpDir, "test") - require.NoError(t, fileutil.WriteStringToFile(pth, "")) - - err := ValidateIfPathExists(pth) - require.NoError(t, err) - } - - t.Log("error - if path does not exist") - { - err := ValidateIfPathExists("/not/exists/for/sure") - require.EqualError(t, err, "path not exist at: /not/exists/for/sure") - } -} - -func TestValidateIfDirExists(t *testing.T) { - tmpDir, err := pathutil.NormalizedOSTempDirPath("test") - require.NoError(t, err) - defer func() { - require.NoError(t, os.RemoveAll(tmpDir)) - }() - - t.Log("no error - if dir exist") - { - err := ValidateIfDirExists(tmpDir) - require.NoError(t, err) - } - - t.Log("error - if dir does not exist") - { - err := ValidateIfDirExists("/not/exists/for/sure") - require.EqualError(t, err, "dir not exist at: /not/exists/for/sure") - } - - t.Log("error - if path is a file path") - { - pth := filepath.Join(tmpDir, "test") - require.NoError(t, fileutil.WriteStringToFile(pth, "")) - - err := ValidateIfDirExists(pth) - require.EqualError(t, err, "dir not exist at: "+pth) - } - -} diff --git a/vendor/github.com/bitrise-tools/go-steputils/output/output.go b/vendor/github.com/bitrise-tools/go-steputils/output/output.go deleted file mode 100644 index 273096cd..00000000 --- a/vendor/github.com/bitrise-tools/go-steputils/output/output.go +++ /dev/null @@ -1,90 +0,0 @@ -package output - -import ( - "fmt" - "path/filepath" - - "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-io/go-utils/fileutil" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/bitrise-io/go-utils/ziputil" - "github.com/bitrise-tools/go-steputils/tools" -) - -// ExportOutputDir ... -func ExportOutputDir(sourceDir, destinationDir, envKey string) error { - absSourceDir, err := pathutil.AbsPath(sourceDir) - if err != nil { - return err - } - - absDestinationDir, err := pathutil.AbsPath(destinationDir) - if err != nil { - return err - } - - if absSourceDir != absDestinationDir { - if err := command.CopyDir(absSourceDir, absDestinationDir, true); err != nil { - return err - } - } - return tools.ExportEnvironmentWithEnvman(envKey, absDestinationDir) -} - -// ExportOutputFile ... -func ExportOutputFile(sourcePth, destinationPth, envKey string) error { - absSourcePth, err := pathutil.AbsPath(sourcePth) - if err != nil { - return err - } - - absDestinationPth, err := pathutil.AbsPath(destinationPth) - if err != nil { - return err - } - - if absSourcePth != absDestinationPth { - if err := command.CopyFile(absSourcePth, absDestinationPth); err != nil { - return err - } - } - return tools.ExportEnvironmentWithEnvman(envKey, absDestinationPth) -} - -// ExportOutputFileContent ... -func ExportOutputFileContent(content, destinationPth, envKey string) error { - if err := fileutil.WriteStringToFile(destinationPth, content); err != nil { - return err - } - - return ExportOutputFile(destinationPth, destinationPth, envKey) -} - -// ZipAndExportOutput ... -func ZipAndExportOutput(sourcePth, destinationZipPth, envKey string) error { - tmpDir, err := pathutil.NormalizedOSTempDirPath("__export_tmp_dir__") - if err != nil { - return err - } - - base := filepath.Base(sourcePth) - tmpZipFilePth := filepath.Join(tmpDir, base+".zip") - - if exist, err := pathutil.IsDirExists(sourcePth); err != nil { - return err - } else if exist { - if err := ziputil.ZipDir(sourcePth, tmpZipFilePth, false); err != nil { - return err - } - } else if exist, err := pathutil.IsPathExists(sourcePth); err != nil { - return err - } else if exist { - if err := ziputil.ZipFile(sourcePth, tmpZipFilePth); err != nil { - return err - } - } else { - return fmt.Errorf("source path (%s) not exists", sourcePth) - } - - return ExportOutputFile(tmpZipFilePth, destinationZipPth, envKey) -} diff --git a/vendor/github.com/bitrise-tools/go-steputils/output/output_test.go b/vendor/github.com/bitrise-tools/go-steputils/output/output_test.go deleted file mode 100644 index 38b4fadd..00000000 --- a/vendor/github.com/bitrise-tools/go-steputils/output/output_test.go +++ /dev/null @@ -1,184 +0,0 @@ -package output - -import ( - "os" - "path/filepath" - "strings" - "testing" - - "github.com/bitrise-io/go-utils/envutil" - "github.com/bitrise-io/go-utils/fileutil" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/stretchr/testify/require" -) - -func TestZipAndExportOutputDir(t *testing.T) { - tmpDir, err := pathutil.NormalizedOSTempDirPath("test") - require.NoError(t, err) - - // envman export requires an envstore - revokeFn, err := pathutil.RevokableChangeDir(tmpDir) - require.NoError(t, err) - defer func() { - require.NoError(t, revokeFn()) - }() - - tmpEnvStorePth := filepath.Join(tmpDir, ".envstore.yml") - require.NoError(t, fileutil.WriteStringToFile(tmpEnvStorePth, "")) - - envstoreRevokeFn, err := envutil.RevokableSetenv("ENVMAN_ENVSTORE_PATH", tmpEnvStorePth) - require.NoError(t, err) - defer func() { - require.NoError(t, envstoreRevokeFn()) - }() - // --- - - sourceDir := filepath.Join(tmpDir, "source") - require.NoError(t, os.MkdirAll(sourceDir, 0777)) - - destinationZip := filepath.Join(tmpDir, "destination.zip") - - envKey := "EXPORTED_ZIP_PATH" - require.NoError(t, ZipAndExportOutput(sourceDir, destinationZip, envKey)) - - // destination should exist - exist, err := pathutil.IsPathExists(destinationZip) - require.NoError(t, err) - require.Equal(t, true, exist, tmpDir) - - // destination should be exported - envstoreContent, err := fileutil.ReadStringFromFile(tmpEnvStorePth) - require.NoError(t, err) - t.Logf("envstoreContent: %s\n", envstoreContent) - require.Equal(t, true, strings.Contains(envstoreContent, "- "+envKey+": "+destinationZip), envstoreContent) -} - -func TestExportOutputFileContent(t *testing.T) { - tmpDir, err := pathutil.NormalizedOSTempDirPath("test") - require.NoError(t, err) - - // envman export requires an envstore - revokeFn, err := pathutil.RevokableChangeDir(tmpDir) - require.NoError(t, err) - defer func() { - require.NoError(t, revokeFn()) - }() - - tmpEnvStorePth := filepath.Join(tmpDir, ".envstore.yml") - require.NoError(t, fileutil.WriteStringToFile(tmpEnvStorePth, "")) - - envstoreRevokeFn, err := envutil.RevokableSetenv("ENVMAN_ENVSTORE_PATH", tmpEnvStorePth) - require.NoError(t, err) - defer func() { - require.NoError(t, envstoreRevokeFn()) - }() - // --- - - sourceFileContent := "test" - - destinationFile := filepath.Join(tmpDir, "destination") - - envKey := "EXPORTED_FILE_PATH" - require.NoError(t, ExportOutputFileContent(sourceFileContent, destinationFile, envKey)) - - // destination should exist - exist, err := pathutil.IsPathExists(destinationFile) - require.NoError(t, err) - require.Equal(t, true, exist) - - // destination should contain the source content - content, err := fileutil.ReadStringFromFile(destinationFile) - require.NoError(t, err) - require.Equal(t, sourceFileContent, content) - - // destination should be exported - envstoreContent, err := fileutil.ReadStringFromFile(os.Getenv("ENVMAN_ENVSTORE_PATH")) - require.NoError(t, err) - require.Equal(t, true, strings.Contains(envstoreContent, "- "+envKey+": "+destinationFile), envstoreContent) - - require.NoError(t, revokeFn()) -} - -func TestExportOutputFile(t *testing.T) { - tmpDir, err := pathutil.NormalizedOSTempDirPath("test") - require.NoError(t, err) - - // envman export requires an envstore - revokeFn, err := pathutil.RevokableChangeDir(tmpDir) - require.NoError(t, err) - defer func() { - require.NoError(t, revokeFn()) - }() - - tmpEnvStorePth := filepath.Join(tmpDir, ".envstore.yml") - require.NoError(t, fileutil.WriteStringToFile(tmpEnvStorePth, "")) - - envstoreRevokeFn, err := envutil.RevokableSetenv("ENVMAN_ENVSTORE_PATH", tmpEnvStorePth) - require.NoError(t, err) - defer func() { - require.NoError(t, envstoreRevokeFn()) - }() - // --- - - sourceFile := filepath.Join(tmpDir, "source") - require.NoError(t, fileutil.WriteStringToFile(sourceFile, "")) - - destinationFile := filepath.Join(tmpDir, "destination") - - envKey := "EXPORTED_FILE_PATH" - require.NoError(t, ExportOutputFile(sourceFile, destinationFile, envKey)) - - // destination should exist - exist, err := pathutil.IsPathExists(destinationFile) - require.NoError(t, err) - require.Equal(t, true, exist) - - // destination should be exported - envstoreContent, err := fileutil.ReadStringFromFile(os.Getenv("ENVMAN_ENVSTORE_PATH")) - require.NoError(t, err) - require.Equal(t, true, strings.Contains(envstoreContent, "- "+envKey+": "+destinationFile), envstoreContent) - - require.NoError(t, revokeFn()) -} - -func TestExportOutputDir(t *testing.T) { - tmpDir, err := pathutil.NormalizedOSTempDirPath("test") - require.NoError(t, err) - - // envman export requires an envstore - revokeFn, err := pathutil.RevokableChangeDir(tmpDir) - require.NoError(t, err) - defer func() { - require.NoError(t, revokeFn()) - }() - - tmpEnvStorePth := filepath.Join(tmpDir, ".envstore.yml") - require.NoError(t, fileutil.WriteStringToFile(tmpEnvStorePth, "")) - - envstoreRevokeFn, err := envutil.RevokableSetenv("ENVMAN_ENVSTORE_PATH", tmpEnvStorePth) - require.NoError(t, err) - defer func() { - require.NoError(t, envstoreRevokeFn()) - }() - // --- - - sourceDir := filepath.Join(tmpDir, "source") - require.NoError(t, os.MkdirAll(sourceDir, 0777)) - - destinationDir := filepath.Join(tmpDir, "destination") - - envKey := "EXPORTED_DIR_PATH" - require.NoError(t, ExportOutputDir(sourceDir, destinationDir, envKey)) - - // destination should exist - exist, err := pathutil.IsDirExists(destinationDir) - require.NoError(t, err) - require.Equal(t, true, exist) - - // destination should be exported - envstoreContent, err := fileutil.ReadStringFromFile(os.Getenv("ENVMAN_ENVSTORE_PATH")) - require.NoError(t, err) - require.Equal(t, true, strings.Contains(envstoreContent, "- "+envKey+": "+destinationDir), envstoreContent) - - require.NoError(t, revokeFn()) -} diff --git a/vendor/github.com/bitrise-tools/go-steputils/tools/tools_test.go b/vendor/github.com/bitrise-tools/go-steputils/tools/tools_test.go deleted file mode 100644 index 572cee9a..00000000 --- a/vendor/github.com/bitrise-tools/go-steputils/tools/tools_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package tools - -import ( - "fmt" - "path/filepath" - "testing" - - "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-io/go-utils/envutil" - "github.com/bitrise-io/go-utils/fileutil" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/stretchr/testify/require" -) - -func TestExportEnvironmentWithEnvman(t *testing.T) { - key := "ExportEnvironmentWithEnvmanKey" - - tmpDir, err := pathutil.NormalizedOSTempDirPath("test") - require.NoError(t, err) - - // envman export requires an envstore - revokeFn, err := pathutil.RevokableChangeDir(tmpDir) - require.NoError(t, err) - defer func() { - require.NoError(t, revokeFn()) - }() - - tmpEnvStorePth := filepath.Join(tmpDir, ".envstore.yml") - require.NoError(t, fileutil.WriteStringToFile(tmpEnvStorePth, "")) - - envstoreRevokeFn, err := envutil.RevokableSetenv("ENVMAN_ENVSTORE_PATH", tmpEnvStorePth) - require.NoError(t, err) - defer func() { - require.NoError(t, envstoreRevokeFn()) - }() - // --- - - { - // envstor should be clear - cmd := command.New("envman", "print") - out, err := cmd.RunAndReturnTrimmedCombinedOutput() - require.NoError(t, err, out) - require.Equal(t, "", out) - } - - value := "test" - require.NoError(t, ExportEnvironmentWithEnvman(key, value)) - - // envstore should contain ExportEnvironmentWithEnvmanKey env var - cmd := command.New("envman", "print") - out, err := cmd.RunAndReturnTrimmedCombinedOutput() - require.NoError(t, err, out) - require.Equal(t, fmt.Sprintf("%s: %s", key, value), out) -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/.gitignore b/vendor/github.com/bitrise-tools/go-xcode/.gitignore deleted file mode 100644 index d722bf25..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/.gitignore +++ /dev/null @@ -1 +0,0 @@ -_tmp/ diff --git a/vendor/github.com/bitrise-tools/go-xcode/README.md b/vendor/github.com/bitrise-tools/go-xcode/README.md deleted file mode 100644 index ecf777bc..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/README.md +++ /dev/null @@ -1 +0,0 @@ -# go-xcode diff --git a/vendor/github.com/bitrise-tools/go-xcode/_tests/integration/ipa_test.go b/vendor/github.com/bitrise-tools/go-xcode/_tests/integration/ipa_test.go deleted file mode 100644 index c0fcbf2a..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/_tests/integration/ipa_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package integration - -import ( - "testing" - - "path/filepath" - - "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/bitrise-tools/go-xcode/ipa" - "github.com/stretchr/testify/require" -) - -const ( - sampleArtifactsGitURI = "https://github.com/bitrise-samples/sample-artifacts.git" -) - -func testIpasDirPth(t *testing.T) string { - tmpDir, err := pathutil.NormalizedOSTempDirPath("__ipa__") - require.NoError(t, err) - - cmd := command.New("git", "clone", sampleArtifactsGitURI, tmpDir) - require.NoError(t, cmd.Run()) - - ipasDir := filepath.Join(tmpDir, "ipas") - exist, err := pathutil.IsDirExists(ipasDir) - require.NoError(t, err, tmpDir) - require.Equal(t, true, exist, tmpDir) - - return ipasDir -} - -func TestIPAPackage(t *testing.T) { - ipasDirPth := testIpasDirPth(t) - - t.Log("multiple files zipped in ipa") - { - ipaPth := filepath.Join(ipasDirPth, "watch-test.ipa") - - embeddedMobileProvisionPth, err := ipa.UnwrapEmbeddedMobileProvision(ipaPth) - require.NoError(t, err) - require.NotEqual(t, "", embeddedMobileProvisionPth) - - infoPlistPth, err := ipa.UnwrapEmbeddedInfoPlist(ipaPth) - require.NoError(t, err) - require.NotEqual(t, "", infoPlistPth) - } - - t.Log("ipa file name != embedded app file name") - { - ipaPth := filepath.Join(ipasDirPth, "app-store-watch-test.ipa") - - embeddedMobileProvisionPth, err := ipa.UnwrapEmbeddedMobileProvision(ipaPth) - require.NoError(t, err) - require.NotEqual(t, "", embeddedMobileProvisionPth) - - infoPlistPth, err := ipa.UnwrapEmbeddedInfoPlist(ipaPth) - require.NoError(t, err) - require.NotEqual(t, "", infoPlistPth) - } -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/bitrise.yml b/vendor/github.com/bitrise-tools/go-xcode/bitrise.yml deleted file mode 100755 index 1fae62f7..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/bitrise.yml +++ /dev/null @@ -1,95 +0,0 @@ -format_version: 1.0.0 -default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git - -app: - envs: - -workflows: - ci: - before_run: - - _install_test_tools - - test - - test: - after_run: - - integration-test - steps: - - script: - title: Export go files to test - inputs: - - content: |- - #!/bin/bash - set -ex - - no_vendor_paths="$(go list ./... | grep -v vendor)" - envman add --key GOLIST_WITHOUT_VENDOR --value "$no_vendor_paths" - - script: - title: Err check - inputs: - - content: |- - #!/bin/bash - set -ex - - errcheck -asserts=true -blank=true $GOLIST_WITHOUT_VENDOR - - script: - title: Go lint - inputs: - - content: |- - #!/bin/bash - set -ex - - while read -r line; do - echo "-> Linting: $line" - golint_out="$(golint $line)" - if [[ "${golint_out}" != "" ]] ; then - echo "=> Golint issues found:" - echo "${golint_out}" - exit 1 - fi - done <<< "$GOLIST_WITHOUT_VENDOR" - - script: - title: Go test - inputs: - - content: |- - #!/bin/bash - set -ex - - go test ./... - - integration-test: - after_run: - steps: - - script: - title: Run integration tests - inputs: - - content: |- - #!/bin/bash - echo "Running integration tests ..." - set -ex - - go test -v ./_tests/integration/... - - _install_test_tools: - steps: - - script: - title: Install required testing tools - inputs: - - content: |- - #!/bin/bash - set -ex - - # Check for unhandled errors - go get -u -v github.com/kisielk/errcheck - - # Go lint - go get -u -v github.com/golang/lint/golint - - go get -u -v github.com/stretchr/testify/require - go get -u -v github.com/bitrise-io/go-utils/fileutil - go get -u -v github.com/bitrise-io/go-utils/pathutil - go get -u -v github.com/bitrise-io/go-utils/command - go get -u -v github.com/hashicorp/go-version - go get -u -v howett.net/plist - go get -u -v github.com/pkg/errors - go get -u -v github.com/fullsailor/pkcs7 - go get -u -v github.com/ryanuber/go-glob diff --git a/vendor/github.com/bitrise-tools/go-xcode/export/export.go b/vendor/github.com/bitrise-tools/go-xcode/export/export.go deleted file mode 100644 index e35a5ec6..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/export/export.go +++ /dev/null @@ -1,357 +0,0 @@ -package export - -import ( - "fmt" - "sort" - - "github.com/bitrise-tools/go-xcode/certificateutil" - "github.com/bitrise-tools/go-xcode/plistutil" - "github.com/bitrise-tools/go-xcode/profileutil" - "github.com/ryanuber/go-glob" -) - -func isCertificateInstalled(installedCertificates []certificateutil.CertificateInfoModel, certificate certificateutil.CertificateInfoModel) bool { - installedMap := map[string]bool{} - for _, certificate := range installedCertificates { - installedMap[certificate.Serial] = true - } - return installedMap[certificate.Serial] -} - -// CertificateProfilesGroup ... -type CertificateProfilesGroup struct { - Certificate certificateutil.CertificateInfoModel - Profiles []profileutil.ProvisioningProfileInfoModel -} - -func createCertificateProfilesGroups(certificates []certificateutil.CertificateInfoModel, profiles []profileutil.ProvisioningProfileInfoModel) []CertificateProfilesGroup { - serialProfilesMap := map[string][]profileutil.ProvisioningProfileInfoModel{} - serialCertificateMap := map[string]certificateutil.CertificateInfoModel{} - for _, profile := range profiles { - for _, certificate := range profile.DeveloperCertificates { - if !isCertificateInstalled(certificates, certificate) { - continue - } - - certificateProfiles := serialProfilesMap[certificate.Serial] - if certificateProfiles == nil { - certificateProfiles = []profileutil.ProvisioningProfileInfoModel{} - } - certificateProfiles = append(certificateProfiles, profile) - serialProfilesMap[certificate.Serial] = certificateProfiles - serialCertificateMap[certificate.Serial] = certificate - } - } - - groups := []CertificateProfilesGroup{} - for serial, profiles := range serialProfilesMap { - certificate := serialCertificateMap[serial] - group := CertificateProfilesGroup{ - Certificate: certificate, - Profiles: profiles, - } - groups = append(groups, group) - } - - return groups -} - -// SelectableCodeSignGroup .. -type SelectableCodeSignGroup struct { - Certificate certificateutil.CertificateInfoModel - BundleIDProfilesMap map[string][]profileutil.ProvisioningProfileInfoModel -} - -func createSelectableCodeSignGroups(certificateProfilesGroups []CertificateProfilesGroup, bundleIDCapabilitiesMap map[string]plistutil.PlistData) []SelectableCodeSignGroup { - groups := []SelectableCodeSignGroup{} - - for _, certificateProfilesGroup := range certificateProfilesGroups { - certificate := certificateProfilesGroup.Certificate - profiles := certificateProfilesGroup.Profiles - - bundleIDProfilesMap := map[string][]profileutil.ProvisioningProfileInfoModel{} - for bundleID, capabilities := range bundleIDCapabilitiesMap { - - matchingProfiles := []profileutil.ProvisioningProfileInfoModel{} - for _, profile := range profiles { - if !glob.Glob(profile.BundleID, bundleID) { - continue - } - - if missingCapabilities := profileutil.MatchTargetAndProfileEntitlements(capabilities, profile.Entitlements); len(missingCapabilities) > 0 { - continue - } - - matchingProfiles = append(matchingProfiles, profile) - } - - if len(matchingProfiles) > 0 { - sort.Sort(ByBundleIDLength(matchingProfiles)) - bundleIDProfilesMap[bundleID] = matchingProfiles - } - } - - if len(bundleIDProfilesMap) == len(bundleIDCapabilitiesMap) { - group := SelectableCodeSignGroup{ - Certificate: certificate, - BundleIDProfilesMap: bundleIDProfilesMap, - } - groups = append(groups, group) - } - } - - return groups -} - -// ResolveSelectableCodeSignGroups ... -func ResolveSelectableCodeSignGroups(certificates []certificateutil.CertificateInfoModel, profiles []profileutil.ProvisioningProfileInfoModel, bundleIDCapabilities map[string]plistutil.PlistData) []SelectableCodeSignGroup { - certificateProfilesGroups := createCertificateProfilesGroups(certificates, profiles) - return createSelectableCodeSignGroups(certificateProfilesGroups, bundleIDCapabilities) -} - -// CodeSignGroup ... -type CodeSignGroup struct { - Certificate certificateutil.CertificateInfoModel - BundleIDProfileMap map[string]profileutil.ProvisioningProfileInfoModel -} - -func createCodeSignGroups(selectableGroups []SelectableCodeSignGroup) []CodeSignGroup { - alreadyUsedProfileUUIDMap := map[string]bool{} - - singleWildcardGroups := []CodeSignGroup{} - xcodeManagedGroups := []CodeSignGroup{} - notXcodeManagedGroups := []CodeSignGroup{} - remainingGroups := []CodeSignGroup{} - - for _, selectableGroup := range selectableGroups { - certificate := selectableGroup.Certificate - bundleIDProfilesMap := selectableGroup.BundleIDProfilesMap - - bundleIDs := []string{} - profiles := []profileutil.ProvisioningProfileInfoModel{} - for bundleID, matchingProfiles := range bundleIDProfilesMap { - bundleIDs = append(bundleIDs, bundleID) - profiles = append(profiles, matchingProfiles...) - } - - // - // create groups with single wildcard profiles - { - for _, profile := range profiles { - if alreadyUsedProfileUUIDMap[profile.UUID] { - continue - } - - matchesForAllBundleID := true - for _, bundleID := range bundleIDs { - if !glob.Glob(profile.BundleID, bundleID) { - matchesForAllBundleID = false - break - } - } - if matchesForAllBundleID { - bundleIDProfileMap := map[string]profileutil.ProvisioningProfileInfoModel{} - for _, bundleID := range bundleIDs { - bundleIDProfileMap[bundleID] = profile - } - - group := CodeSignGroup{ - Certificate: certificate, - BundleIDProfileMap: bundleIDProfileMap, - } - singleWildcardGroups = append(singleWildcardGroups, group) - - alreadyUsedProfileUUIDMap[profile.UUID] = true - } - } - } - - // - // create groups with xcode managed profiles - { - // collect xcode managed profiles - xcodeManagedProfiles := []profileutil.ProvisioningProfileInfoModel{} - for _, profile := range profiles { - if !alreadyUsedProfileUUIDMap[profile.UUID] && profile.IsXcodeManaged() { - xcodeManagedProfiles = append(xcodeManagedProfiles, profile) - } - } - sort.Sort(ByBundleIDLength(xcodeManagedProfiles)) - - // map profiles to bundle ids + remove the already used profiles - bundleIDMannagedProfilesMap := map[string][]profileutil.ProvisioningProfileInfoModel{} - for _, bundleID := range bundleIDs { - for _, profile := range xcodeManagedProfiles { - if !glob.Glob(profile.BundleID, bundleID) { - continue - } - - matchingProfiles := bundleIDMannagedProfilesMap[bundleID] - if matchingProfiles == nil { - matchingProfiles = []profileutil.ProvisioningProfileInfoModel{} - } - matchingProfiles = append(matchingProfiles, profile) - bundleIDMannagedProfilesMap[bundleID] = matchingProfiles - } - } - - if len(bundleIDMannagedProfilesMap) == len(bundleIDs) { - // if only one profile can sign a bundle id, remove it from bundleIDMannagedProfilesMap - alreadyUsedManagedProfileMap := map[string]bool{} - for _, profiles := range bundleIDMannagedProfilesMap { - if len(profiles) == 1 { - profile := profiles[0] - alreadyUsedManagedProfileMap[profile.UUID] = true - } - } - - bundleIDMannagedProfileMap := map[string]profileutil.ProvisioningProfileInfoModel{} - for bundleID, profiles := range bundleIDMannagedProfilesMap { - if len(profiles) == 1 { - bundleIDMannagedProfileMap[bundleID] = profiles[0] - } else { - remainingProfiles := []profileutil.ProvisioningProfileInfoModel{} - for _, profile := range profiles { - if !alreadyUsedManagedProfileMap[profile.UUID] { - remainingProfiles = append(remainingProfiles, profile) - } - } - if len(remainingProfiles) == 1 { - bundleIDMannagedProfileMap[bundleID] = remainingProfiles[0] - } - } - } - - // create code sign group - if len(bundleIDMannagedProfileMap) == len(bundleIDs) { - for _, profile := range bundleIDMannagedProfileMap { - alreadyUsedProfileUUIDMap[profile.UUID] = true - } - - group := CodeSignGroup{ - Certificate: certificate, - BundleIDProfileMap: bundleIDMannagedProfileMap, - } - xcodeManagedGroups = append(xcodeManagedGroups, group) - } - } - } - - // - // create groups with NOT xcode managed profiles - { - // collect xcode managed profiles - notXcodeManagedProfiles := []profileutil.ProvisioningProfileInfoModel{} - for _, profile := range profiles { - if !alreadyUsedProfileUUIDMap[profile.UUID] && !profile.IsXcodeManaged() { - notXcodeManagedProfiles = append(notXcodeManagedProfiles, profile) - } - } - sort.Sort(ByBundleIDLength(notXcodeManagedProfiles)) - - // map profiles to bundle ids + remove the already used profiles - bundleIDNotMannagedProfilesMap := map[string][]profileutil.ProvisioningProfileInfoModel{} - for _, bundleID := range bundleIDs { - for _, profile := range notXcodeManagedProfiles { - if !glob.Glob(profile.BundleID, bundleID) { - continue - } - - matchingProfiles := bundleIDNotMannagedProfilesMap[bundleID] - if matchingProfiles == nil { - matchingProfiles = []profileutil.ProvisioningProfileInfoModel{} - } - matchingProfiles = append(matchingProfiles, profile) - bundleIDNotMannagedProfilesMap[bundleID] = matchingProfiles - } - } - - if len(bundleIDNotMannagedProfilesMap) == len(bundleIDs) { - // if only one profile can sign a bundle id, remove it from bundleIDNotMannagedProfilesMap - alreadyUsedNotManagedProfileMap := map[string]bool{} - for _, profiles := range bundleIDNotMannagedProfilesMap { - if len(profiles) == 1 { - profile := profiles[0] - alreadyUsedNotManagedProfileMap[profile.UUID] = true - } - } - - bundleIDNotMannagedProfileMap := map[string]profileutil.ProvisioningProfileInfoModel{} - for bundleID, profiles := range bundleIDNotMannagedProfilesMap { - if len(profiles) == 1 { - bundleIDNotMannagedProfileMap[bundleID] = profiles[0] - } else { - remainingProfiles := []profileutil.ProvisioningProfileInfoModel{} - for _, profile := range profiles { - if !alreadyUsedNotManagedProfileMap[profile.UUID] { - remainingProfiles = append(remainingProfiles, profile) - } - } - if len(remainingProfiles) == 1 { - bundleIDNotMannagedProfileMap[bundleID] = remainingProfiles[0] - } - } - } - - // create code sign group - if len(bundleIDNotMannagedProfileMap) == len(bundleIDs) { - for _, profile := range bundleIDNotMannagedProfileMap { - alreadyUsedProfileUUIDMap[profile.UUID] = true - } - - codeSignGroup := CodeSignGroup{ - Certificate: certificate, - BundleIDProfileMap: bundleIDNotMannagedProfileMap, - } - notXcodeManagedGroups = append(notXcodeManagedGroups, codeSignGroup) - } - } - } - - // - // if there are remaining profiles we create a not exact group by using the first matching profile for every bundle id - { - if len(alreadyUsedProfileUUIDMap) != len(profiles) { - bundleIDProfileMap := map[string]profileutil.ProvisioningProfileInfoModel{} - for _, bundleID := range bundleIDs { - for _, profile := range profiles { - if alreadyUsedProfileUUIDMap[profile.UUID] { - continue - } - - if !glob.Glob(profile.BundleID, bundleID) { - continue - } - - bundleIDProfileMap[bundleID] = profile - break - } - } - - if len(bundleIDProfileMap) == len(bundleIDs) { - group := CodeSignGroup{ - Certificate: certificate, - BundleIDProfileMap: bundleIDProfileMap, - } - remainingGroups = append(remainingGroups, group) - } - } - } - - fmt.Println() - } - - codeSignGroups := []CodeSignGroup{} - codeSignGroups = append(codeSignGroups, notXcodeManagedGroups...) - codeSignGroups = append(codeSignGroups, xcodeManagedGroups...) - codeSignGroups = append(codeSignGroups, singleWildcardGroups...) - codeSignGroups = append(codeSignGroups, remainingGroups...) - - return codeSignGroups -} - -// ResolveCodeSignGroups ... -func ResolveCodeSignGroups(certificates []certificateutil.CertificateInfoModel, profiles []profileutil.ProvisioningProfileInfoModel, bundleIDCapabilities map[string]plistutil.PlistData) []CodeSignGroup { - selectableCodeSignGroups := ResolveSelectableCodeSignGroups(certificates, profiles, bundleIDCapabilities) - return createCodeSignGroups(selectableCodeSignGroups) -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/export/filter.go b/vendor/github.com/bitrise-tools/go-xcode/export/filter.go deleted file mode 100644 index 1ebee90f..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/export/filter.go +++ /dev/null @@ -1,114 +0,0 @@ -package export - -import ( - "github.com/bitrise-tools/go-xcode/exportoptions" - "github.com/bitrise-tools/go-xcode/profileutil" -) - -// FilterSelectableCodeSignGroupsForTeam ... -func FilterSelectableCodeSignGroupsForTeam(codeSignGroups []SelectableCodeSignGroup, teamID string) []SelectableCodeSignGroup { - filteredGroups := []SelectableCodeSignGroup{} - for _, group := range codeSignGroups { - if group.Certificate.TeamID == teamID { - filteredGroups = append(filteredGroups, group) - } - } - return filteredGroups -} - -// FilterSelectableCodeSignGroupsForExportMethod ... -func FilterSelectableCodeSignGroupsForExportMethod(codeSignGroups []SelectableCodeSignGroup, exportMethod exportoptions.Method) []SelectableCodeSignGroup { - filteredGroups := []SelectableCodeSignGroup{} - for _, group := range codeSignGroups { - - bundleIDProfilesMap := map[string][]profileutil.ProvisioningProfileInfoModel{} - for bundleID, profiles := range group.BundleIDProfilesMap { - matchingProfiles := []profileutil.ProvisioningProfileInfoModel{} - for _, profile := range profiles { - if profile.ExportType == exportMethod { - matchingProfiles = append(matchingProfiles, profile) - } - } - if len(matchingProfiles) > 0 { - bundleIDProfilesMap[bundleID] = profiles - } - } - - if len(bundleIDProfilesMap) == len(group.BundleIDProfilesMap) { - filteredGroups = append(filteredGroups, group) - } - } - return filteredGroups -} - -// FilterSelectableCodeSignGroupsForNotXcodeManagedProfiles ... -func FilterSelectableCodeSignGroupsForNotXcodeManagedProfiles(codeSignGroups []SelectableCodeSignGroup) []SelectableCodeSignGroup { - filteredGroups := []SelectableCodeSignGroup{} - for _, group := range codeSignGroups { - - bundleIDNotManagedProfilesMap := map[string][]profileutil.ProvisioningProfileInfoModel{} - for bundleID, profiles := range group.BundleIDProfilesMap { - notManagedProfiles := []profileutil.ProvisioningProfileInfoModel{} - for _, profile := range profiles { - if !profile.IsXcodeManaged() { - notManagedProfiles = append(notManagedProfiles, profile) - } - } - if len(notManagedProfiles) > 0 { - bundleIDNotManagedProfilesMap[bundleID] = profiles - } - } - - if len(bundleIDNotManagedProfilesMap) == len(group.BundleIDProfilesMap) { - filteredGroups = append(filteredGroups, group) - } - } - return filteredGroups -} - -// FilterCodeSignGroupsForTeam ... -func FilterCodeSignGroupsForTeam(codeSignGroups []CodeSignGroup, teamID string) []CodeSignGroup { - filteredGroups := []CodeSignGroup{} - for _, group := range codeSignGroups { - if group.Certificate.TeamID == teamID { - filteredGroups = append(filteredGroups, group) - } - } - return filteredGroups -} - -// FilterCodeSignGroupsForExportMethod ... -func FilterCodeSignGroupsForExportMethod(codeSignGroups []CodeSignGroup, exportMethod exportoptions.Method) []CodeSignGroup { - filteredGroups := []CodeSignGroup{} - for _, group := range codeSignGroups { - matchingGroup := true - for _, profile := range group.BundleIDProfileMap { - if profile.ExportType != exportMethod { - matchingGroup = false - break - } - } - if matchingGroup { - filteredGroups = append(filteredGroups, group) - } - } - return filteredGroups -} - -// FilterCodeSignGroupsForNotXcodeManagedProfiles ... -func FilterCodeSignGroupsForNotXcodeManagedProfiles(codeSignGroups []CodeSignGroup) []CodeSignGroup { - filteredGroups := []CodeSignGroup{} - for _, group := range codeSignGroups { - xcodeManagedGroup := false - for _, profile := range group.BundleIDProfileMap { - if profile.IsXcodeManaged() { - xcodeManagedGroup = true - break - } - } - if !xcodeManagedGroup { - filteredGroups = append(filteredGroups, group) - } - } - return filteredGroups -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/export/profile.go b/vendor/github.com/bitrise-tools/go-xcode/export/profile.go deleted file mode 100644 index 0976ccd0..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/export/profile.go +++ /dev/null @@ -1,75 +0,0 @@ -package export - -import ( - "io" - "net/http" - "os" - "path/filepath" - - "github.com/bitrise-io/go-utils/log" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/bitrise-tools/go-xcode/profileutil" -) - -// ByBundleIDLength ... -type ByBundleIDLength []profileutil.ProvisioningProfileInfoModel - -// Len .. -func (s ByBundleIDLength) Len() int { - return len(s) -} - -// Swap ... -func (s ByBundleIDLength) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -// Less ... -func (s ByBundleIDLength) Less(i, j int) bool { - return len(s[i].BundleID) > len(s[j].BundleID) -} - -// GetDefaultProvisioningProfile ... -func GetDefaultProvisioningProfile() (profileutil.ProvisioningProfileInfoModel, error) { - defaultProfileURL := os.Getenv("BITRISE_DEFAULT_PROVISION_URL") - if defaultProfileURL == "" { - return profileutil.ProvisioningProfileInfoModel{}, nil - } - - tmpDir, err := pathutil.NormalizedOSTempDirPath("tmp_default_profile") - if err != nil { - return profileutil.ProvisioningProfileInfoModel{}, err - } - - tmpDst := filepath.Join(tmpDir, "default.mobileprovision") - tmpDstFile, err := os.Create(tmpDst) - if err != nil { - return profileutil.ProvisioningProfileInfoModel{}, err - } - defer func() { - if err := tmpDstFile.Close(); err != nil { - log.Errorf("Failed to close file (%s), error: %s", tmpDst, err) - } - }() - - response, err := http.Get(defaultProfileURL) - if err != nil { - return profileutil.ProvisioningProfileInfoModel{}, err - } - defer func() { - if err := response.Body.Close(); err != nil { - log.Errorf("Failed to close response body, error: %s", err) - } - }() - - if _, err := io.Copy(tmpDstFile, response.Body); err != nil { - return profileutil.ProvisioningProfileInfoModel{}, err - } - - defaultProfile, err := profileutil.NewProvisioningProfileInfoFromFile(tmpDst) - if err != nil { - return profileutil.ProvisioningProfileInfoModel{}, err - } - - return defaultProfile, nil -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/exportoptions/exportoptions_test.go b/vendor/github.com/bitrise-tools/go-xcode/exportoptions/exportoptions_test.go deleted file mode 100644 index 95eac67a..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/exportoptions/exportoptions_test.go +++ /dev/null @@ -1,407 +0,0 @@ -package exportoptions - -import ( - "path/filepath" - "testing" - - "github.com/bitrise-io/go-utils/fileutil" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/stretchr/testify/require" -) - -func TestManifestIsEmpty(t *testing.T) { - t.Log("returns true if empty manifest") - { - manifest := Manifest{} - require.Equal(t, true, manifest.IsEmpty()) - } - - t.Log("returns false if not empty manifest") - { - manifest := Manifest{ - AppURL: "appURL", - } - require.Equal(t, false, manifest.IsEmpty()) - } - { - manifest := Manifest{ - DisplayImageURL: "displayImageURL", - } - require.Equal(t, false, manifest.IsEmpty()) - } - { - manifest := Manifest{ - FullSizeImageURL: "fullSizeImageURL.", - } - require.Equal(t, false, manifest.IsEmpty()) - } - { - manifest := Manifest{ - AssetPackManifestURL: "assetPackManifestURL.", - } - require.Equal(t, false, manifest.IsEmpty()) - } -} - -func TestManifestToHash(t *testing.T) { - t.Log("empty manifest creates empty hash") - { - manifest := Manifest{} - hash := manifest.ToHash() - require.Equal(t, 0, len(hash)) - { - value, ok := hash[ManifestAppURLKey] - require.Equal(t, false, ok) - require.Equal(t, "", value) - } - { - value, ok := hash[ManifestDisplayImageURLKey] - require.Equal(t, false, ok) - require.Equal(t, "", value) - } - { - value, ok := hash[ManifestFullSizeImageURLKey] - require.Equal(t, false, ok) - require.Equal(t, "", value) - } - { - value, ok := hash[ManifestAssetPackManifestURLKey] - require.Equal(t, false, ok) - require.Equal(t, "", value) - } - } - - t.Log("creates hash from manifest") - { - manifest := Manifest{ - AppURL: "appURL", - DisplayImageURL: "displayImageURL", - FullSizeImageURL: "fullSizeImageURL", - AssetPackManifestURL: "assetPackManifestURL", - } - hash := manifest.ToHash() - require.Equal(t, 4, len(hash)) - { - value, ok := hash[ManifestAppURLKey] - require.Equal(t, true, ok) - require.Equal(t, "appURL", value) - } - { - value, ok := hash[ManifestDisplayImageURLKey] - require.Equal(t, true, ok) - require.Equal(t, "displayImageURL", value) - } - { - value, ok := hash[ManifestFullSizeImageURLKey] - require.Equal(t, true, ok) - require.Equal(t, "fullSizeImageURL", value) - } - { - value, ok := hash[ManifestAssetPackManifestURLKey] - require.Equal(t, true, ok) - require.Equal(t, "assetPackManifestURL", value) - } - } -} - -func TestNewAppStoreOptions(t *testing.T) { - t.Log("create app-store type export options with default values") - { - options := NewAppStoreOptions() - require.Equal(t, UploadBitcodeDefault, options.UploadBitcode) - require.Equal(t, UploadSymbolsDefault, options.UploadSymbols) - } -} - -func TestAppStoreOptionsToHash(t *testing.T) { - t.Log("default app-store type options creates hash with method") - { - options := NewAppStoreOptions() - hash := options.Hash() - require.Equal(t, 1, len(hash)) - - { - value, ok := hash[MethodKey] - require.Equal(t, true, ok) - require.Equal(t, MethodAppStore, value) - } - } - - t.Log("custom app-store type option's generated hash contains all properties") - { - options := NewAppStoreOptions() - options.TeamID = "123" - options.UploadBitcode = false - options.UploadSymbols = false - - hash := options.Hash() - require.Equal(t, 4, len(hash)) - - { - value, ok := hash[MethodKey] - require.Equal(t, true, ok) - require.Equal(t, MethodAppStore, value) - } - { - value, ok := hash[TeamIDKey] - require.Equal(t, true, ok) - require.Equal(t, "123", value) - } - { - value, ok := hash[UploadBitcodeKey] - require.Equal(t, true, ok) - require.Equal(t, false, value) - } - { - value, ok := hash[UploadSymbolsKey] - require.Equal(t, true, ok) - require.Equal(t, false, value) - } - } -} - -func TestAppStoreOptionsWriteToFile(t *testing.T) { - t.Log("default app-store type options overrides only method") - { - tmpDir, err := pathutil.NormalizedOSTempDirPath("output") - require.NoError(t, err) - pth := filepath.Join(tmpDir, "exportOptions.plist") - - options := NewAppStoreOptions() - require.NoError(t, options.WriteToFile(pth)) - - content, err := fileutil.ReadStringFromFile(pth) - require.NoError(t, err) - desired := ` - - - - method - app-store - -` - require.Equal(t, desired, content) - } - - t.Log("custom app-store type options overrides all properties") - { - tmpDir, err := pathutil.NormalizedOSTempDirPath("output") - require.NoError(t, err) - pth := filepath.Join(tmpDir, "exportOptions.plist") - - options := NewAppStoreOptions() - options.TeamID = "123" - options.UploadBitcode = false - options.UploadSymbols = false - require.NoError(t, options.WriteToFile(pth)) - - content, err := fileutil.ReadStringFromFile(pth) - require.NoError(t, err) - desired := ` - - - - method - app-store - teamID - 123 - uploadBitcode - - uploadSymbols - - -` - require.Equal(t, desired, content) - } -} - -func TestNonNewAppStoreOptions(t *testing.T) { - t.Log("create NON app-store type export options with default values") - { - options := NewNonAppStoreOptions(MethodDevelopment) - require.Equal(t, MethodDevelopment, options.Method) - require.Equal(t, CompileBitcodeDefault, options.CompileBitcode) - require.Equal(t, EmbedOnDemandResourcesAssetPacksInBundleDefault, options.EmbedOnDemandResourcesAssetPacksInBundle) - require.Equal(t, ICloudContainerEnvironmentDefault, options.ICloudContainerEnvironment) - require.Equal(t, ThinningDefault, options.Thinning) - } -} - -func TestNonAppStoreOptionsToHash(t *testing.T) { - t.Log("default NON app-store type options creates hash with method") - { - options := NewNonAppStoreOptions(MethodDevelopment) - hash := options.Hash() - require.Equal(t, 1, len(hash)) - - { - value, ok := hash[MethodKey] - require.Equal(t, true, ok) - require.Equal(t, MethodDevelopment, value) - } - } - - t.Log("custom NON app-store type option's generated hash contains all properties") - { - options := NewNonAppStoreOptions(MethodEnterprise) - options.TeamID = "123" - options.CompileBitcode = false - options.EmbedOnDemandResourcesAssetPacksInBundle = false - options.ICloudContainerEnvironment = ICloudContainerEnvironmentProduction - options.OnDemandResourcesAssetPacksBaseURL = "url" - options.Thinning = ThinningThinForAllVariants - options.Manifest = Manifest{ - AppURL: "appURL", - DisplayImageURL: "displayImageURL", - FullSizeImageURL: "fullSizeImageURL", - AssetPackManifestURL: "assetPackManifestURL", - } - - hash := options.Hash() - require.Equal(t, 8, len(hash)) - - { - value, ok := hash[MethodKey] - require.Equal(t, true, ok) - require.Equal(t, MethodEnterprise, value) - } - { - value, ok := hash[TeamIDKey] - require.Equal(t, true, ok) - require.Equal(t, "123", value) - } - { - value, ok := hash[CompileBitcodeKey] - require.Equal(t, true, ok) - require.Equal(t, false, value) - } - { - value, ok := hash[EmbedOnDemandResourcesAssetPacksInBundleKey] - require.Equal(t, true, ok) - require.Equal(t, false, value) - } - { - value, ok := hash[ICloudContainerEnvironmentKey] - require.Equal(t, true, ok) - require.Equal(t, ICloudContainerEnvironmentProduction, value) - } - { - value, ok := hash[OnDemandResourcesAssetPacksBaseURLKey] - require.Equal(t, true, ok) - require.Equal(t, "url", value) - } - { - value, ok := hash[ThinningKey] - require.Equal(t, true, ok) - require.Equal(t, ThinningThinForAllVariants, value) - } - { - manifestHash, ok := hash[ManifestKey].(map[string]string) - require.Equal(t, true, ok) - require.Equal(t, 4, len(manifestHash)) - - { - value, ok := manifestHash[ManifestAppURLKey] - require.Equal(t, true, ok) - require.Equal(t, "appURL", value) - } - { - value, ok := manifestHash[ManifestDisplayImageURLKey] - require.Equal(t, true, ok) - require.Equal(t, "displayImageURL", value) - } - { - value, ok := manifestHash[ManifestFullSizeImageURLKey] - require.Equal(t, true, ok) - require.Equal(t, "fullSizeImageURL", value) - } - { - value, ok := manifestHash[ManifestAssetPackManifestURLKey] - require.Equal(t, true, ok) - require.Equal(t, "assetPackManifestURL", value) - } - } - } -} - -func TestNonAppStoreOptionsWriteToFile(t *testing.T) { - t.Log("default NON app-store type options overrides only method") - { - tmpDir, err := pathutil.NormalizedOSTempDirPath("output") - require.NoError(t, err) - pth := filepath.Join(tmpDir, "exportOptions.plist") - - options := NewNonAppStoreOptions(MethodEnterprise) - require.NoError(t, options.WriteToFile(pth)) - - content, err := fileutil.ReadStringFromFile(pth) - require.NoError(t, err) - desired := ` - - - - method - enterprise - -` - require.Equal(t, desired, content) - } - - t.Log("custom app-store type options overrides all properties") - { - tmpDir, err := pathutil.NormalizedOSTempDirPath("output") - require.NoError(t, err) - pth := filepath.Join(tmpDir, "exportOptions.plist") - - options := NewNonAppStoreOptions(MethodEnterprise) - options.TeamID = "123" - options.CompileBitcode = false - options.EmbedOnDemandResourcesAssetPacksInBundle = false - options.ICloudContainerEnvironment = ICloudContainerEnvironmentProduction - options.OnDemandResourcesAssetPacksBaseURL = "url" - options.Thinning = ThinningThinForAllVariants - options.Manifest = Manifest{ - AppURL: "appURL", - DisplayImageURL: "displayImageURL", - FullSizeImageURL: "fullSizeImageURL", - AssetPackManifestURL: "assetPackManifestURL", - } - - require.NoError(t, options.WriteToFile(pth)) - - content, err := fileutil.ReadStringFromFile(pth) - require.NoError(t, err) - desired := ` - - - - compileBitcode - - embedOnDemandResourcesAssetPacksInBundle - - iCloudContainerEnvironment - Production - manifest - - appURL - appURL - assetPackManifestURL - assetPackManifestURL - displayImageURL - displayImageURL - fullSizeImageURL - fullSizeImageURL - - method - enterprise - onDemandResourcesAssetPacksBaseURL - url - teamID - 123 - thinning - thin-for-all-variants - -` - require.Equal(t, desired, content) - } -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/gows.yml b/vendor/github.com/bitrise-tools/go-xcode/gows.yml deleted file mode 100644 index 81de1610..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/gows.yml +++ /dev/null @@ -1 +0,0 @@ -package_name: github.com/bitrise-tools/go-xcode diff --git a/vendor/github.com/bitrise-tools/go-xcode/ipa/ipa_test.go b/vendor/github.com/bitrise-tools/go-xcode/ipa/ipa_test.go deleted file mode 100644 index 1c48b029..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/ipa/ipa_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package ipa - -import ( - "testing" - - "os" - "path/filepath" - - "github.com/bitrise-io/go-utils/fileutil" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/stretchr/testify/require" -) - -func TestFindFileInPayloadDir(t *testing.T) { - t.Log("app name == ipa name") - { - tmpDir, err := pathutil.NormalizedOSTempDirPath("__ipa__") - require.NoError(t, err) - - payloadDir := filepath.Join(tmpDir, "Payload") - appDir := filepath.Join(payloadDir, "test.app") - require.NoError(t, os.MkdirAll(appDir, 0777)) - - infoPlistPth := filepath.Join(appDir, "Info.plist") - require.NoError(t, fileutil.WriteStringToFile(infoPlistPth, "")) - - pth, err := findFileInPayloadAppDir(payloadDir, "test", "Info.plist") - require.NoError(t, err) - require.Equal(t, infoPlistPth, pth) - } - - t.Log("app name != ipa name") - { - tmpDir, err := pathutil.NormalizedOSTempDirPath("__ipa__") - require.NoError(t, err) - - payloadDir := filepath.Join(tmpDir, "Payload") - appDir := filepath.Join(payloadDir, "test.app") - require.NoError(t, os.MkdirAll(appDir, 0777)) - - infoPlistPth := filepath.Join(appDir, "Info.plist") - require.NoError(t, fileutil.WriteStringToFile(infoPlistPth, "")) - - pth, err := findFileInPayloadAppDir(payloadDir, "not_test", "Info.plist") - require.NoError(t, err) - require.Equal(t, infoPlistPth, pth) - } - - t.Log("invalid .app path - extra path component") - { - tmpDir, err := pathutil.NormalizedOSTempDirPath("__ipa__") - require.NoError(t, err) - - payloadDir := filepath.Join(tmpDir, "Payload") - appDir := filepath.Join(payloadDir, "test.app/invalidcomponent") - require.NoError(t, os.MkdirAll(appDir, 0777)) - - infoPlistPth := filepath.Join(appDir, "Info.plist") - require.NoError(t, fileutil.WriteStringToFile(infoPlistPth, "")) - - pth, err := findFileInPayloadAppDir(payloadDir, "test", "Info.plist") - require.EqualError(t, err, "failed to find Info.plist") - require.Equal(t, "", pth) - } -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/plistutil/plistutil_test.go b/vendor/github.com/bitrise-tools/go-xcode/plistutil/plistutil_test.go deleted file mode 100644 index 1b9faa9b..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/plistutil/plistutil_test.go +++ /dev/null @@ -1,125 +0,0 @@ -package plistutil - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -func TestAnalyzeInfoPlist(t *testing.T) { - infoPlistData, err := NewPlistDataFromContent(infoPlistContent) - require.NoError(t, err) - - appTitle, ok := infoPlistData.GetString("CFBundleName") - require.Equal(t, true, ok) - require.Equal(t, "ios-simple-objc", appTitle) - - bundleID, _ := infoPlistData.GetString("CFBundleIdentifier") - require.Equal(t, true, ok) - require.Equal(t, "Bitrise.ios-simple-objc", bundleID) - - version, ok := infoPlistData.GetString("CFBundleShortVersionString") - require.Equal(t, true, ok) - require.Equal(t, "1.0", version) - - buildNumber, ok := infoPlistData.GetString("CFBundleVersion") - require.Equal(t, true, ok) - require.Equal(t, "1", buildNumber) - - minOSVersion, ok := infoPlistData.GetString("MinimumOSVersion") - require.Equal(t, true, ok) - require.Equal(t, "8.1", minOSVersion) - - deviceFamilyList, ok := infoPlistData.GetUInt64Array("UIDeviceFamily") - require.Equal(t, true, ok) - require.Equal(t, 2, len(deviceFamilyList)) - require.Equal(t, uint64(1), deviceFamilyList[0]) - require.Equal(t, uint64(2), deviceFamilyList[1]) -} - -func TestAnalyzeEmbeddedProfile(t *testing.T) { - profileData, err := NewPlistDataFromContent(appStoreProfileContent) - require.NoError(t, err) - - creationDate, ok := profileData.GetTime("CreationDate") - require.Equal(t, true, ok) - expectedCreationDate, err := time.Parse("2006-01-02T15:04:05Z", "2016-09-22T11:29:12Z") - require.NoError(t, err) - require.Equal(t, true, creationDate.Equal(expectedCreationDate)) - - expirationDate, ok := profileData.GetTime("ExpirationDate") - require.Equal(t, true, ok) - expectedExpirationDate, err := time.Parse("2006-01-02T15:04:05Z", "2017-09-21T13:20:06Z") - require.NoError(t, err) - require.Equal(t, true, expirationDate.Equal(expectedExpirationDate)) - - deviceUDIDList, ok := profileData.GetStringArray("ProvisionedDevices") - require.Equal(t, false, ok) - require.Equal(t, 0, len(deviceUDIDList)) - - teamName, ok := profileData.GetString("TeamName") - require.Equal(t, true, ok) - require.Equal(t, "Some Dude", teamName) - - profileName, ok := profileData.GetString("Name") - require.Equal(t, true, ok) - require.Equal(t, "Bitrise Test App Store", profileName) - - provisionsAlldevices, ok := profileData.GetBool("ProvisionsAllDevices") - require.Equal(t, false, ok) - require.Equal(t, false, provisionsAlldevices) -} - -func TestGetBool(t *testing.T) { - profileData, err := NewPlistDataFromContent(enterpriseProfileContent) - require.NoError(t, err) - - allDevices, ok := profileData.GetBool("ProvisionsAllDevices") - require.Equal(t, true, ok) - require.Equal(t, true, allDevices) -} - -func TestGetTime(t *testing.T) { - profileData, err := NewPlistDataFromContent(developmentProfileContent) - require.NoError(t, err) - - expire, ok := profileData.GetTime("ExpirationDate") - require.Equal(t, true, ok) - - // 2017-09-22T11:28:46Z - desiredExpire, err := time.Parse("2006-01-02T15:04:05Z", "2017-09-22T11:28:46Z") - require.NoError(t, err) - require.Equal(t, true, expire.Equal(desiredExpire)) -} - -func TestGetInt(t *testing.T) { - profileData, err := NewPlistDataFromContent(developmentProfileContent) - require.NoError(t, err) - - version, ok := profileData.GetUInt64("Version") - require.Equal(t, true, ok) - require.Equal(t, uint64(1), version) -} - -func TestGetStringArray(t *testing.T) { - profileData, err := NewPlistDataFromContent(developmentProfileContent) - require.NoError(t, err) - - devices, ok := profileData.GetStringArray("ProvisionedDevices") - require.Equal(t, true, ok) - require.Equal(t, 1, len(devices)) - require.Equal(t, "b138", devices[0]) -} - -func TestGetMapStringInterface(t *testing.T) { - profileData, err := NewPlistDataFromContent(developmentProfileContent) - require.NoError(t, err) - - entitlements, ok := profileData.GetMapStringInterface("Entitlements") - require.Equal(t, true, ok) - - teamID, ok := entitlements.GetString("com.apple.developer.team-identifier") - require.Equal(t, true, ok) - require.Equal(t, "9NS4", teamID) -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/profileutil/capabilities.go b/vendor/github.com/bitrise-tools/go-xcode/profileutil/capabilities.go deleted file mode 100644 index 85241673..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/profileutil/capabilities.go +++ /dev/null @@ -1,68 +0,0 @@ -package profileutil - -import ( - "github.com/bitrise-tools/go-xcode/plistutil" -) - -// MatchTargetAndProfileEntitlements ... -func MatchTargetAndProfileEntitlements(targetEntitlements plistutil.PlistData, profileEntitlements plistutil.PlistData) []string { - missingEntitlements := []string{} - for key := range targetEntitlements { - _, found := profileEntitlements[key] - if !found { - missingEntitlements = append(missingEntitlements, key) - } - } - return missingEntitlements -} - -// KnownTargetCapabilityProfileCapabilityMapping ... -var KnownTargetCapabilityProfileCapabilityMapping = map[string]interface{}{ - "com.apple.ApplePay": "com.apple.developer.in-app-payments", - "com.apple.ApplicationGroups.iOS": "com.apple.security.application-groups", - "com.apple.BackgroundModes": "", - "com.apple.DataProtection": "com.apple.developer.default-data-protection", - "com.apple.GameCenter": "", - "com.apple.HealthKit": "com.apple.developer.healthkit", - "com.apple.HomeKit": "com.apple.developer.homekit", - "com.apple.HotspotConfiguration": "com.apple.developer.networking.HotspotConfiguration", - "com.apple.InAppPurchase": "", - "com.apple.InterAppAudio": "inter-app-audio", - "com.apple.Keychain": "keychain-access-groups", - "com.apple.Maps.iOS": "", - "com.apple.Multipath": "com.apple.developer.networking.multipath", - "com.apple.NearFieldCommunicationTagReading": "com.apple.developer.nfc.readersession.formats", - "com.apple.NetworkExtensions.iOS": "com.apple.developer.networking.networkextension", - "com.apple.Push": "aps-environment", - "com.apple.SafariKeychain": "com.apple.developer.associated-domains", - "com.apple.Siri": "com.apple.developer.siri", - "com.apple.VPNLite": "com.apple.developer.networking.vpn.api", - "com.apple.WAC": "com.apple.external-accessory.wireless-configuration", - "com.apple.Wallet": "com.apple.developer.pass-type-identifiers", - "com.apple.iCloud": "com.apple.developer.icloud-container-identifiers", - - "com.apple.BackgroundModes.watchos.extension": "", - "com.apple.HealthKit.watchos": "com.apple.developer.healthkit", -} - -// KnownProfileCapabilitiesMap ... -var KnownProfileCapabilitiesMap = map[string]bool{ - "com.apple.developer.in-app-payments": true, - "com.apple.security.application-groups": true, - "com.apple.developer.default-data-protection": true, - "com.apple.developer.healthkit": true, - "com.apple.developer.homekit": true, - "com.apple.developer.networking.HotspotConfiguration": true, - "inter-app-audio": true, - "keychain-access-groups": true, - "com.apple.developer.networking.multipath": true, - "com.apple.developer.nfc.readersession.formats": true, - "com.apple.developer.networking.networkextension": true, - "aps-environment": true, - "com.apple.developer.associated-domains": true, - "com.apple.developer.siri": true, - "com.apple.developer.networking.vpn.api": true, - "com.apple.external-accessory.wireless-configuration": true, - "com.apple.developer.pass-type-identifiers": true, - "com.apple.developer.icloud-container-identifiers": true, -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/profileutil/info_model_test.go b/vendor/github.com/bitrise-tools/go-xcode/profileutil/info_model_test.go deleted file mode 100644 index f87ec03d..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/profileutil/info_model_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package profileutil - -import "testing" -import "github.com/stretchr/testify/require" - -func TestIsXcodeManaged(t *testing.T) { - xcodeManagedNames := []string{ - "XC iOS: custom.bundle.id", - "iOS Team Provisioning Profile: another.custom.bundle.id", - "iOS Team Store Provisioning Profile: my.bundle.id", - } - nonXcodeManagedNames := []string{ - "Test Profile Name", - "iOS Distribution Profile: test.bundle.id", - "iOS Dev", - } - - for _, profileName := range xcodeManagedNames { - require.Equal(t, true, IsXcodeManaged(profileName)) - } - - for _, profileName := range nonXcodeManagedNames { - require.Equal(t, false, IsXcodeManaged(profileName)) - } -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/profileutil/plist_data_test.go b/vendor/github.com/bitrise-tools/go-xcode/profileutil/plist_data_test.go deleted file mode 100644 index 796d3a44..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/profileutil/plist_data_test.go +++ /dev/null @@ -1,300 +0,0 @@ -package profileutil - -import ( - "testing" - - "github.com/bitrise-tools/go-xcode/exportoptions" - "github.com/bitrise-tools/go-xcode/plistutil" - "github.com/stretchr/testify/require" -) - -func TestPlistData(t *testing.T) { - t.Log("development profile specifies development export method") - { - profile, err := plistutil.NewPlistDataFromContent(developmentProfileContent) - require.NoError(t, err) - require.Equal(t, "4b617a5f-e31e-4edc-9460-718a5abacd05", PlistData(profile).GetUUID()) - require.Equal(t, "Bitrise Test Development", PlistData(profile).GetName()) - require.Equal(t, "9NS44DLTN7.*", PlistData(profile).GetApplicationIdentifier()) - require.Equal(t, "*", PlistData(profile).GetBundleIdentifier()) - require.Equal(t, exportoptions.MethodDevelopment, PlistData(profile).GetExportMethod()) - require.Equal(t, "9NS44DLTN7", PlistData(profile).GetTeamID()) - require.Equal(t, "Some Dude", PlistData(profile).GetTeamName()) - require.Equal(t, "2016-09-22T11:28:46Z", PlistData(profile).GetCreationDate().Format("2006-01-02T15:04:05Z")) - require.Equal(t, "2017-09-22T11:28:46Z", PlistData(profile).GetExpirationDate().Format("2006-01-02T15:04:05Z")) - require.Equal(t, []string{"b13813075ad9b298cb9a9f28555c49573d8bc322"}, PlistData(profile).GetProvisionedDevices()) - require.Equal(t, [][]uint8{[]uint8{}}, PlistData(profile).GetDeveloperCertificates()) - require.Equal(t, false, PlistData(profile).GetProvisionsAllDevices()) - } - - t.Log("app store profile specifies app-store export method") - { - profile, err := plistutil.NewPlistDataFromContent(appStoreProfileContent) - require.NoError(t, err) - require.Equal(t, "a60668dd-191a-4770-8b1e-b453b87aa60b", PlistData(profile).GetUUID()) - require.Equal(t, "Bitrise Test App Store", PlistData(profile).GetName()) - require.Equal(t, "9NS44DLTN7.*", PlistData(profile).GetApplicationIdentifier()) - require.Equal(t, "*", PlistData(profile).GetBundleIdentifier()) - require.Equal(t, exportoptions.MethodAppStore, PlistData(profile).GetExportMethod()) - require.Equal(t, "9NS44DLTN7", PlistData(profile).GetTeamID()) - require.Equal(t, "Some Dude", PlistData(profile).GetTeamName()) - require.Equal(t, "2016-09-22T11:29:12Z", PlistData(profile).GetCreationDate().Format("2006-01-02T15:04:05Z")) - require.Equal(t, "2017-09-21T13:20:06Z", PlistData(profile).GetExpirationDate().Format("2006-01-02T15:04:05Z")) - require.Equal(t, []string(nil), PlistData(profile).GetProvisionedDevices()) - require.Equal(t, [][]uint8{[]uint8{}}, PlistData(profile).GetDeveloperCertificates()) - require.Equal(t, false, PlistData(profile).GetProvisionsAllDevices()) - } - - t.Log("ad hoc profile specifies ad-hoc export method") - { - profile, err := plistutil.NewPlistDataFromContent(adHocProfileContent) - require.NoError(t, err) - require.Equal(t, "26668300-5743-46a1-8e00-7023e2e35c7d", PlistData(profile).GetUUID()) - require.Equal(t, "Bitrise Test Ad Hoc", PlistData(profile).GetName()) - require.Equal(t, "9NS44DLTN7.*", PlistData(profile).GetApplicationIdentifier()) - require.Equal(t, "*", PlistData(profile).GetBundleIdentifier()) - require.Equal(t, exportoptions.MethodAdHoc, PlistData(profile).GetExportMethod()) - require.Equal(t, "9NS44DLTN7", PlistData(profile).GetTeamID()) - require.Equal(t, "Some Dude", PlistData(profile).GetTeamName()) - require.Equal(t, "2016-09-22T11:29:38Z", PlistData(profile).GetCreationDate().Format("2006-01-02T15:04:05Z")) - require.Equal(t, "2017-09-21T13:20:06Z", PlistData(profile).GetExpirationDate().Format("2006-01-02T15:04:05Z")) - require.Equal(t, []string{"b13813075ad9b298cb9a9f28555c49573d8bc322"}, PlistData(profile).GetProvisionedDevices()) - require.Equal(t, [][]uint8{[]uint8{}}, PlistData(profile).GetDeveloperCertificates()) - require.Equal(t, false, PlistData(profile).GetProvisionsAllDevices()) - } - - t.Log("it creates model from enterprise profile content") - { - profile, err := plistutil.NewPlistDataFromContent(enterpriseProfileContent) - require.NoError(t, err) - require.Equal(t, "8d6caa15-ac49-48f9-9bd3-ce9244add6a0", PlistData(profile).GetUUID()) - require.Equal(t, "Bitrise Test Enterprise", PlistData(profile).GetName()) - require.Equal(t, "9NS44DLTN7.com.Bitrise.Test", PlistData(profile).GetApplicationIdentifier()) - require.Equal(t, "com.Bitrise.Test", PlistData(profile).GetBundleIdentifier()) - require.Equal(t, exportoptions.MethodEnterprise, PlistData(profile).GetExportMethod()) - require.Equal(t, "9NS44DLTN7", PlistData(profile).GetTeamID()) - require.Equal(t, "Bitrise", PlistData(profile).GetTeamName()) - require.Equal(t, "2015-10-05T13:32:46Z", PlistData(profile).GetCreationDate().Format("2006-01-02T15:04:05Z")) - require.Equal(t, "2016-10-04T13:32:46Z", PlistData(profile).GetExpirationDate().Format("2006-01-02T15:04:05Z")) - require.Equal(t, []string(nil), PlistData(profile).GetProvisionedDevices()) - require.Equal(t, [][]uint8{[]uint8{}}, PlistData(profile).GetDeveloperCertificates()) - require.Equal(t, true, PlistData(profile).GetProvisionsAllDevices()) - } -} - -const developmentProfileContent = ` - - - - AppIDName - Bitrise Test - ApplicationIdentifierPrefix - - 9NS44DLTN7 - - CreationDate - 2016-09-22T11:28:46Z - Platform - - iOS - - DeveloperCertificates - - - - Entitlements - - keychain-access-groups - - 9NS44DLTN7.* - - get-task-allow - - application-identifier - 9NS44DLTN7.* - com.apple.developer.team-identifier - 9NS44DLTN7 - - ExpirationDate - 2017-09-22T11:28:46Z - Name - Bitrise Test Development - ProvisionedDevices - - b13813075ad9b298cb9a9f28555c49573d8bc322 - - TeamIdentifier - - 9NS44DLTN7 - - TeamName - Some Dude - TimeToLive - 365 - UUID - 4b617a5f-e31e-4edc-9460-718a5abacd05 - Version - 1 -` - -const appStoreProfileContent = ` - - - - AppIDName - Bitrise Test - ApplicationIdentifierPrefix - - 9NS44DLTN7 - - CreationDate - 2016-09-22T11:29:12Z - Platform - - iOS - - DeveloperCertificates - - - - Entitlements - - keychain-access-groups - - 9NS44DLTN7.* - - get-task-allow - - application-identifier - 9NS44DLTN7.* - com.apple.developer.team-identifier - 9NS44DLTN7 - beta-reports-active - - - ExpirationDate - 2017-09-21T13:20:06Z - Name - Bitrise Test App Store - TeamIdentifier - - 9NS44DLTN7 - - TeamName - Some Dude - TimeToLive - 364 - UUID - a60668dd-191a-4770-8b1e-b453b87aa60b - Version - 1 -` - -const adHocProfileContent = ` - - - - AppIDName - Bitrise Test - ApplicationIdentifierPrefix - - 9NS44DLTN7 - - CreationDate - 2016-09-22T11:29:38Z - Platform - - iOS - - DeveloperCertificates - - - - Entitlements - - keychain-access-groups - - 9NS44DLTN7.* - - get-task-allow - - application-identifier - 9NS44DLTN7.* - com.apple.developer.team-identifier - 9NS44DLTN7 - - ExpirationDate - 2017-09-21T13:20:06Z - Name - Bitrise Test Ad Hoc - ProvisionedDevices - - b13813075ad9b298cb9a9f28555c49573d8bc322 - - TeamIdentifier - - 9NS44DLTN7 - - TeamName - Some Dude - TimeToLive - 364 - UUID - 26668300-5743-46a1-8e00-7023e2e35c7d - Version - 1 -` - -const enterpriseProfileContent = ` - - - - AppIDName - Test - ApplicationIdentifierPrefix - - 9NS44DLTN7 - - CreationDate - 2015-10-05T13:32:46Z - Platform - - iOS - - DeveloperCertificates - - - - Entitlements - - keychain-access-groups - - 9NS44DLTN7.* - - get-task-allow - - application-identifier - 9NS44DLTN7.com.Bitrise.Test - com.apple.developer.team-identifier - 9NS44DLTN7 - - - ExpirationDate - 2016-10-04T13:32:46Z - Name - Bitrise Test Enterprise - ProvisionsAllDevices - - TeamIdentifier - - 9NS44DLTN7 - - TeamName - Bitrise - TimeToLive - 365 - UUID - 8d6caa15-ac49-48f9-9bd3-ce9244add6a0 - Version - 1 -` diff --git a/vendor/github.com/bitrise-tools/go-xcode/simulator/simulator.go b/vendor/github.com/bitrise-tools/go-xcode/simulator/simulator.go deleted file mode 100644 index a9d3734d..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/simulator/simulator.go +++ /dev/null @@ -1,306 +0,0 @@ -package simulator - -import ( - "bufio" - "fmt" - "log" - "path/filepath" - "regexp" - "strconv" - "strings" - - "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-tools/go-xcode/models" - version "github.com/hashicorp/go-version" -) - -// InfoModel ... -type InfoModel struct { - Name string - ID string - Status string - StatusOther string -} - -// OsVersionSimulatorInfosMap ... -type OsVersionSimulatorInfosMap map[string][]InfoModel // Os version - []Info map - -// getSimulatorInfoFromLine ... -// a simulator info line should look like this: -// iPhone 5s (EA1C7E48-8137-428C-A0A5-B2C63FF276EB) (Shutdown) -// or -// iPhone 4s (51B10EBD-C949-49F5-A38B-E658F41640FF) (Shutdown) (unavailable, runtime profile not found) -func getSimulatorInfoFromLine(lineStr string) (InfoModel, error) { - baseInfosExp := regexp.MustCompile(`(?P[a-zA-Z].*[a-zA-Z0-9 -]*) \((?P[a-zA-Z0-9-]{36})\) \((?P[a-zA-Z]*)\)`) - baseInfosRes := baseInfosExp.FindStringSubmatch(lineStr) - if baseInfosRes == nil { - return InfoModel{}, fmt.Errorf("No match found") - } - - simInfo := InfoModel{ - Name: baseInfosRes[1], - ID: baseInfosRes[2], - Status: baseInfosRes[3], - } - - // StatusOther - restOfTheLine := lineStr[len(baseInfosRes[0]):] - if len(restOfTheLine) > 0 { - statusOtherExp := regexp.MustCompile(`\((?P[a-zA-Z ,]*)\)`) - statusOtherRes := statusOtherExp.FindStringSubmatch(restOfTheLine) - if statusOtherRes != nil { - simInfo.StatusOther = statusOtherRes[1] - } - } - return simInfo, nil -} - -func getOsVersionSimulatorInfosMapFromSimctlList(simctlList string) (OsVersionSimulatorInfosMap, error) { - simulatorsByIOSVersions := OsVersionSimulatorInfosMap{} - currIOSVersion := "" - - fscanner := bufio.NewScanner(strings.NewReader(simctlList)) - isDevicesSectionFound := false - for fscanner.Scan() { - aLine := fscanner.Text() - - if aLine == "== Devices ==" { - isDevicesSectionFound = true - continue - } - - if !isDevicesSectionFound { - continue - } - if strings.HasPrefix(aLine, "==") { - isDevicesSectionFound = false - continue - } - if strings.HasPrefix(aLine, "--") { - iosVersionSectionExp := regexp.MustCompile(`-- (?P.*) --`) - iosVersionSectionRes := iosVersionSectionExp.FindStringSubmatch(aLine) - if iosVersionSectionRes != nil { - currIOSVersion = iosVersionSectionRes[1] - } - continue - } - - simInfo, err := getSimulatorInfoFromLine(aLine) - if err != nil { - fmt.Println(" [!] Error scanning the line for Simulator info: ", err) - } - - currIOSVersionSimList := simulatorsByIOSVersions[currIOSVersion] - currIOSVersionSimList = append(currIOSVersionSimList, simInfo) - simulatorsByIOSVersions[currIOSVersion] = currIOSVersionSimList - } - - return simulatorsByIOSVersions, nil -} - -// GetOsVersionSimulatorInfosMap ... -func GetOsVersionSimulatorInfosMap() (OsVersionSimulatorInfosMap, error) { - cmd := command.New("xcrun", "simctl", "list") - simctlListOut, err := cmd.RunAndReturnTrimmedCombinedOutput() - if err != nil { - return OsVersionSimulatorInfosMap{}, err - } - - return getOsVersionSimulatorInfosMapFromSimctlList(simctlListOut) -} - -func getSimulatorInfoFromSimctlOut(simctlListOut, osNameAndVersion, deviceName string) (InfoModel, error) { - osVersionSimulatorInfosMap, err := getOsVersionSimulatorInfosMapFromSimctlList(simctlListOut) - if err != nil { - return InfoModel{}, err - } - - infos, ok := osVersionSimulatorInfosMap[osNameAndVersion] - if !ok { - return InfoModel{}, fmt.Errorf("no simulators found for os version: %s", osNameAndVersion) - } - - for _, info := range infos { - if info.Name == deviceName { - return info, nil - } - } - - return InfoModel{}, fmt.Errorf("no simulators found for os version: (%s), device name: (%s)", osNameAndVersion, deviceName) -} - -// GetSimulatorInfo ... -func GetSimulatorInfo(osNameAndVersion, deviceName string) (InfoModel, error) { - cmd := command.New("xcrun", "simctl", "list") - simctlListOut, err := cmd.RunAndReturnTrimmedCombinedOutput() - if err != nil { - return InfoModel{}, err - } - - return getSimulatorInfoFromSimctlOut(simctlListOut, osNameAndVersion, deviceName) -} - -func getLatestSimulatorInfoFromSimctlOut(simctlListOut, osName, deviceName string) (InfoModel, string, error) { - osVersionSimulatorInfosMap, err := getOsVersionSimulatorInfosMapFromSimctlList(simctlListOut) - if err != nil { - return InfoModel{}, "", err - } - - var latestVersionPtr *version.Version - latestInfo := InfoModel{} - for osVersion, infos := range osVersionSimulatorInfosMap { - if !strings.HasPrefix(osVersion, osName) { - continue - } - - deviceInfo := InfoModel{} - deviceFound := false - for _, info := range infos { - if info.Name == deviceName { - deviceFound = true - deviceInfo = info - break - } - } - if !deviceFound { - continue - } - - versionStr := strings.TrimPrefix(osVersion, osName) - versionStr = strings.TrimSpace(versionStr) - - versionPtr, err := version.NewVersion(versionStr) - if err != nil { - return InfoModel{}, "", fmt.Errorf("failed to parse version (%s), error: %s", versionStr, err) - } - - if latestVersionPtr == nil || versionPtr.GreaterThan(latestVersionPtr) { - latestVersionPtr = versionPtr - latestInfo = deviceInfo - } - } - - if latestVersionPtr == nil { - return InfoModel{}, "", fmt.Errorf("failed to determin latest (%s) simulator version", osName) - } - - versionSegments := latestVersionPtr.Segments() - if len(versionSegments) < 2 { - return InfoModel{}, "", fmt.Errorf("invalid version created: %s, segments count < 2", latestVersionPtr.String()) - } - - osVersion := fmt.Sprintf("%s %d.%d", osName, versionSegments[0], versionSegments[1]) - - return latestInfo, osVersion, nil -} - -// GetLatestSimulatorInfoAndVersion ... -func GetLatestSimulatorInfoAndVersion(osName, deviceName string) (InfoModel, string, error) { - cmd := command.New("xcrun", "simctl", "list") - simctlListOut, err := cmd.RunAndReturnTrimmedCombinedOutput() - if err != nil { - return InfoModel{}, "", err - } - - return getLatestSimulatorInfoFromSimctlOut(simctlListOut, osName, deviceName) -} - -// Is64BitArchitecture ... -func Is64BitArchitecture(simulatorDevice string) (bool, error) { - // 64 bit processor iPhones: - // - iPhone 5S, - // - iPhone 6, iPhone 6 Plus, iPhone 6S, iPhone 6S Plus, - // - iPhone SE, - // - iPhone 7, iPhone 7 Plus - - // 64 bit processor iPads: - // - iPad Mini 2, iPad Mini 3, iPad Mini 4 - // - iPad Air, iPad Air 2 - // - iPad Pro (12.9 inch), iPad Pro (9.7 inch) - deviceSplit := strings.Split(simulatorDevice, " ") - if len(deviceSplit) == 1 && deviceSplit[0] == "iPad" { - return false, nil - } - - if len(deviceSplit) < 2 { - return false, fmt.Errorf("Unexpected deivice name (%s)", simulatorDevice) - } - - name := strings.TrimSpace(deviceSplit[0]) - versionSlice := deviceSplit[1:] - - if name == "iPhone" { - if versionSlice[0] == "SE" { - return true, nil - } - - versionNumber := versionSlice[0] - if versionNumber == "5S" { - return true, nil - } - - majorVersionStr := string(versionNumber[0]) - majorVersion, err := strconv.Atoi(majorVersionStr) - if err != nil { - return false, err - } - - if majorVersion >= 6 { - return true, nil - } - } else if name == "iPad" { - subNameOrVersion := strings.TrimSpace(versionSlice[0]) - - if subNameOrVersion == "Mini" { - if len(versionSlice) == 2 { - version, err := strconv.Atoi(versionSlice[1]) - if err != nil { - return false, err - } - - if version > 1 { - return true, nil - } - } - } - - if subNameOrVersion == "Air" { - return true, nil - } - - if subNameOrVersion == "Pro" { - return true, nil - } - } - - return false, nil -} - -func getXcodeDeveloperDirPath() (string, error) { - cmd := command.New("xcode-select", "--print-path") - return cmd.RunAndReturnTrimmedCombinedOutput() -} - -// BootSimulator ... -func BootSimulator(simulator InfoModel, xcodebuildVersion models.XcodebuildVersionModel) error { - simulatorApp := "Simulator" - if xcodebuildVersion.MajorVersion == 6 { - simulatorApp = "iOS Simulator" - } - xcodeDevDirPth, err := getXcodeDeveloperDirPath() - if err != nil { - return fmt.Errorf("failed to get Xcode Developer Directory - most likely Xcode.app is not installed") - } - simulatorAppFullPath := filepath.Join(xcodeDevDirPth, "Applications", simulatorApp+".app") - - openCmd := command.New("open", simulatorAppFullPath, "--args", "-CurrentDeviceUDID", simulator.ID) - - log.Printf("$ %s", openCmd.PrintableCommandArgs()) - - outStr, err := openCmd.RunAndReturnTrimmedCombinedOutput() - if err != nil { - return fmt.Errorf("failed to start simulators (%s), output: %s, error: %s", simulator.ID, outStr, err) - } - - return nil -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/simulator/simulator_test.go b/vendor/github.com/bitrise-tools/go-xcode/simulator/simulator_test.go deleted file mode 100644 index be82da3b..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/simulator/simulator_test.go +++ /dev/null @@ -1,168 +0,0 @@ -package simulator - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestGetLatestSimulatorInfoFromSimctlOut(t *testing.T) { - t.Log("iOS iPhone 6s Plus") - { - info, version, err := getLatestSimulatorInfoFromSimctlOut(simctlListOut, "iOS", "iPhone 6s Plus") - require.NoError(t, err) - require.Equal(t, "iOS 10.2", version) - require.Equal(t, "iPhone 6s Plus", info.Name) - require.Equal(t, "3924585A-F638-46BC-9F93-99354C058D19", info.ID) - require.Equal(t, "Shutdown", info.Status) - require.Equal(t, "", info.StatusOther) - } -} - -func TestGetSimulatorInfoFromSimctlOut(t *testing.T) { - t.Log("iOS 10.1 iPhone 6s Plus") - { - info, err := getSimulatorInfoFromSimctlOut(simctlListOut, "iOS 10.1", "iPhone 6s Plus") - require.NoError(t, err) - require.Equal(t, "iPhone 6s Plus", info.Name) - require.Equal(t, "8255740B-6952-4802-93FF-52B1F0D34BBF", info.ID) - require.Equal(t, "Shutdown", info.Status) - require.Equal(t, "", info.StatusOther) - } -} - -func TestIs64BitArchitecture(t *testing.T) { - t.Log("64-bit simulators") - { - iPhoneSimulators := []string{ - "iPhone 5S", - "iPhone 6", "iPhone 6 Plus", "iPhone 6S", "iPhone 6S Plus", - "iPhone SE", - "iPhone 7", "iPhone 7 Plus", - } - - for _, iPhoneSimulator := range iPhoneSimulators { - is64bit, err := Is64BitArchitecture(iPhoneSimulator) - require.NoError(t, err, iPhoneSimulator) - require.Equal(t, true, is64bit, iPhoneSimulator) - } - - iPadSimulators := []string{ - "iPad Mini 2", "iPad Mini 3", "iPad Mini 4", - "iPad Air", "iPad Air 2", - "iPad Pro (12.9 inch)", "iPad Pro (9.7 inch)", - } - - for _, iPadSimulator := range iPadSimulators { - is64bit, err := Is64BitArchitecture(iPadSimulator) - require.NoError(t, err, iPadSimulator) - require.Equal(t, true, is64bit, iPadSimulator) - } - } - - t.Log("not 64-bit simulators") - { - iPhoneSimulators := []string{ - "iPhone 5", "iPhone 5C", - "iPhone 4", "iPhone 4s", - "iPhone 3G", "iPhone 3GS", - } - - for _, iPhoneSimulator := range iPhoneSimulators { - is64bit, err := Is64BitArchitecture(iPhoneSimulator) - require.NoError(t, err, iPhoneSimulator) - require.Equal(t, false, is64bit, iPhoneSimulator) - } - - iPadSimulators := []string{ - "iPad", "iPad 2", "iPad 3", "iPad 4", - "iPad Mini", - } - - for _, iPadSimulator := range iPadSimulators { - is64bit, err := Is64BitArchitecture(iPadSimulator) - require.NoError(t, err, iPadSimulator) - require.Equal(t, false, is64bit, iPadSimulator) - } - } - -} - -const simctlListOut = `== Device Types == -iPhone 4s (com.apple.CoreSimulator.SimDeviceType.iPhone-4s) -iPhone 5 (com.apple.CoreSimulator.SimDeviceType.iPhone-5) -iPhone 5s (com.apple.CoreSimulator.SimDeviceType.iPhone-5s) -iPhone 6 (com.apple.CoreSimulator.SimDeviceType.iPhone-6) -iPhone 6 Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-6-Plus) -iPhone 6s (com.apple.CoreSimulator.SimDeviceType.iPhone-6s) -iPhone 6s Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-6s-Plus) -iPhone 7 (com.apple.CoreSimulator.SimDeviceType.iPhone-7) -iPhone 7 Plus (com.apple.CoreSimulator.SimDeviceType.iPhone-7-Plus) -iPhone SE (com.apple.CoreSimulator.SimDeviceType.iPhone-SE) -iPad 2 (com.apple.CoreSimulator.SimDeviceType.iPad-2) -iPad Retina (com.apple.CoreSimulator.SimDeviceType.iPad-Retina) -iPad Air (com.apple.CoreSimulator.SimDeviceType.iPad-Air) -iPad Air 2 (com.apple.CoreSimulator.SimDeviceType.iPad-Air-2) -iPad Pro (9.7-inch) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro--9-7-inch-) -iPad Pro (12.9-inch) (com.apple.CoreSimulator.SimDeviceType.iPad-Pro) -Apple TV 1080p (com.apple.CoreSimulator.SimDeviceType.Apple-TV-1080p) -Apple Watch - 38mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-38mm) -Apple Watch - 42mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-42mm) -Apple Watch Series 2 - 38mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-2-38mm) -Apple Watch Series 2 - 42mm (com.apple.CoreSimulator.SimDeviceType.Apple-Watch-Series-2-42mm) -== Runtimes == -iOS 8.1 (8.1 - 12B411) (com.apple.CoreSimulator.SimRuntime.iOS-8-1) -iOS 9.3 (9.3 - 13E233) (com.apple.CoreSimulator.SimRuntime.iOS-9-3) -iOS 10.1 (10.1 - 14B72) (com.apple.CoreSimulator.SimRuntime.iOS-10-1) -iOS 10.2 (10.2 - 14C89) (com.apple.CoreSimulator.SimRuntime.iOS-10-2) -tvOS 10.1 (10.1 - 14U591) (com.apple.CoreSimulator.SimRuntime.tvOS-10-1) -watchOS 3.1 (3.1 - 14S471a) (com.apple.CoreSimulator.SimRuntime.watchOS-3-1) -== Devices == --- iOS 8.1 -- --- iOS 9.3 -- --- iOS 10.1 -- - iPhone 5 (BF890074-6F3B-4947-863B-719389EE130A) (Shutdown) - iPhone 5s (6578E45A-DBE6-4132-BB9D-EFB9E46F3DB1) (Shutdown) - iPhone 6 (FE7403F6-2DC4-437C-8F22-36ED833F43D5) (Shutdown) - iPhone 6 Plus (8F988216-8CC9-4C34-B134-F91A0D243107) (Shutdown) - iPhone 6s (1AE8A4B3-72D0-4CC7-92AC-DA499C035E2D) (Shutdown) - iPhone 6s Plus (8255740B-6952-4802-93FF-52B1F0D34BBF) (Shutdown) - iPhone 7 (C3615E82-9864-4C62-9071-4D6F3A950158) (Creating) - iPhone 7 Plus (92F985EF-AFA7-4A6A-AE59-898DAA787214) (Creating) - iPhone SE (C78E0A01-B3EC-43B2-B219-C76BFA730142) (Shutdown) - iPad Retina (47997B81-9B9B-4EF5-A02C-5A3146965952) (Shutdown) - iPad Air (ED4281C1-DC83-449A-B740-24DBC3FAE7F9) (Shutdown) - iPad Air 2 (466D9824-416A-414F-8F17-CFDEB124AB1F) (Shutdown) - iPad Pro (9.7 inch) (A2ED8637-F295-4322-9EAD-6F55ACD209AB) (Shutdown) - iPad Pro (12.9 inch) (8423BCC0-203A-4076-B1D8-BFAA2601A722) (Shutdown) --- iOS 10.2 -- - iPhone 5 (F9CCC75E-1CF8-4FD6-8973-0696134858EA) (Shutdown) - iPhone 5s (4E15C24C-DFC9-4C4A-AA4D-2132AF6B42D7) (Shutdown) - iPhone 6 (F428080E-B6DA-493B-8101-F372FA537E2C) (Shutdown) - iPhone 6 Plus (3D6E672E-5D89-4B8E-A83C-7D9D30831AD2) (Shutdown) - iPhone 6s (5656804A-BB52-4453-AAC9-7B439D744B52) (Shutdown) - iPhone 6s Plus (3924585A-F638-46BC-9F93-99354C058D19) (Shutdown) - iPhone 7 (DBAEDE5B-34F6-431C-898D-CECA63658E63) (Shutdown) - iPhone 7 Plus (A0385845-47BC-4424-8D02-D223810F85DA) (Shutdown) - iPhone SE (E1CD6D89-2C33-4534-A340-47E0E9168970) (Shutdown) - iPad Retina (F7D8A427-7594-4A24-9CE9-09BE38090C23) (Shutdown) - iPad Air (7C37463A-5587-4BC5-BBA6-F32B52252BAB) (Shutdown) - iPad Air 2 (87D6D52A-A522-4D93-B13F-EFED1BBDD9DF) (Shutdown) - iPad Pro (9.7 inch) (B38E2FB8-6375-4020-85C2-49FF4C6DC9A6) (Shutdown) - iPad Pro (12.9 inch) (49288CB3-EA62-4472-8BF6-2F81C4E2F62E) (Shutdown) --- tvOS 10.1 -- - Apple TV 1080p (FBB62097-8171-4A99-95B2-91A90A039BEC) (Shutdown) --- watchOS 3.1 -- - Apple Watch - 38mm (DD9BAB53-23EB-4CA4-B042-DC2EF2C84B7D) (Shutdown) - Apple Watch - 42mm (6DC5251E-C2F3-4D89-AD33-DB189AFDEDD7) (Shutdown) - Apple Watch Series 2 - 38mm (D7D06B47-C8D6-4072-9F3C-BB5058826286) (Shutdown) - Apple Watch Series 2 - 42mm (F47234F6-D237-4BFC-A337-4D88B63ADE77) (Shutdown) --- Unavailable: com.apple.CoreSimulator.SimRuntime.tvOS-10-0 -- - Apple TV 1080p (C246D04C-3C24-4FFC-AB37-34F471A6265A) (Shutdown) (unavailable, runtime profile not found) -== Device Pairs == -604413C4-EE63-4A88-B7E4-91018674FE8A (active, disconnected) - Watch: Apple Watch Series 2 - 38mm (D7D06B47-C8D6-4072-9F3C-BB5058826286) (Shutdown) - Phone: iPhone 7 (DBAEDE5B-34F6-431C-898D-CECA63658E63) (Shutdown) -0CE457A5-3458-4545-9503-F2A1584169C6 (active, disconnected) - Watch: Apple Watch Series 2 - 42mm (F47234F6-D237-4BFC-A337-4D88B63ADE77) (Shutdown) - Phone: iPhone 7 Plus (A0385845-47BC-4424-8D02-D223810F85DA) (Shutdown)` diff --git a/vendor/github.com/bitrise-tools/go-xcode/utility/utility_test.go b/vendor/github.com/bitrise-tools/go-xcode/utility/utility_test.go deleted file mode 100644 index 4eded4aa..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/utility/utility_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package utility - -import ( - "testing" - - "github.com/bitrise-tools/go-xcode/models" - "github.com/stretchr/testify/require" -) - -const testXcodebuildVersionOutput = `Xcode 8.2.1 -Build version 8C1002` - -func TestGetXcodeVersionFromXcodebuildOutput(t *testing.T) { - t.Log("GetXcodeVersionFromXcodebuildOutput") - { - expectedVersion := models.XcodebuildVersionModel{ - Version: "Xcode 8.2.1", - BuildVersion: "Build version 8C1002", - MajorVersion: 8, - } - - currentVersion, err := getXcodeVersionFromXcodebuildOutput(testXcodebuildVersionOutput) - require.NoError(t, err) - require.Equal(t, expectedVersion, currentVersion) - } -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcarchive/xcarchive.go b/vendor/github.com/bitrise-tools/go-xcode/xcarchive/xcarchive.go deleted file mode 100644 index 245030de..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcarchive/xcarchive.go +++ /dev/null @@ -1,344 +0,0 @@ -package xcarchive - -import ( - "fmt" - "path/filepath" - "strings" - - "github.com/bitrise-io/go-utils/log" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/bitrise-tools/go-xcode/plistutil" - "github.com/bitrise-tools/go-xcode/profileutil" - "github.com/bitrise-tools/go-xcode/utility" -) - -// Application ... -type Application struct { - Path string - InfoPlist plistutil.PlistData - Entitlements plistutil.PlistData - ProvisioningProfile profileutil.ProvisioningProfileInfoModel - Plugins []Application - WatchApplication *Application - IsMacOS bool -} - -// BundleIdentifier ... -func (app Application) BundleIdentifier() string { - bundleID, _ := app.InfoPlist.GetString("CFBundleIdentifier") - return bundleID -} - -// NewApplication ... -func NewApplication(applicationsDir string) (Application, error) { - mainApplication := Application{} - mainApplicationPth := "" - applicationContentPth := "" - { - pattern := filepath.Join(applicationsDir, "*.app") - pths, err := filepath.Glob(pattern) - if err != nil { - return Application{}, err - } - - if len(pths) == 0 { - return Application{}, fmt.Errorf("Failed to find main application using pattern: %s", pattern) - } else if len(pths) > 1 { - log.Warnf("Multiple main applications found") - for _, pth := range pths { - log.Warnf("- %s", pth) - } - - mainApplicationPth = pths[0] - log.Warnf("Using first: %s", mainApplicationPth) - } else { - mainApplicationPth = pths[0] - } - - application := Application{ - Path: mainApplicationPth, - } - - { - applicationContentPth = filepath.Join(mainApplicationPth, "Contents") - exists, err := pathutil.IsPathExists(applicationContentPth) - if err != nil { - return Application{}, err - } - if exists { - application.IsMacOS = true - } else { - application.IsMacOS = false - applicationContentPth = mainApplicationPth - } - } - - { - infoPlistPth := filepath.Join(applicationContentPth, "Info.plist") - infoPlistExist, err := pathutil.IsPathExists(infoPlistPth) - if err != nil { - return Application{}, err - } - if !infoPlistExist { - if !infoPlistExist { - return Application{}, fmt.Errorf("Info.plist does not exist at: (%s)", infoPlistPth) - } - } - infoPlist, err := plistutil.NewPlistDataFromFile(infoPlistPth) - if err != nil { - return Application{}, err - } - application.InfoPlist = infoPlist - } - - { - provisioningProfilePth := filepath.Join(applicationContentPth, "embedded.mobileprovision") - exist, err := pathutil.IsPathExists(provisioningProfilePth) - if err != nil { - return Application{}, err - } else if !exist && !application.IsMacOS { - return Application{}, fmt.Errorf("embedded.mobileprovision does not exist at: %s", provisioningProfilePth) - } - if exist { - profile, err := profileutil.NewProvisioningProfileInfoFromFile(provisioningProfilePth) - if err != nil { - return Application{}, err - } - application.ProvisioningProfile = profile - } - } - - { - entitlementsBasePth := applicationContentPth - if application.IsMacOS { - entitlementsBasePth = filepath.Join(entitlementsBasePth, "Resources") - } - - entitlementsPth := filepath.Join(entitlementsBasePth, "archived-expanded-entitlements.xcent") - exist, err := pathutil.IsPathExists(entitlementsPth) - if err != nil { - return Application{}, err - } else if exist { - entitlements, err := plistutil.NewPlistDataFromFile(entitlementsPth) - if err != nil { - return Application{}, err - } - - application.Entitlements = entitlements - } - } - mainApplication = application - } - - plugins := []Application{} - { - pattern := filepath.Join(applicationContentPth, "PlugIns/*.appex") - pths, err := filepath.Glob(pattern) - if err != nil { - return Application{}, err - } - for _, pth := range pths { - plugin, err := NewApplication(pth) - if err != nil { - return Application{}, err - } - - plugins = append(plugins, plugin) - } - mainApplication.Plugins = plugins - } - - var watchApplicationPtr *Application - watchApplicationPth := "" - { - pattern := filepath.Join(applicationContentPth, "Watch/*.app") - pths, err := filepath.Glob(pattern) - if err != nil { - return Application{}, err - } - - if len(pths) > 1 { - log.Warnf("Multiple watch applications found") - for _, pth := range pths { - log.Warnf("- %s", pth) - } - - watchApplicationPth = pths[0] - log.Warnf("Using first: %s", watchApplicationPth) - } else if len(pths) == 1 { - watchApplicationPth = pths[0] - } - - if watchApplicationPth != "" { - watchApplication, err := NewApplication(watchApplicationPth) - if err != nil { - return Application{}, err - } - - watchApplicationPtr = &watchApplication - } - } - - watchPlugins := []Application{} - { - if watchApplicationPth != "" { - pattern := filepath.Join(watchApplicationPth, "PlugIns/*.appex") - pths, err := filepath.Glob(pattern) - if err != nil { - return Application{}, err - } - for _, pth := range pths { - plugin, err := NewApplication(pth) - if err != nil { - return Application{}, err - } - - watchPlugins = append(watchPlugins, plugin) - } - (*watchApplicationPtr).Plugins = watchPlugins - } - } - - return mainApplication, nil -} - -// XCArchive ... -type XCArchive struct { - Path string - Application Application - InfoPlist plistutil.PlistData -} - -// IsXcodeManaged ... -func (archive XCArchive) IsXcodeManaged() bool { - return archive.Application.ProvisioningProfile.IsXcodeManaged() -} - -// SigningIdentity ... -func (archive XCArchive) SigningIdentity() string { - properties, found := archive.InfoPlist.GetMapStringInterface("ApplicationProperties") - if found { - identity, _ := properties.GetString("SigningIdentity") - return identity - } - return "" -} - -// BundleIDEntitlementsMap ... -func (archive XCArchive) BundleIDEntitlementsMap() map[string]plistutil.PlistData { - bundleIDEntitlementsMap := map[string]plistutil.PlistData{} - - bundleID := archive.Application.BundleIdentifier() - bundleIDEntitlementsMap[bundleID] = archive.Application.Entitlements - - for _, plugin := range archive.Application.Plugins { - bundleID := plugin.BundleIdentifier() - bundleIDEntitlementsMap[bundleID] = plugin.Entitlements - } - - if archive.Application.WatchApplication != nil { - watchApplication := *archive.Application.WatchApplication - - bundleID := watchApplication.BundleIdentifier() - bundleIDEntitlementsMap[bundleID] = watchApplication.Entitlements - - for _, plugin := range watchApplication.Plugins { - bundleID := plugin.BundleIdentifier() - bundleIDEntitlementsMap[bundleID] = plugin.Entitlements - } - } - - return bundleIDEntitlementsMap -} - -// BundleIDProfileInfoMap ... -func (archive XCArchive) BundleIDProfileInfoMap() map[string]profileutil.ProvisioningProfileInfoModel { - bundleIDProfileMap := map[string]profileutil.ProvisioningProfileInfoModel{} - - bundleID := archive.Application.BundleIdentifier() - bundleIDProfileMap[bundleID] = archive.Application.ProvisioningProfile - - for _, plugin := range archive.Application.Plugins { - bundleID := plugin.BundleIdentifier() - bundleIDProfileMap[bundleID] = plugin.ProvisioningProfile - } - - if archive.Application.WatchApplication != nil { - watchApplication := *archive.Application.WatchApplication - - bundleID := watchApplication.BundleIdentifier() - bundleIDProfileMap[bundleID] = watchApplication.ProvisioningProfile - - for _, plugin := range watchApplication.Plugins { - bundleID := plugin.BundleIdentifier() - bundleIDProfileMap[bundleID] = plugin.ProvisioningProfile - } - } - - return bundleIDProfileMap -} - -// FindDSYMs ... -func (archive XCArchive) FindDSYMs() (string, []string, error) { - dsymsDirPth := filepath.Join(archive.Path, "dSYMs") - dsyms, err := utility.ListEntries(dsymsDirPth, utility.ExtensionFilter(".dsym", true)) - if err != nil { - return "", []string{}, err - } - - appDSYM := "" - frameworkDSYMs := []string{} - for _, dsym := range dsyms { - if strings.HasSuffix(dsym, ".app.dSYM") { - appDSYM = dsym - } else { - frameworkDSYMs = append(frameworkDSYMs, dsym) - } - } - if appDSYM == "" && len(frameworkDSYMs) == 0 { - return "", []string{}, fmt.Errorf("no dsym found") - } - - return appDSYM, frameworkDSYMs, nil -} - -// NewXCArchive ... -func NewXCArchive(xcarchivePth string) (XCArchive, error) { - application := Application{} - { - applicationsDir := filepath.Join(xcarchivePth, "Products/Applications") - exist, err := pathutil.IsDirExists(applicationsDir) - if err != nil { - return XCArchive{}, err - } else if !exist { - return XCArchive{}, fmt.Errorf("Applications dir does not exist at: %s", applicationsDir) - } - - application, err = NewApplication(applicationsDir) - if err != nil { - return XCArchive{}, err - } - - } - - infoPlist := plistutil.PlistData{} - { - infoPlistPth := filepath.Join(xcarchivePth, "Info.plist") - exist, err := pathutil.IsPathExists(infoPlistPth) - if err != nil { - return XCArchive{}, err - } else if !exist { - return XCArchive{}, fmt.Errorf("Info.plist does not exist at: %s", infoPlistPth) - } - infoPlist, err = plistutil.NewPlistDataFromFile(infoPlistPth) - if err != nil { - return XCArchive{}, err - } - } - - return XCArchive{ - Path: xcarchivePth, - Application: application, - InfoPlist: infoPlist, - }, nil -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/archive.go b/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/archive.go deleted file mode 100644 index 65d0ce12..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/archive.go +++ /dev/null @@ -1,185 +0,0 @@ -package xcodebuild - -import ( - "fmt" - "os" - "os/exec" - - "github.com/bitrise-io/go-utils/command" -) - -/* -xcodebuild [-project ] \ - -scheme \ - [-destination ]... \ - [-configuration ] \ - [-arch ]... \ - [-sdk [|]] \ - [-showBuildSettings] \ - [=]... \ - []... - -xcodebuild -workspace \ - -scheme \ - [-destination ]... \ - [-configuration ] \ - [-arch ]... \ - [-sdk [|]] \ - [-showBuildSettings] \ - [=]... \ - []... -*/ - -// ArchiveCommandModel ... -type ArchiveCommandModel struct { - projectPath string - isWorkspace bool - scheme string - configuration string - - // buildsetting - forceDevelopmentTeam string - forceProvisioningProfileSpecifier string - forceProvisioningProfile string - forceCodeSignIdentity string - - // buildaction - customBuildActions []string - - // Options - archivePath string - customOptions []string -} - -// NewArchiveCommand ... -func NewArchiveCommand(projectPath string, isWorkspace bool) *ArchiveCommandModel { - return &ArchiveCommandModel{ - projectPath: projectPath, - isWorkspace: isWorkspace, - } -} - -// SetScheme ... -func (c *ArchiveCommandModel) SetScheme(scheme string) *ArchiveCommandModel { - c.scheme = scheme - return c -} - -// SetConfiguration ... -func (c *ArchiveCommandModel) SetConfiguration(configuration string) *ArchiveCommandModel { - c.configuration = configuration - return c -} - -// SetForceDevelopmentTeam ... -func (c *ArchiveCommandModel) SetForceDevelopmentTeam(forceDevelopmentTeam string) *ArchiveCommandModel { - c.forceDevelopmentTeam = forceDevelopmentTeam - return c -} - -// SetForceProvisioningProfileSpecifier ... -func (c *ArchiveCommandModel) SetForceProvisioningProfileSpecifier(forceProvisioningProfileSpecifier string) *ArchiveCommandModel { - c.forceProvisioningProfileSpecifier = forceProvisioningProfileSpecifier - return c -} - -// SetForceProvisioningProfile ... -func (c *ArchiveCommandModel) SetForceProvisioningProfile(forceProvisioningProfile string) *ArchiveCommandModel { - c.forceProvisioningProfile = forceProvisioningProfile - return c -} - -// SetForceCodeSignIdentity ... -func (c *ArchiveCommandModel) SetForceCodeSignIdentity(forceCodeSignIdentity string) *ArchiveCommandModel { - c.forceCodeSignIdentity = forceCodeSignIdentity - return c -} - -// SetCustomBuildAction ... -func (c *ArchiveCommandModel) SetCustomBuildAction(buildAction ...string) *ArchiveCommandModel { - c.customBuildActions = buildAction - return c -} - -// SetArchivePath ... -func (c *ArchiveCommandModel) SetArchivePath(archivePath string) *ArchiveCommandModel { - c.archivePath = archivePath - return c -} - -// SetCustomOptions ... -func (c *ArchiveCommandModel) SetCustomOptions(customOptions []string) *ArchiveCommandModel { - c.customOptions = customOptions - return c -} - -func (c *ArchiveCommandModel) cmdSlice() []string { - slice := []string{toolName} - - if c.projectPath != "" { - if c.isWorkspace { - slice = append(slice, "-workspace", c.projectPath) - } else { - slice = append(slice, "-project", c.projectPath) - } - } - - if c.scheme != "" { - slice = append(slice, "-scheme", c.scheme) - } - if c.configuration != "" { - slice = append(slice, "-configuration", c.configuration) - } - - if c.forceDevelopmentTeam != "" { - slice = append(slice, fmt.Sprintf("DEVELOPMENT_TEAM=%s", c.forceDevelopmentTeam)) - } - if c.forceProvisioningProfileSpecifier != "" { - slice = append(slice, fmt.Sprintf("PROVISIONING_PROFILE_SPECIFIER=%s", c.forceProvisioningProfileSpecifier)) - } - if c.forceProvisioningProfile != "" { - slice = append(slice, fmt.Sprintf("PROVISIONING_PROFILE=%s", c.forceProvisioningProfile)) - } - if c.forceCodeSignIdentity != "" { - slice = append(slice, fmt.Sprintf("CODE_SIGN_IDENTITY=%s", c.forceCodeSignIdentity)) - } - - slice = append(slice, c.customBuildActions...) - slice = append(slice, "archive") - - if c.archivePath != "" { - slice = append(slice, "-archivePath", c.archivePath) - } - - slice = append(slice, c.customOptions...) - - return slice -} - -// PrintableCmd ... -func (c ArchiveCommandModel) PrintableCmd() string { - cmdSlice := c.cmdSlice() - return command.PrintableCommandArgs(false, cmdSlice) -} - -// Command ... -func (c ArchiveCommandModel) Command() *command.Model { - cmdSlice := c.cmdSlice() - return command.New(cmdSlice[0], cmdSlice[1:]...) -} - -// Cmd ... -func (c ArchiveCommandModel) Cmd() *exec.Cmd { - command := c.Command() - return command.GetCmd() -} - -// Run ... -func (c ArchiveCommandModel) Run() error { - command := c.Command() - - command.SetStdout(os.Stdout) - command.SetStderr(os.Stderr) - - return command.Run() -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/export.go b/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/export.go deleted file mode 100644 index fa2e0c7b..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/export.go +++ /dev/null @@ -1,105 +0,0 @@ -package xcodebuild - -import ( - "bytes" - "io" - "os" - "os/exec" - - "github.com/bitrise-io/go-utils/command" -) - -/* -xcodebuild -exportArchive \ - -archivePath \ - -exportPath \ - -exportOptionsPlist -*/ - -// ExportCommandModel ... -type ExportCommandModel struct { - archivePath string - exportDir string - exportOptionsPlist string -} - -// NewExportCommand ... -func NewExportCommand() *ExportCommandModel { - return &ExportCommandModel{} -} - -// SetArchivePath ... -func (c *ExportCommandModel) SetArchivePath(archivePath string) *ExportCommandModel { - c.archivePath = archivePath - return c -} - -// SetExportDir ... -func (c *ExportCommandModel) SetExportDir(exportDir string) *ExportCommandModel { - c.exportDir = exportDir - return c -} - -// SetExportOptionsPlist ... -func (c *ExportCommandModel) SetExportOptionsPlist(exportOptionsPlist string) *ExportCommandModel { - c.exportOptionsPlist = exportOptionsPlist - return c -} - -func (c ExportCommandModel) cmdSlice() []string { - slice := []string{toolName, "-exportArchive"} - if c.archivePath != "" { - slice = append(slice, "-archivePath", c.archivePath) - } - if c.exportDir != "" { - slice = append(slice, "-exportPath", c.exportDir) - } - if c.exportOptionsPlist != "" { - slice = append(slice, "-exportOptionsPlist", c.exportOptionsPlist) - } - return slice -} - -// PrintableCmd ... -func (c ExportCommandModel) PrintableCmd() string { - cmdSlice := c.cmdSlice() - return command.PrintableCommandArgs(false, cmdSlice) -} - -// Command ... -func (c ExportCommandModel) Command() *command.Model { - cmdSlice := c.cmdSlice() - return command.New(cmdSlice[0], cmdSlice[1:]...) -} - -// Cmd ... -func (c ExportCommandModel) Cmd() *exec.Cmd { - command := c.Command() - return command.GetCmd() -} - -// Run ... -func (c ExportCommandModel) Run() error { - command := c.Command() - - command.SetStdout(os.Stdout) - command.SetStderr(os.Stderr) - - return command.Run() -} - -// RunAndReturnOutput ... -func (c ExportCommandModel) RunAndReturnOutput() (string, error) { - command := c.Command() - - var outBuffer bytes.Buffer - outWriter := io.MultiWriter(&outBuffer, os.Stdout) - - command.SetStdout(outWriter) - command.SetStderr(outWriter) - - err := command.Run() - out := outBuffer.String() - - return out, err -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/legacy_export.go b/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/legacy_export.go deleted file mode 100644 index 2f46aaff..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/legacy_export.go +++ /dev/null @@ -1,100 +0,0 @@ -package xcodebuild - -import ( - "os" - "os/exec" - - "github.com/bitrise-io/go-utils/command" -) - -/* -xcodebuild -exportArchive \ - -exportFormat format \ - -archivePath xcarchivepath \ - -exportPath destinationpath \ - [-exportProvisioningProfile profilename] \ - [-exportSigningIdentity identityname] \ - [-exportInstallerIdentity identityname] -*/ - -// LegacyExportCommandModel ... -type LegacyExportCommandModel struct { - exportFormat string - archivePath string - exportPath string - exportProvisioningProfileName string -} - -// NewLegacyExportCommand ... -func NewLegacyExportCommand() *LegacyExportCommandModel { - return &LegacyExportCommandModel{} -} - -// SetExportFormat ... -func (c *LegacyExportCommandModel) SetExportFormat(exportFormat string) *LegacyExportCommandModel { - c.exportFormat = exportFormat - return c -} - -// SetArchivePath ... -func (c *LegacyExportCommandModel) SetArchivePath(archivePath string) *LegacyExportCommandModel { - c.archivePath = archivePath - return c -} - -// SetExportPath ... -func (c *LegacyExportCommandModel) SetExportPath(exportPath string) *LegacyExportCommandModel { - c.exportPath = exportPath - return c -} - -// SetExportProvisioningProfileName ... -func (c *LegacyExportCommandModel) SetExportProvisioningProfileName(exportProvisioningProfileName string) *LegacyExportCommandModel { - c.exportProvisioningProfileName = exportProvisioningProfileName - return c -} - -func (c LegacyExportCommandModel) cmdSlice() []string { - slice := []string{toolName, "-exportArchive"} - if c.exportFormat != "" { - slice = append(slice, "-exportFormat", c.exportFormat) - } - if c.archivePath != "" { - slice = append(slice, "-archivePath", c.archivePath) - } - if c.exportPath != "" { - slice = append(slice, "-exportPath", c.exportPath) - } - if c.exportProvisioningProfileName != "" { - slice = append(slice, "-exportProvisioningProfile", c.exportProvisioningProfileName) - } - return slice -} - -// PrintableCmd ... -func (c LegacyExportCommandModel) PrintableCmd() string { - cmdSlice := c.cmdSlice() - return command.PrintableCommandArgs(false, cmdSlice) -} - -// Command ... -func (c LegacyExportCommandModel) Command() *command.Model { - cmdSlice := c.cmdSlice() - return command.New(cmdSlice[0], cmdSlice[1:]...) -} - -// Cmd ... -func (c LegacyExportCommandModel) Cmd() *exec.Cmd { - command := c.Command() - return command.GetCmd() -} - -// Run ... -func (c LegacyExportCommandModel) Run() error { - command := c.Command() - - command.SetStdout(os.Stdout) - command.SetStderr(os.Stderr) - - return command.Run() -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/show_build_settings.go b/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/show_build_settings.go deleted file mode 100644 index 912c8575..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/show_build_settings.go +++ /dev/null @@ -1,88 +0,0 @@ -package xcodebuild - -import ( - "bufio" - "os/exec" - "strings" - - "github.com/bitrise-io/go-utils/command" -) - -// ShowBuildSettingsCommandModel ... -type ShowBuildSettingsCommandModel struct { - projectPath string - isWorkspace bool -} - -// NewShowBuildSettingsCommand ... -func NewShowBuildSettingsCommand(projectPath string, isWorkspace bool) *ShowBuildSettingsCommandModel { - return &ShowBuildSettingsCommandModel{ - projectPath: projectPath, - isWorkspace: isWorkspace, - } -} - -func (c *ShowBuildSettingsCommandModel) cmdSlice() []string { - slice := []string{toolName} - - if c.projectPath != "" { - if c.isWorkspace { - slice = append(slice, "-workspace", c.projectPath) - } else { - slice = append(slice, "-project", c.projectPath) - } - } - - return slice -} - -// PrintableCmd ... -func (c ShowBuildSettingsCommandModel) PrintableCmd() string { - cmdSlice := c.cmdSlice() - return command.PrintableCommandArgs(false, cmdSlice) -} - -// Command ... -func (c ShowBuildSettingsCommandModel) Command() *command.Model { - cmdSlice := c.cmdSlice() - return command.New(cmdSlice[0], cmdSlice[1:]...) -} - -// Cmd ... -func (c ShowBuildSettingsCommandModel) Cmd() *exec.Cmd { - command := c.Command() - return command.GetCmd() -} - -func parseBuildSettings(out string) (map[string]string, error) { - settings := map[string]string{} - - scanner := bufio.NewScanner(strings.NewReader(out)) - for scanner.Scan() { - line := strings.TrimSpace(scanner.Text()) - - if split := strings.Split(line, "="); len(split) == 2 { - key := strings.TrimSpace(split[0]) - value := strings.TrimSpace(split[1]) - value = strings.Trim(value, `"`) - - settings[key] = value - } - } - if err := scanner.Err(); err != nil { - return map[string]string{}, err - } - - return settings, nil -} - -// RunAndReturnSettings ... -func (c ShowBuildSettingsCommandModel) RunAndReturnSettings() (map[string]string, error) { - command := c.Command() - out, err := command.RunAndReturnTrimmedCombinedOutput() - if err != nil { - return map[string]string{}, err - } - - return parseBuildSettings(out) -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/show_build_settings_test.go b/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/show_build_settings_test.go deleted file mode 100644 index 462fb774..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/show_build_settings_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package xcodebuild - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestParseBuildSettings(t *testing.T) { - settings, err := parseBuildSettings(testBuildSettingsOut) - require.NoError(t, err) - - desired := map[string]string{ - "VERSION_INFO_STRING": "@(#)PROGRAM:sample-apps-osx-10-12 PROJECT:sample-apps-osx-10-12-", - "AVAILABLE_PLATFORMS": "appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator", - "EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES": "*.nib *.lproj *.framework *.gch *.xcode* *.xcassets (*) .DS_Store CVS .svn .git .hg *.pbproj *.pbxproj", - "BUILD_STYLE": "", - "ACTION": "build", - "SDK_VERSION_MINOR": "1200", - } - - require.Equal(t, desired, settings) -} - -const testBuildSettingsOut = `Build settings for action build and target sample-apps-osx-10-12: - VERSION_INFO_STRING = "@(#)PROGRAM:sample-apps-osx-10-12 PROJECT:sample-apps-osx-10-12-" - AVAILABLE_PLATFORMS = appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator - EXCLUDED_RECURSIVE_SEARCH_PATH_SUBDIRECTORIES = *.nib *.lproj *.framework *.gch *.xcode* *.xcassets (*) .DS_Store CVS .svn .git .hg *.pbproj *.pbxproj - BUILD_STYLE = - ACTION = build - SDK_VERSION_MINOR = 1200` diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/test.go b/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/test.go deleted file mode 100644 index 2953ca38..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/test.go +++ /dev/null @@ -1,142 +0,0 @@ -package xcodebuild - -import ( - "os" - "os/exec" - - "github.com/bitrise-io/go-utils/command" -) - -/* -xcodebuild [-project ] \ - -scheme \ - [-destination ]... \ - [-configuration ] \ - [-arch ]... \ - [-sdk [|]] \ - [-showBuildSettings] \ - [=]... \ - []... - -xcodebuild -workspace \ - -scheme \ - [-destination ]... \ - [-configuration ] \ - [-arch ]... \ - [-sdk [|]] \ - [-showBuildSettings] \ - [=]... \ - []... -*/ - -// TestCommandModel ... -type TestCommandModel struct { - projectPath string - isWorkspace bool - scheme string - destination string - - // buildsetting - generateCodeCoverage bool - - // buildaction - customBuildActions []string // clean, build - - // Options - customOptions []string -} - -// NewTestCommand ... -func NewTestCommand(projectPath string, isWorkspace bool) *TestCommandModel { - return &TestCommandModel{ - projectPath: projectPath, - isWorkspace: isWorkspace, - } -} - -// SetScheme ... -func (c *TestCommandModel) SetScheme(scheme string) *TestCommandModel { - c.scheme = scheme - return c -} - -// SetDestination ... -func (c *TestCommandModel) SetDestination(destination string) *TestCommandModel { - c.destination = destination - return c -} - -// SetGenerateCodeCoverage ... -func (c *TestCommandModel) SetGenerateCodeCoverage(generateCodeCoverage bool) *TestCommandModel { - c.generateCodeCoverage = generateCodeCoverage - return c -} - -// SetCustomBuildAction ... -func (c *TestCommandModel) SetCustomBuildAction(buildAction ...string) *TestCommandModel { - c.customBuildActions = buildAction - return c -} - -// SetCustomOptions ... -func (c *TestCommandModel) SetCustomOptions(customOptions []string) *TestCommandModel { - c.customOptions = customOptions - return c -} - -func (c *TestCommandModel) cmdSlice() []string { - slice := []string{toolName} - - if c.projectPath != "" { - if c.isWorkspace { - slice = append(slice, "-workspace", c.projectPath) - } else { - slice = append(slice, "-project", c.projectPath) - } - } - - if c.scheme != "" { - slice = append(slice, "-scheme", c.scheme) - } - - if c.generateCodeCoverage { - slice = append(slice, "GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES", "GCC_GENERATE_TEST_COVERAGE_FILES=YES") - } - - slice = append(slice, c.customBuildActions...) - slice = append(slice, "test") - if c.destination != "" { - slice = append(slice, "-destination", c.destination) - } - slice = append(slice, c.customOptions...) - - return slice -} - -// PrintableCmd ... -func (c TestCommandModel) PrintableCmd() string { - cmdSlice := c.cmdSlice() - return command.PrintableCommandArgs(false, cmdSlice) -} - -// Command ... -func (c TestCommandModel) Command() *command.Model { - cmdSlice := c.cmdSlice() - return command.New(cmdSlice[0], cmdSlice[1:]...) -} - -// Cmd ... -func (c TestCommandModel) Cmd() *exec.Cmd { - command := c.Command() - return command.GetCmd() -} - -// Run ... -func (c TestCommandModel) Run() error { - command := c.Command() - - command.SetStdout(os.Stdout) - command.SetStderr(os.Stderr) - - return command.Run() -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/xcodebuild.go b/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/xcodebuild.go deleted file mode 100644 index 3b35f434..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodebuild/xcodebuild.go +++ /dev/null @@ -1,13 +0,0 @@ -package xcodebuild - -import "github.com/bitrise-io/go-utils/command" - -const ( - toolName = "xcodebuild" -) - -// CommandModel ... -type CommandModel interface { - PrintableCmd() string - Command() *command.Model -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/code_sign_info.go b/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/code_sign_info.go deleted file mode 100644 index 0b7337a6..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/code_sign_info.go +++ /dev/null @@ -1,252 +0,0 @@ -package xcodeproj - -import ( - "bufio" - "encoding/json" - "fmt" - "path/filepath" - "strings" - - "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-io/go-utils/command/rubyscript" - "github.com/bitrise-io/go-utils/errorutil" - "github.com/bitrise-tools/go-xcode/plistutil" - "github.com/pkg/errors" -) - -// CodeSignInfo ... -type CodeSignInfo struct { - CodeSignEntitlementsPath string - BundleIdentifier string - CodeSignIdentity string - ProvisioningProfileSpecifier string - ProvisioningProfile string - DevelopmentTeam string -} - -// TargetMapping ... -type TargetMapping struct { - Configuration string `json:"configuration"` - ProjectTargets map[string][]string `json:"project_targets"` -} - -func clearRubyScriptOutput(out string) string { - reader := strings.NewReader(out) - scanner := bufio.NewScanner(reader) - - jsonLines := []string{} - jsonResponseStart := false - - for scanner.Scan() { - line := scanner.Text() - trimmed := strings.TrimSpace(line) - - if !jsonResponseStart && trimmed == "{" { - jsonResponseStart = true - } - if !jsonResponseStart { - continue - } - - jsonLines = append(jsonLines, line) - } - - if len(jsonLines) == 0 { - return out - } - - return strings.Join(jsonLines, "\n") -} - -func readSchemeTargetMapping(projectPth, scheme, user string) (TargetMapping, error) { - runner := rubyscript.New(codeSignInfoScriptContent) - bundleInstallCmd, err := runner.BundleInstallCommand(gemfileContent, "") - if err != nil { - return TargetMapping{}, fmt.Errorf("failed to create bundle install command, error: %s", err) - } - - if out, err := bundleInstallCmd.RunAndReturnTrimmedCombinedOutput(); err != nil { - return TargetMapping{}, fmt.Errorf("bundle install failed, output: %s, error: %s", out, err) - } - - runCmd, err := runner.RunScriptCommand() - if err != nil { - return TargetMapping{}, fmt.Errorf("failed to create script runner command, error: %s", err) - } - - envsToAppend := []string{ - "project=" + projectPth, - "scheme=" + scheme, - "user=" + user} - envs := append(runCmd.GetCmd().Env, envsToAppend...) - - runCmd.SetEnvs(envs...) - - out, err := runCmd.RunAndReturnTrimmedCombinedOutput() - if err != nil { - return TargetMapping{}, fmt.Errorf("failed to run code signing analyzer script, output: %s, error: %s", out, err) - } - - type OutputModel struct { - Data TargetMapping `json:"data"` - Error string `json:"error"` - } - var output OutputModel - if err := json.Unmarshal([]byte(out), &output); err != nil { - out = clearRubyScriptOutput(out) - if err := json.Unmarshal([]byte(out), &output); err != nil { - return TargetMapping{}, fmt.Errorf("failed to unmarshal output: %s", out) - } - } - - if output.Error != "" { - return TargetMapping{}, fmt.Errorf("failed to get provisioning profile - bundle id mapping, error: %s", output.Error) - } - - return output.Data, nil -} - -func parseBuildSettingsOut(out string) (map[string]string, error) { - reader := strings.NewReader(out) - scanner := bufio.NewScanner(reader) - - buildSettings := map[string]string{} - isBuildSettings := false - for scanner.Scan() { - line := scanner.Text() - - if strings.HasPrefix(line, "Build settings for") { - isBuildSettings = true - continue - } - if !isBuildSettings { - continue - } - - split := strings.Split(line, " = ") - if len(split) > 1 { - key := strings.TrimSpace(split[0]) - value := strings.TrimSpace(strings.Join(split[1:], " = ")) - - buildSettings[key] = value - } - } - if err := scanner.Err(); err != nil { - return map[string]string{}, errors.Wrap(err, "Failed to scan build settings") - } - - return buildSettings, nil -} - -func getTargetBuildSettingsWithXcodebuild(projectPth, target, configuration string) (map[string]string, error) { - args := []string{"-showBuildSettings", "-project", projectPth, "-target", target} - if configuration != "" { - args = append(args, "-configuration", configuration) - } - - cmd := command.New("xcodebuild", args...) - cmd.SetDir(filepath.Dir(projectPth)) - - out, err := cmd.RunAndReturnTrimmedCombinedOutput() - if err != nil { - if errorutil.IsExitStatusError(err) { - return map[string]string{}, errors.Wrapf(err, "%s failed with output: %s", cmd.PrintableCommandArgs(), out) - } - return map[string]string{}, errors.Wrapf(err, "%s failed", cmd.PrintableCommandArgs()) - } - - return parseBuildSettingsOut(out) -} - -func getBundleIDWithPlistbuddy(infoPlistPth string) (string, error) { - plistData, err := plistutil.NewPlistDataFromFile(infoPlistPth) - if err != nil { - return "", err - } - - bundleID, _ := plistData.GetString("CFBundleIdentifier") - return bundleID, nil -} - -func firstNonEmpty(values ...string) string { - for _, value := range values { - if value != "" { - return value - } - } - return "" -} - -// ResolveCodeSignInfo ... -func ResolveCodeSignInfo(projectOrWorkspacePth, scheme, user string) (map[string]CodeSignInfo, error) { - projectTargetsMapping, err := readSchemeTargetMapping(projectOrWorkspacePth, scheme, user) - if err != nil { - return nil, err - } - - resolvedCodeSignInfoMap := map[string]CodeSignInfo{} - for projectPth, targets := range projectTargetsMapping.ProjectTargets { - for _, targetName := range targets { - if targetName == "" { - return nil, errors.New("target name is empty") - } - - if projectPth == "" { - return nil, fmt.Errorf("failed to resolve which project contains target: %s", targetName) - } - - buildSettings, err := getTargetBuildSettingsWithXcodebuild(projectPth, targetName, projectTargetsMapping.Configuration) - if err != nil { - return nil, fmt.Errorf("failed to read project build settings, error: %s", err) - } - - // resolve Info.plist path - infoPlistPth := buildSettings["INFOPLIST_FILE"] - if infoPlistPth != "" { - projectDir := filepath.Dir(projectPth) - infoPlistPth = filepath.Join(projectDir, infoPlistPth) - } - // --- - - // resolve bundle id - // best case if it presents in the buildSettings, since it is expanded - bundleID := buildSettings["PRODUCT_BUNDLE_IDENTIFIER"] - if bundleID == "" && infoPlistPth != "" { - // try to find the bundle id in the Info.plist file, unless it contains env var - id, err := getBundleIDWithPlistbuddy(infoPlistPth) - if err != nil { - return nil, fmt.Errorf("failed to resolve bundle id, error: %s", err) - } - bundleID = id - } - if bundleID == "" { - return nil, fmt.Errorf("failed to resolve bundle id") - } - // --- - - codeSignEntitlementsPth := buildSettings["CODE_SIGN_ENTITLEMENTS"] - if codeSignEntitlementsPth != "" { - projectDir := filepath.Dir(projectPth) - codeSignEntitlementsPth = filepath.Join(projectDir, codeSignEntitlementsPth) - } - - codeSignIdentity := buildSettings["CODE_SIGN_IDENTITY"] - provisioningProfileSpecifier := buildSettings["PROVISIONING_PROFILE_SPECIFIER"] - provisioningProfile := buildSettings["PROVISIONING_PROFILE"] - developmentTeam := buildSettings["DEVELOPMENT_TEAM"] - - resolvedCodeSignInfo := CodeSignInfo{ - CodeSignEntitlementsPath: codeSignEntitlementsPth, - BundleIdentifier: bundleID, - CodeSignIdentity: codeSignIdentity, - ProvisioningProfileSpecifier: provisioningProfileSpecifier, - ProvisioningProfile: provisioningProfile, - DevelopmentTeam: developmentTeam, - } - - resolvedCodeSignInfoMap[targetName] = resolvedCodeSignInfo - } - } - - return resolvedCodeSignInfoMap, nil -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/code_sign_info_script.go b/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/code_sign_info_script.go deleted file mode 100644 index 68c87398..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/code_sign_info_script.go +++ /dev/null @@ -1,188 +0,0 @@ -package xcodeproj - -const codeSignInfoScriptContent = `require 'xcodeproj' -require 'json' - -def workspace_contained_projects(workspace_pth) - workspace = Xcodeproj::Workspace.new_from_xcworkspace(workspace_pth) - workspace_dir = File.dirname(workspace_pth) - project_paths = [] - workspace.file_references.each do |ref| - pth = ref.path - next unless File.extname(pth) == '.xcodeproj' - next if pth.end_with?('Pods/Pods.xcodeproj') - - project_path = File.expand_path(pth, workspace_dir) - project_paths << project_path - end - - project_paths -end - -def shared_scheme_path(project_or_workspace_pth, scheme_name) - File.join(project_or_workspace_pth, 'xcshareddata', 'xcschemes', scheme_name + '.xcscheme') -end - -def user_scheme_path(project_or_workspace_pth, scheme_name, user_name) - File.join(project_or_workspace_pth, 'xcuserdata', user_name + '.xcuserdatad', 'xcschemes', scheme_name + '.xcscheme') -end - -def read_scheme(project_or_workspace_pth, scheme_name, user_name) - project_paths = [project_or_workspace_pth] - if File.extname(project_or_workspace_pth) == '.xcworkspace' - project_paths += workspace_contained_projects(project_or_workspace_pth) - end - - project_paths.each do |project_path| - scheme_pth = shared_scheme_path(project_path, scheme_name) - scheme_pth = user_scheme_path(project_path, scheme_name, user_name) unless File.exist?(scheme_pth) - next unless File.exist?(scheme_pth) - - scheme = Xcodeproj::XCScheme.new(scheme_pth) - container_dir = File.dirname(project_path) - - return { - scheme: scheme, - container_dir: container_dir - } - end - - nil -end - -def project_buildable_target_mapping(project_dir, scheme) - build_action = scheme.build_action - return nil unless build_action - - entries = build_action.entries || [] - return nil if entries.empty? - - entries = entries.select(&:build_for_archiving?) || [] - return nil if entries.empty? - - mapping = {} - - entries.each do |entry| - buildable_references = entry.buildable_references || [] - next if buildable_references.empty? - - buildable_references = buildable_references.reject do |r| - r.target_name.to_s.empty? || r.target_referenced_container.to_s.empty? - end - next if buildable_references.empty? - - buildable_reference = entry.buildable_references.first - - target_name = buildable_reference.target_name.to_s - container = buildable_reference.target_referenced_container.to_s.sub(/^container:/, '') - next if target_name.empty? || container.empty? - - project_pth = File.expand_path(container, project_dir) - next unless File.exist?(project_pth) - - project = Xcodeproj::Project.open(project_pth) - next unless project - - target = project.targets.find { |t| t.name == target_name } - next unless target - next unless runnable_target?(target) - - targets = mapping[project_pth] || [] - targets << target - mapping[project_pth] = targets - end - - mapping -end - -def runnable_target?(target) - return false unless target.is_a?(Xcodeproj::Project::Object::PBXNativeTarget) - - product_reference = target.product_reference - return false unless product_reference - - product_reference.path.end_with?('.app', '.appex') -end - -def collect_dependent_targets(target, dependent_targets) - dependent_targets << target - - dependencies = target.dependencies || [] - return dependent_targets if dependencies.empty? - - dependencies.each do |dependency| - dependent_target = dependency.target - next unless dependent_target - next unless runnable_target?(dependent_target) - - collect_dependent_targets(dependent_target, dependent_targets) - end - - dependent_targets -end - -def find_archive_action_build_configuration_name(scheme) - archive_action = scheme.archive_action - return nil unless archive_action - - archive_action.build_configuration -end - -def read_scheme_target_mapping(project_or_workspace_pth, scheme_name, user_name) - scheme_container_dir = read_scheme(project_or_workspace_pth, scheme_name, user_name) - raise "project (#{project_or_workspace_pth}) does not contain scheme: #{scheme_name}" unless scheme_container_dir - scheme = scheme_container_dir[:scheme] - container_dir = scheme_container_dir[:container_dir] - - configuration = find_archive_action_build_configuration_name(scheme) - - target_mapping = project_buildable_target_mapping(container_dir, scheme) || [] - raise 'scheme does not contain buildable target' if target_mapping.empty? - - project_targets = {} - target_mapping.each do |project_pth, targets| - targets.each do |target| - dependent_targets = [] - dependent_targets = collect_dependent_targets(target, dependent_targets) - - project_targets[project_pth] = dependent_targets.collect(&:name) - end - end - raise 'failed to collect buildable targets' if project_targets.empty? - - { - configuration: configuration, - project_targets: project_targets - } -end - -begin - project_path = ENV['project'] - scheme_name = ENV['scheme'] - user_name = ENV['user'] - - raise 'missing project_path' if project_path.to_s.empty? - raise 'missing scheme_name' if scheme_name.to_s.empty? - raise 'missing user_name' if user_name.to_s.empty? - - mapping = read_scheme_target_mapping(project_path, scheme_name, user_name) - result = { - data: mapping - } - result_json = JSON.pretty_generate(result).to_s - puts result_json -rescue => e - error_message = e.to_s + "\n" + e.backtrace.join("\n") - result = { - error: error_message - } - result_json = result.to_json.to_s - puts result_json - exit(1) -end -` - -const gemfileContent = `source "https://rubygems.org" -gem "xcodeproj" -gem "json" -` diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/code_sign_info_script.rb b/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/code_sign_info_script.rb deleted file mode 100644 index 4c825933..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/code_sign_info_script.rb +++ /dev/null @@ -1,180 +0,0 @@ -require 'xcodeproj' -require 'json' - -def workspace_contained_projects(workspace_pth) - workspace = Xcodeproj::Workspace.new_from_xcworkspace(workspace_pth) - workspace_dir = File.dirname(workspace_pth) - project_paths = [] - workspace.file_references.each do |ref| - pth = ref.path - next unless File.extname(pth) == '.xcodeproj' - next if pth.end_with?('Pods/Pods.xcodeproj') - - project_path = File.expand_path(pth, workspace_dir) - project_paths << project_path - end - - project_paths -end - -def shared_scheme_path(project_or_workspace_pth, scheme_name) - File.join(project_or_workspace_pth, 'xcshareddata', 'xcschemes', scheme_name + '.xcscheme') -end - -def user_scheme_path(project_or_workspace_pth, scheme_name, user_name) - File.join(project_or_workspace_pth, 'xcuserdata', user_name + '.xcuserdatad', 'xcschemes', scheme_name + '.xcscheme') -end - -def read_scheme(project_or_workspace_pth, scheme_name, user_name) - project_paths = [project_or_workspace_pth] - if File.extname(project_or_workspace_pth) == '.xcworkspace' - project_paths += workspace_contained_projects(project_or_workspace_pth) - end - - project_paths.each do |project_path| - scheme_pth = shared_scheme_path(project_path, scheme_name) - scheme_pth = user_scheme_path(project_path, scheme_name, user_name) unless File.exist?(scheme_pth) - next unless File.exist?(scheme_pth) - - scheme = Xcodeproj::XCScheme.new(scheme_pth) - container_dir = File.dirname(project_path) - - return { - scheme: scheme, - container_dir: container_dir - } - end - - nil -end - -def project_buildable_target_mapping(project_dir, scheme) - build_action = scheme.build_action - return nil unless build_action - - entries = build_action.entries || [] - return nil if entries.empty? - - entries = entries.select(&:build_for_archiving?) || [] - return nil if entries.empty? - - mapping = {} - - entries.each do |entry| - buildable_references = entry.buildable_references || [] - next if buildable_references.empty? - - buildable_references = buildable_references.reject do |r| - r.target_name.to_s.empty? || r.target_referenced_container.to_s.empty? - end - next if buildable_references.empty? - - buildable_reference = entry.buildable_references.first - - target_name = buildable_reference.target_name.to_s - container = buildable_reference.target_referenced_container.to_s.sub(/^container:/, '') - next if target_name.empty? || container.empty? - - project_pth = File.expand_path(container, project_dir) - next unless File.exist?(project_pth) - - project = Xcodeproj::Project.open(project_pth) - next unless project - - target = project.targets.find { |t| t.name == target_name } - next unless target - next unless runnable_target?(target) - - targets = mapping[project_pth] || [] - targets << target - mapping[project_pth] = targets - end - - mapping -end - -def runnable_target?(target) - return false unless target.is_a?(Xcodeproj::Project::Object::PBXNativeTarget) - - product_reference = target.product_reference - return false unless product_reference - - product_reference.path.end_with?('.app', '.appex') -end - -def collect_dependent_targets(target, dependent_targets) - dependent_targets << target - - dependencies = target.dependencies || [] - return dependent_targets if dependencies.empty? - - dependencies.each do |dependency| - dependent_target = dependency.target - next unless dependent_target - next unless runnable_target?(dependent_target) - - collect_dependent_targets(dependent_target, dependent_targets) - end - - dependent_targets -end - -def find_archive_action_build_configuration_name(scheme) - archive_action = scheme.archive_action - return nil unless archive_action - - archive_action.build_configuration -end - -def read_scheme_target_mapping(project_or_workspace_pth, scheme_name, user_name) - scheme_container_dir = read_scheme(project_or_workspace_pth, scheme_name, user_name) - raise "project (#{project_or_workspace_pth}) does not contain scheme: #{scheme_name}" unless scheme_container_dir - scheme = scheme_container_dir[:scheme] - container_dir = scheme_container_dir[:container_dir] - - configuration = find_archive_action_build_configuration_name(scheme) - - target_mapping = project_buildable_target_mapping(container_dir, scheme) || [] - raise 'scheme does not contain buildable target' if target_mapping.empty? - - project_targets = {} - target_mapping.each do |project_pth, targets| - targets.each do |target| - dependent_targets = [] - dependent_targets = collect_dependent_targets(target, dependent_targets) - - project_targets[project_pth] = dependent_targets.collect(&:name) - end - end - raise 'failed to collect buildable targets' if project_targets.empty? - - { - configuration: configuration, - project_targets: project_targets - } -end - -begin - project_path = ENV['project'] - scheme_name = ENV['scheme'] - user_name = ENV['user'] - - raise 'missing project_path' if project_path.to_s.empty? - raise 'missing scheme_name' if scheme_name.to_s.empty? - raise 'missing user_name' if user_name.to_s.empty? - - mapping = read_scheme_target_mapping(project_path, scheme_name, user_name) - result = { - data: mapping - } - result_json = JSON.pretty_generate(result).to_s - puts result_json -rescue => e - error_message = e.to_s + "\n" + e.backtrace.join("\n") - result = { - error: error_message - } - result_json = result.to_json.to_s - puts result_json - exit(1) -end diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/code_sign_info_script.sh b/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/code_sign_info_script.sh deleted file mode 100644 index 9bfe6410..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/code_sign_info_script.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -# test code_sign_info_script.rb - -export user="" -export project="" -export scheme="" -export configuration="" - -ruby code_sign_info_script.rb \ No newline at end of file diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/code_sign_info_test.go b/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/code_sign_info_test.go deleted file mode 100644 index b68159dc..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/code_sign_info_test.go +++ /dev/null @@ -1,97 +0,0 @@ -package xcodeproj - -import ( - "fmt" - "os" - "path/filepath" - "testing" - - "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-io/go-utils/pathutil" - "github.com/stretchr/testify/require" -) - -func cloneSampleProject(t *testing.T, url, projectPth string) string { - tmpDir, err := pathutil.NormalizedOSTempDirPath("__codesignproperties__") - require.NoError(t, err) - - cmd := command.New("git", "clone", url, tmpDir) - require.NoError(t, cmd.Run()) - - return filepath.Join(tmpDir, projectPth) -} - -func TestResolveCodeSignInfo(t *testing.T) { - user := os.Getenv("USER") - - { - projectPth := cloneSampleProject(t, "https://github.com/bitrise-samples/sample-apps-ios-multi-target.git", "code-sign-test.xcodeproj") - - targetCodeSignInfoMap, err := ResolveCodeSignInfo(projectPth, "code-sign-test", user) - require.NoError(t, err) - require.Equal(t, 4, len(targetCodeSignInfoMap), fmt.Sprintf("%s", targetCodeSignInfoMap)) - - { - properties, ok := targetCodeSignInfoMap["watchkit-app Extension"] - require.True(t, ok) - - require.Equal(t, "com.bitrise.code-sign-test.watchkitapp.watchkitextension", properties.BundleIdentifier) - require.Equal(t, "iPhone Developer", properties.CodeSignIdentity) - require.Equal(t, "548cd560-c511-4540-8b6b-cbec4a22f49d", properties.ProvisioningProfile) - require.Equal(t, "BitriseBot-Wildcard", properties.ProvisioningProfileSpecifier) - require.Equal(t, "72SA8V3WYL", properties.DevelopmentTeam) - } - - { - properties, ok := targetCodeSignInfoMap["code-sign-test"] - require.True(t, ok) - - require.Equal(t, "com.bitrise.code-sign-test", properties.BundleIdentifier) - require.Equal(t, "iPhone Developer", properties.CodeSignIdentity) - require.Equal(t, "548cd560-c511-4540-8b6b-cbec4a22f49d", properties.ProvisioningProfile) - require.Equal(t, "BitriseBot-Wildcard", properties.ProvisioningProfileSpecifier) - require.Equal(t, "72SA8V3WYL", properties.DevelopmentTeam) - } - - { - properties, ok := targetCodeSignInfoMap["share-extension"] - require.True(t, ok) - - require.Equal(t, "com.bitrise.code-sign-test.share-extension", properties.BundleIdentifier) - require.Equal(t, "iPhone Developer", properties.CodeSignIdentity) - require.Equal(t, "548cd560-c511-4540-8b6b-cbec4a22f49d", properties.ProvisioningProfile) - require.Equal(t, "BitriseBot-Wildcard", properties.ProvisioningProfileSpecifier) - require.Equal(t, "72SA8V3WYL", properties.DevelopmentTeam) - } - - { - properties, ok := targetCodeSignInfoMap["watchkit-app"] - require.True(t, ok) - - require.Equal(t, "com.bitrise.code-sign-test.watchkitapp", properties.BundleIdentifier) - require.Equal(t, "iPhone Developer", properties.CodeSignIdentity) - require.Equal(t, "548cd560-c511-4540-8b6b-cbec4a22f49d", properties.ProvisioningProfile) - require.Equal(t, "BitriseBot-Wildcard", properties.ProvisioningProfileSpecifier) - require.Equal(t, "72SA8V3WYL", properties.DevelopmentTeam) - } - } - - { - projectPth := cloneSampleProject(t, "https://github.com/bitrise-samples/sample-apps-ios-simple-objc.git", "ios-simple-objc/ios-simple-objc.xcodeproj") - - targetCodeSignInfoMap, err := ResolveCodeSignInfo(projectPth, "ios-simple-objc", user) - require.NoError(t, err) - require.Equal(t, 1, len(targetCodeSignInfoMap), fmt.Sprintf("%s", targetCodeSignInfoMap)) - - { - properties, ok := targetCodeSignInfoMap["ios-simple-objc"] - require.True(t, ok) - - require.Equal(t, "Bitrise.ios-simple-objc", properties.BundleIdentifier) - require.Equal(t, "iPhone Developer", properties.CodeSignIdentity) - require.Equal(t, "", properties.ProvisioningProfile) - require.Equal(t, "BitriseBot-Wildcard", properties.ProvisioningProfileSpecifier) - require.Equal(t, "72SA8V3WYL", properties.DevelopmentTeam) - } - } -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/project.go b/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/project.go deleted file mode 100644 index e9fc0554..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/project.go +++ /dev/null @@ -1,70 +0,0 @@ -package xcodeproj - -import ( - "fmt" - "path/filepath" - "strings" - - "github.com/bitrise-io/go-utils/pathutil" -) - -// ProjectModel ... -type ProjectModel struct { - Pth string - Name string - SDKs []string - SharedSchemes []SchemeModel - Targets []TargetModel -} - -// NewProject ... -func NewProject(xcodeprojPth string) (ProjectModel, error) { - project := ProjectModel{ - Pth: xcodeprojPth, - Name: strings.TrimSuffix(filepath.Base(xcodeprojPth), filepath.Ext(xcodeprojPth)), - } - - // SDK - pbxprojPth := filepath.Join(xcodeprojPth, "project.pbxproj") - - if exist, err := pathutil.IsPathExists(pbxprojPth); err != nil { - return ProjectModel{}, err - } else if !exist { - return ProjectModel{}, fmt.Errorf("Project descriptor not found at: %s", pbxprojPth) - } - - sdks, err := GetBuildConfigSDKs(pbxprojPth) - if err != nil { - return ProjectModel{}, err - } - - project.SDKs = sdks - - // Shared Schemes - schemes, err := ProjectSharedSchemes(xcodeprojPth) - if err != nil { - return ProjectModel{}, err - } - - project.SharedSchemes = schemes - - // Targets - targets, err := ProjectTargets(xcodeprojPth) - if err != nil { - return ProjectModel{}, err - } - - project.Targets = targets - - return project, nil -} - -// ContainsSDK ... -func (p ProjectModel) ContainsSDK(sdk string) bool { - for _, s := range p.SDKs { - if s == sdk { - return true - } - } - return false -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/workspace.go b/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/workspace.go deleted file mode 100644 index 1d9d03be..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/workspace.go +++ /dev/null @@ -1,78 +0,0 @@ -package xcodeproj - -import ( - "fmt" - "path/filepath" - "strings" - - "github.com/bitrise-io/go-utils/pathutil" -) - -// WorkspaceModel ... -type WorkspaceModel struct { - Pth string - Name string - Projects []ProjectModel - IsPodWorkspace bool -} - -// NewWorkspace ... -func NewWorkspace(xcworkspacePth string, projectsToCheck ...string) (WorkspaceModel, error) { - workspace := WorkspaceModel{ - Pth: xcworkspacePth, - Name: strings.TrimSuffix(filepath.Base(xcworkspacePth), filepath.Ext(xcworkspacePth)), - } - - projects, err := WorkspaceProjectReferences(xcworkspacePth) - if err != nil { - return WorkspaceModel{}, err - } - - if len(projectsToCheck) > 0 { - filteredProjects := []string{} - for _, project := range projects { - for _, projectToCheck := range projectsToCheck { - if project == projectToCheck { - filteredProjects = append(filteredProjects, project) - } - } - } - projects = filteredProjects - } - - for _, xcodeprojPth := range projects { - - if exist, err := pathutil.IsPathExists(xcodeprojPth); err != nil { - return WorkspaceModel{}, err - } else if !exist { - return WorkspaceModel{}, fmt.Errorf("referred project (%s) not found", xcodeprojPth) - } - - project, err := NewProject(xcodeprojPth) - if err != nil { - return WorkspaceModel{}, err - } - - workspace.Projects = append(workspace.Projects, project) - } - - return workspace, nil -} - -// GetSharedSchemes ... -func (w WorkspaceModel) GetSharedSchemes() []SchemeModel { - schemes := []SchemeModel{} - for _, project := range w.Projects { - schemes = append(schemes, project.SharedSchemes...) - } - return schemes -} - -// GetTargets ... -func (w WorkspaceModel) GetTargets() []TargetModel { - targets := []TargetModel{} - for _, project := range w.Projects { - targets = append(targets, project.Targets...) - } - return targets -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/xcodeproj.go b/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/xcodeproj.go deleted file mode 100644 index c1b28ca6..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/xcodeproj.go +++ /dev/null @@ -1,84 +0,0 @@ -package xcodeproj - -import ( - "bufio" - "regexp" - "strings" - - "github.com/bitrise-io/go-utils/fileutil" -) - -// Extensions -const ( - // XCWorkspaceExt ... - XCWorkspaceExt = ".xcworkspace" - // XCodeProjExt ... - XCodeProjExt = ".xcodeproj" - // XCSchemeExt ... - XCSchemeExt = ".xcscheme" -) - -// IsXCodeProj ... -func IsXCodeProj(pth string) bool { - return strings.HasSuffix(pth, XCodeProjExt) -} - -// IsXCWorkspace ... -func IsXCWorkspace(pth string) bool { - return strings.HasSuffix(pth, XCWorkspaceExt) -} - -// GetBuildConfigSDKs ... -func GetBuildConfigSDKs(pbxprojPth string) ([]string, error) { - content, err := fileutil.ReadStringFromFile(pbxprojPth) - if err != nil { - return []string{}, err - } - - return getBuildConfigSDKsFromContent(content) -} - -func getBuildConfigSDKsFromContent(pbxprojContent string) ([]string, error) { - sdkMap := map[string]bool{} - - beginXCBuildConfigurationSection := `/* Begin XCBuildConfiguration section */` - endXCBuildConfigurationSection := `/* End XCBuildConfiguration section */` - isXCBuildConfigurationSection := false - - // SDKROOT = macosx; - pattern := `SDKROOT = (?P.*);` - regexp := regexp.MustCompile(pattern) - - scanner := bufio.NewScanner(strings.NewReader(pbxprojContent)) - for scanner.Scan() { - line := scanner.Text() - - if strings.TrimSpace(line) == endXCBuildConfigurationSection { - break - } - - if strings.TrimSpace(line) == beginXCBuildConfigurationSection { - isXCBuildConfigurationSection = true - continue - } - - if !isXCBuildConfigurationSection { - continue - } - - if match := regexp.FindStringSubmatch(line); len(match) == 2 { - sdk := match[1] - sdkMap[sdk] = true - } - } - if err := scanner.Err(); err != nil { - return []string{}, err - } - - sdks := []string{} - for sdk := range sdkMap { - sdks = append(sdks, sdk) - } - - return sdks, nil -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/xcodeproj_test.go b/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/xcodeproj_test.go deleted file mode 100644 index 3dc3aad6..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/xcodeproj_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package xcodeproj - -import ( - "testing" - - "github.com/bitrise-io/go-utils/testutil" - "github.com/stretchr/testify/require" -) - -func TestGetBuildConfigSDKRoot(t *testing.T) { - t.Log("ios") - { - pbxprojPth, err := testIOSPbxprojPth() - require.NoError(t, err) - - sdks, err := GetBuildConfigSDKs(pbxprojPth) - require.NoError(t, err) - testutil.EqualSlicesWithoutOrder(t, []string{"iphoneos"}, sdks) - } - - t.Log("macos") - { - pbxprojPth, err := testMacOSPbxprojPth() - require.NoError(t, err) - - sdks, err := GetBuildConfigSDKs(pbxprojPth) - require.NoError(t, err) - testutil.EqualSlicesWithoutOrder(t, []string{"macosx"}, sdks) - } -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/xcodeproj_test_files.go b/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/xcodeproj_test_files.go deleted file mode 100644 index 7960bd54..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/xcodeproj_test_files.go +++ /dev/null @@ -1,1326 +0,0 @@ -package xcodeproj - -import ( - "path/filepath" - - "github.com/bitrise-io/go-utils/fileutil" - "github.com/bitrise-io/go-utils/pathutil" -) - -func testIOSPbxprojPth() (string, error) { - tmpDir, err := pathutil.NormalizedOSTempDirPath("__bitrise_init__") - if err != nil { - return "", err - } - - pth := filepath.Join(tmpDir, "project.pbxproj") - - if err := fileutil.WriteStringToFile(pth, testIOSPbxprojContent); err != nil { - return "", err - } - - return pth, nil -} - -func testMacOSPbxprojPth() (string, error) { - tmpDir, err := pathutil.NormalizedOSTempDirPath("__bitrise_init__") - if err != nil { - return "", err - } - - pth := filepath.Join(tmpDir, "project.pbxproj") - - if err := fileutil.WriteStringToFile(pth, testMacOSPbxprojContent); err != nil { - return "", err - } - - return pth, nil -} - -const testMacOSPbxprojContent = `// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1302F7441D95BA4A005CE678 /* Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1302F7431D95BA4A005CE678 /* Session.swift */; }; - 130E6BBE1D95BBB4009D3C78 /* Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = 138F9EE61D8E7ABC00515FCA /* Command.swift */; }; - 131A3D9A1D90543F002DAF99 /* Realm.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 131A3D961D9053BB002DAF99 /* Realm.framework */; }; - 131A3D9B1D90543F002DAF99 /* Realm.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 131A3D961D9053BB002DAF99 /* Realm.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 131A3D9C1D90543F002DAF99 /* RealmSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 131A3D971D9053BB002DAF99 /* RealmSwift.framework */; }; - 131A3D9D1D90543F002DAF99 /* RealmSwift.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 131A3D971D9053BB002DAF99 /* RealmSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 131A3DA61D9060AA002DAF99 /* Yaml.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 131A3DA11D90609E002DAF99 /* Yaml.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 131A3DA71D9060C0002DAF99 /* Yaml.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 131A3DA11D90609E002DAF99 /* Yaml.framework */; }; - 131A3DAB1D906BFA002DAF99 /* BitriseTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 131A3DAA1D906BFA002DAF99 /* BitriseTool.swift */; }; - 131A3DAD1D906D54002DAF99 /* Bitrise.swift in Sources */ = {isa = PBXBuildFile; fileRef = 131A3DAC1D906D54002DAF99 /* Bitrise.swift */; }; - 131A3DAF1D906DAB002DAF99 /* Envman.swift in Sources */ = {isa = PBXBuildFile; fileRef = 131A3DAE1D906DAB002DAF99 /* Envman.swift */; }; - 131A3DB11D906DBF002DAF99 /* Stepman.swift in Sources */ = {isa = PBXBuildFile; fileRef = 131A3DB01D906DBF002DAF99 /* Stepman.swift */; }; - 131ACE731D93054B007E71E9 /* ToolManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 131ACE721D93054B007E71E9 /* ToolManager.swift */; }; - 131ACE761D9323E3007E71E9 /* Version.swift in Sources */ = {isa = PBXBuildFile; fileRef = 131ACE751D9323E3007E71E9 /* Version.swift */; }; - 13A95E821D966F040061B54F /* BashSessionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13A95E811D966F040061B54F /* BashSessionViewController.swift */; }; - 13AAE1BD1D8426FF00AEE66D /* FileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13AAE1BC1D8426FF00AEE66D /* FileManager.swift */; }; - 13B0B8F31D872E93006EA29C /* RealmManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13B0B8F21D872E93006EA29C /* RealmManager.swift */; }; - 13B958CD1D89E87600D3310D /* SystemInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13B958CC1D89E87600D3310D /* SystemInfoViewController.swift */; }; - 13B958D01D89EC7800D3310D /* RunViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13B958CE1D89EC7800D3310D /* RunViewController.swift */; }; - 13C989811D8319600028BA2C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C989801D8319600028BA2C /* AppDelegate.swift */; }; - 13C989851D8319600028BA2C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13C989841D8319600028BA2C /* Assets.xcassets */; }; - 13C989881D8319600028BA2C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 13C989861D8319600028BA2C /* Main.storyboard */; }; - 13C989931D8319600028BA2C /* BitriseStudioTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C989921D8319600028BA2C /* BitriseStudioTests.swift */; }; - 13C9899E1D8319600028BA2C /* BitriseStudioUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C9899D1D8319600028BA2C /* BitriseStudioUITests.swift */; }; - 13CA73D61D84A74800B1A323 /* AddProjectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13CA73D51D84A74800B1A323 /* AddProjectViewController.swift */; }; - 13CA73DE1D84B67200B1A323 /* Project.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13CA73DD1D84B67200B1A323 /* Project.swift */; }; - 13E3F5531D83477300AE7C20 /* ProjectsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C989821D8319600028BA2C /* ProjectsViewController.swift */; }; - 13FF5FCE1D9859EE008C7DFB /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13FF5FCD1D9859EE008C7DFB /* Log.swift */; }; - 13FF5FD11D98620A008C7DFB /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13FF5FD01D98620A008C7DFB /* String+Extensions.swift */; }; - 13FF5FD31D9862DA008C7DFB /* Data+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13FF5FD21D9862DA008C7DFB /* Data+Extensions.swift */; }; - 13FF5FD51D9872EC008C7DFB /* Pipe+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13FF5FD41D9872EC008C7DFB /* Pipe+Extensions.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 13C9898F1D8319600028BA2C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 13C989751D83195F0028BA2C /* Project object */; - proxyType = 1; - remoteGlobalIDString = 13C9897C1D83195F0028BA2C; - remoteInfo = BitriseStudio; - }; - 13C9899A1D8319600028BA2C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 13C989751D83195F0028BA2C /* Project object */; - proxyType = 1; - remoteGlobalIDString = 13C9897C1D83195F0028BA2C; - remoteInfo = BitriseStudio; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 131A3D9E1D90543F002DAF99 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 131A3D9D1D90543F002DAF99 /* RealmSwift.framework in Embed Frameworks */, - 131A3D9B1D90543F002DAF99 /* Realm.framework in Embed Frameworks */, - 131A3DA61D9060AA002DAF99 /* Yaml.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1302F7431D95BA4A005CE678 /* Session.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Session.swift; sourceTree = ""; }; - 131A3D961D9053BB002DAF99 /* Realm.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Realm.framework; path = Framworks/Realm.framework; sourceTree = ""; }; - 131A3D971D9053BB002DAF99 /* RealmSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RealmSwift.framework; path = Framworks/RealmSwift.framework; sourceTree = ""; }; - 131A3DA11D90609E002DAF99 /* Yaml.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Yaml.framework; path = Framworks/Yaml.framework; sourceTree = ""; }; - 131A3DAA1D906BFA002DAF99 /* BitriseTool.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BitriseTool.swift; sourceTree = ""; }; - 131A3DAC1D906D54002DAF99 /* Bitrise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bitrise.swift; sourceTree = ""; }; - 131A3DAE1D906DAB002DAF99 /* Envman.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Envman.swift; sourceTree = ""; }; - 131A3DB01D906DBF002DAF99 /* Stepman.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Stepman.swift; sourceTree = ""; }; - 131ACE721D93054B007E71E9 /* ToolManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ToolManager.swift; sourceTree = ""; }; - 131ACE751D9323E3007E71E9 /* Version.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Version.swift; sourceTree = ""; }; - 138F9EE61D8E7ABC00515FCA /* Command.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Command.swift; sourceTree = ""; }; - 13A95E811D966F040061B54F /* BashSessionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BashSessionViewController.swift; sourceTree = ""; }; - 13AAE1BC1D8426FF00AEE66D /* FileManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileManager.swift; sourceTree = ""; }; - 13B0B8F21D872E93006EA29C /* RealmManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RealmManager.swift; sourceTree = ""; }; - 13B958CC1D89E87600D3310D /* SystemInfoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SystemInfoViewController.swift; sourceTree = ""; }; - 13B958CE1D89EC7800D3310D /* RunViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RunViewController.swift; sourceTree = ""; }; - 13C9897D1D8319600028BA2C /* BitriseStudio.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BitriseStudio.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 13C989801D8319600028BA2C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 13C989821D8319600028BA2C /* ProjectsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProjectsViewController.swift; sourceTree = ""; }; - 13C989841D8319600028BA2C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 13C989871D8319600028BA2C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 13C989891D8319600028BA2C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 13C9898E1D8319600028BA2C /* BitriseStudioTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BitriseStudioTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 13C989921D8319600028BA2C /* BitriseStudioTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BitriseStudioTests.swift; sourceTree = ""; }; - 13C989941D8319600028BA2C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 13C989991D8319600028BA2C /* BitriseStudioUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BitriseStudioUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 13C9899D1D8319600028BA2C /* BitriseStudioUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BitriseStudioUITests.swift; sourceTree = ""; }; - 13C9899F1D8319600028BA2C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 13CA73D51D84A74800B1A323 /* AddProjectViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddProjectViewController.swift; sourceTree = ""; }; - 13CA73DD1D84B67200B1A323 /* Project.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Project.swift; sourceTree = ""; }; - 13FF5FCD1D9859EE008C7DFB /* Log.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = ""; }; - 13FF5FD01D98620A008C7DFB /* String+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = ""; }; - 13FF5FD21D9862DA008C7DFB /* Data+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Data+Extensions.swift"; sourceTree = ""; }; - 13FF5FD41D9872EC008C7DFB /* Pipe+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Pipe+Extensions.swift"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 13C9897A1D83195F0028BA2C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 131A3D9C1D90543F002DAF99 /* RealmSwift.framework in Frameworks */, - 131A3D9A1D90543F002DAF99 /* Realm.framework in Frameworks */, - 131A3DA71D9060C0002DAF99 /* Yaml.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13C9898B1D8319600028BA2C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13C989961D8319600028BA2C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 1302F7421D95BA35005CE678 /* Bash */ = { - isa = PBXGroup; - children = ( - 1302F7431D95BA4A005CE678 /* Session.swift */, - 138F9EE61D8E7ABC00515FCA /* Command.swift */, - ); - name = Bash; - sourceTree = ""; - }; - 131ACE741D9323C1007E71E9 /* Version */ = { - isa = PBXGroup; - children = ( - 131ACE751D9323E3007E71E9 /* Version.swift */, - ); - name = Version; - sourceTree = ""; - }; - 13C989741D83195F0028BA2C = { - isa = PBXGroup; - children = ( - 13C9897F1D8319600028BA2C /* BitriseStudio */, - 13C989911D8319600028BA2C /* BitriseStudioTests */, - 13C9899C1D8319600028BA2C /* BitriseStudioUITests */, - 13C9897E1D8319600028BA2C /* Products */, - 13CA73D71D84B5C500B1A323 /* Frameworks */, - ); - sourceTree = ""; - }; - 13C9897E1D8319600028BA2C /* Products */ = { - isa = PBXGroup; - children = ( - 13C9897D1D8319600028BA2C /* BitriseStudio.app */, - 13C9898E1D8319600028BA2C /* BitriseStudioTests.xctest */, - 13C989991D8319600028BA2C /* BitriseStudioUITests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 13C9897F1D8319600028BA2C /* BitriseStudio */ = { - isa = PBXGroup; - children = ( - 13FF5FCF1D9861E3008C7DFB /* Extensions */, - 13FF5FCC1D9859DB008C7DFB /* Log */, - 1302F7421D95BA35005CE678 /* Bash */, - 131ACE741D9323C1007E71E9 /* Version */, - 13CA73DC1D84B63E00B1A323 /* Models */, - 13E3F5501D8342DD00AE7C20 /* Managers */, - 13E3F54D1D8341DF00AE7C20 /* Controllers */, - 13E3F54E1D83429900AE7C20 /* Supporting Files */, - 13E3F54F1D8342BC00AE7C20 /* Assets */, - 13C989801D8319600028BA2C /* AppDelegate.swift */, - ); - path = BitriseStudio; - sourceTree = ""; - }; - 13C989911D8319600028BA2C /* BitriseStudioTests */ = { - isa = PBXGroup; - children = ( - 13C989921D8319600028BA2C /* BitriseStudioTests.swift */, - 13C989941D8319600028BA2C /* Info.plist */, - ); - path = BitriseStudioTests; - sourceTree = ""; - }; - 13C9899C1D8319600028BA2C /* BitriseStudioUITests */ = { - isa = PBXGroup; - children = ( - 13C9899D1D8319600028BA2C /* BitriseStudioUITests.swift */, - 13C9899F1D8319600028BA2C /* Info.plist */, - ); - path = BitriseStudioUITests; - sourceTree = ""; - }; - 13CA73D71D84B5C500B1A323 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 131A3DA11D90609E002DAF99 /* Yaml.framework */, - 131A3D961D9053BB002DAF99 /* Realm.framework */, - 131A3D971D9053BB002DAF99 /* RealmSwift.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 13CA73DC1D84B63E00B1A323 /* Models */ = { - isa = PBXGroup; - children = ( - 13CA73DD1D84B67200B1A323 /* Project.swift */, - 131A3DAA1D906BFA002DAF99 /* BitriseTool.swift */, - 131A3DAC1D906D54002DAF99 /* Bitrise.swift */, - 131A3DAE1D906DAB002DAF99 /* Envman.swift */, - 131A3DB01D906DBF002DAF99 /* Stepman.swift */, - ); - name = Models; - sourceTree = ""; - }; - 13E3F54D1D8341DF00AE7C20 /* Controllers */ = { - isa = PBXGroup; - children = ( - 13C989861D8319600028BA2C /* Main.storyboard */, - 13C989821D8319600028BA2C /* ProjectsViewController.swift */, - 13CA73D51D84A74800B1A323 /* AddProjectViewController.swift */, - 13B958CC1D89E87600D3310D /* SystemInfoViewController.swift */, - 13B958CE1D89EC7800D3310D /* RunViewController.swift */, - 13A95E811D966F040061B54F /* BashSessionViewController.swift */, - ); - name = Controllers; - sourceTree = ""; - }; - 13E3F54E1D83429900AE7C20 /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 13C989891D8319600028BA2C /* Info.plist */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; - 13E3F54F1D8342BC00AE7C20 /* Assets */ = { - isa = PBXGroup; - children = ( - 13C989841D8319600028BA2C /* Assets.xcassets */, - ); - name = Assets; - sourceTree = ""; - }; - 13E3F5501D8342DD00AE7C20 /* Managers */ = { - isa = PBXGroup; - children = ( - 13AAE1BC1D8426FF00AEE66D /* FileManager.swift */, - 13B0B8F21D872E93006EA29C /* RealmManager.swift */, - 131ACE721D93054B007E71E9 /* ToolManager.swift */, - ); - name = Managers; - sourceTree = ""; - }; - 13FF5FCC1D9859DB008C7DFB /* Log */ = { - isa = PBXGroup; - children = ( - 13FF5FCD1D9859EE008C7DFB /* Log.swift */, - ); - name = Log; - sourceTree = ""; - }; - 13FF5FCF1D9861E3008C7DFB /* Extensions */ = { - isa = PBXGroup; - children = ( - 13FF5FD01D98620A008C7DFB /* String+Extensions.swift */, - 13FF5FD21D9862DA008C7DFB /* Data+Extensions.swift */, - 13FF5FD41D9872EC008C7DFB /* Pipe+Extensions.swift */, - ); - name = Extensions; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 13C9897C1D83195F0028BA2C /* BitriseStudio */ = { - isa = PBXNativeTarget; - buildConfigurationList = 13C989A21D8319600028BA2C /* Build configuration list for PBXNativeTarget "BitriseStudio" */; - buildPhases = ( - 13C989791D83195F0028BA2C /* Sources */, - 13C9897A1D83195F0028BA2C /* Frameworks */, - 13C9897B1D83195F0028BA2C /* Resources */, - 131A3D9E1D90543F002DAF99 /* Embed Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = BitriseStudio; - productName = BitriseStudio; - productReference = 13C9897D1D8319600028BA2C /* BitriseStudio.app */; - productType = "com.apple.product-type.application"; - }; - 13C9898D1D8319600028BA2C /* BitriseStudioTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 13C989A51D8319600028BA2C /* Build configuration list for PBXNativeTarget "BitriseStudioTests" */; - buildPhases = ( - 13C9898A1D8319600028BA2C /* Sources */, - 13C9898B1D8319600028BA2C /* Frameworks */, - 13C9898C1D8319600028BA2C /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 13C989901D8319600028BA2C /* PBXTargetDependency */, - ); - name = BitriseStudioTests; - productName = BitriseStudioTests; - productReference = 13C9898E1D8319600028BA2C /* BitriseStudioTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 13C989981D8319600028BA2C /* BitriseStudioUITests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 13C989A81D8319600028BA2C /* Build configuration list for PBXNativeTarget "BitriseStudioUITests" */; - buildPhases = ( - 13C989951D8319600028BA2C /* Sources */, - 13C989961D8319600028BA2C /* Frameworks */, - 13C989971D8319600028BA2C /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 13C9899B1D8319600028BA2C /* PBXTargetDependency */, - ); - name = BitriseStudioUITests; - productName = BitriseStudioUITests; - productReference = 13C989991D8319600028BA2C /* BitriseStudioUITests.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 13C989751D83195F0028BA2C /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 0800; - LastUpgradeCheck = 0810; - ORGANIZATIONNAME = "Krisztian Goedrei"; - TargetAttributes = { - 13C9897C1D83195F0028BA2C = { - CreatedOnToolsVersion = 8.0; - DevelopmentTeam = 9NS44DLTN7; - ProvisioningStyle = Manual; - }; - 13C9898D1D8319600028BA2C = { - CreatedOnToolsVersion = 8.0; - DevelopmentTeam = L935L4GU3F; - ProvisioningStyle = Automatic; - TestTargetID = 13C9897C1D83195F0028BA2C; - }; - 13C989981D8319600028BA2C = { - CreatedOnToolsVersion = 8.0; - DevelopmentTeam = L935L4GU3F; - ProvisioningStyle = Automatic; - TestTargetID = 13C9897C1D83195F0028BA2C; - }; - }; - }; - buildConfigurationList = 13C989781D83195F0028BA2C /* Build configuration list for PBXProject "BitriseStudio" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 13C989741D83195F0028BA2C; - productRefGroup = 13C9897E1D8319600028BA2C /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 13C9897C1D83195F0028BA2C /* BitriseStudio */, - 13C9898D1D8319600028BA2C /* BitriseStudioTests */, - 13C989981D8319600028BA2C /* BitriseStudioUITests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 13C9897B1D83195F0028BA2C /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 13C989851D8319600028BA2C /* Assets.xcassets in Resources */, - 13C989881D8319600028BA2C /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13C9898C1D8319600028BA2C /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13C989971D8319600028BA2C /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 13C989791D83195F0028BA2C /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 13FF5FD11D98620A008C7DFB /* String+Extensions.swift in Sources */, - 131A3DB11D906DBF002DAF99 /* Stepman.swift in Sources */, - 13B0B8F31D872E93006EA29C /* RealmManager.swift in Sources */, - 13FF5FCE1D9859EE008C7DFB /* Log.swift in Sources */, - 131A3DAB1D906BFA002DAF99 /* BitriseTool.swift in Sources */, - 13E3F5531D83477300AE7C20 /* ProjectsViewController.swift in Sources */, - 130E6BBE1D95BBB4009D3C78 /* Command.swift in Sources */, - 13FF5FD51D9872EC008C7DFB /* Pipe+Extensions.swift in Sources */, - 131ACE731D93054B007E71E9 /* ToolManager.swift in Sources */, - 13A95E821D966F040061B54F /* BashSessionViewController.swift in Sources */, - 13C989811D8319600028BA2C /* AppDelegate.swift in Sources */, - 1302F7441D95BA4A005CE678 /* Session.swift in Sources */, - 131ACE761D9323E3007E71E9 /* Version.swift in Sources */, - 13B958CD1D89E87600D3310D /* SystemInfoViewController.swift in Sources */, - 13CA73D61D84A74800B1A323 /* AddProjectViewController.swift in Sources */, - 131A3DAD1D906D54002DAF99 /* Bitrise.swift in Sources */, - 13FF5FD31D9862DA008C7DFB /* Data+Extensions.swift in Sources */, - 13AAE1BD1D8426FF00AEE66D /* FileManager.swift in Sources */, - 13B958D01D89EC7800D3310D /* RunViewController.swift in Sources */, - 131A3DAF1D906DAB002DAF99 /* Envman.swift in Sources */, - 13CA73DE1D84B67200B1A323 /* Project.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13C9898A1D8319600028BA2C /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 13C989931D8319600028BA2C /* BitriseStudioTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13C989951D8319600028BA2C /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 13C9899E1D8319600028BA2C /* BitriseStudioUITests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 13C989901D8319600028BA2C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 13C9897C1D83195F0028BA2C /* BitriseStudio */; - targetProxy = 13C9898F1D8319600028BA2C /* PBXContainerItemProxy */; - }; - 13C9899B1D8319600028BA2C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 13C9897C1D83195F0028BA2C /* BitriseStudio */; - targetProxy = 13C9899A1D8319600028BA2C /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 13C989861D8319600028BA2C /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 13C989871D8319600028BA2C /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 13C989A01D8319600028BA2C /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 13C989A11D8319600028BA2C /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - }; - name = Release; - }; - 13C989A31D8319600028BA2C /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Mac Developer: Some Dude (KYXQXCWE3G)"; - COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = 9NS44DLTN7; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/Mac", - "$(PROJECT_DIR)/Framworks", - ); - INFOPLIST_FILE = BitriseStudio/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.bitrise.BitriseStudio; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = "b17a1b90-9459-4620-9332-347d399f7cd9"; - PROVISIONING_PROFILE_SPECIFIER = "Mac Development Wildcard"; - SWIFT_VERSION = 3.0; - }; - name = Debug; - }; - 13C989A41D8319600028BA2C /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application"; - COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = 9NS44DLTN7; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/Mac", - "$(PROJECT_DIR)/Framworks", - ); - INFOPLIST_FILE = BitriseStudio/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.bitrise.BitriseStudio; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = "1bb807b8-a953-459e-85ca-c86d3fe13645"; - PROVISIONING_PROFILE_SPECIFIER = "Mac App-Store Wildcards"; - SWIFT_VERSION = 3.0; - }; - name = Release; - }; - 13C989A61D8319600028BA2C /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - BUNDLE_LOADER = "$(TEST_HOST)"; - COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = L935L4GU3F; - INFOPLIST_FILE = BitriseStudioTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = bitrise.BitriseStudioTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BitriseStudio.app/Contents/MacOS/BitriseStudio"; - }; - name = Debug; - }; - 13C989A71D8319600028BA2C /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - BUNDLE_LOADER = "$(TEST_HOST)"; - COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = L935L4GU3F; - INFOPLIST_FILE = BitriseStudioTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = bitrise.BitriseStudioTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BitriseStudio.app/Contents/MacOS/BitriseStudio"; - }; - name = Release; - }; - 13C989A91D8319600028BA2C /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = L935L4GU3F; - INFOPLIST_FILE = BitriseStudioUITests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = bitrise.BitriseStudioUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; - TEST_TARGET_NAME = BitriseStudio; - }; - name = Debug; - }; - 13C989AA1D8319600028BA2C /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = L935L4GU3F; - INFOPLIST_FILE = BitriseStudioUITests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = bitrise.BitriseStudioUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; - TEST_TARGET_NAME = BitriseStudio; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 13C989781D83195F0028BA2C /* Build configuration list for PBXProject "BitriseStudio" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 13C989A01D8319600028BA2C /* Debug */, - 13C989A11D8319600028BA2C /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 13C989A21D8319600028BA2C /* Build configuration list for PBXNativeTarget "BitriseStudio" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 13C989A31D8319600028BA2C /* Debug */, - 13C989A41D8319600028BA2C /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 13C989A51D8319600028BA2C /* Build configuration list for PBXNativeTarget "BitriseStudioTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 13C989A61D8319600028BA2C /* Debug */, - 13C989A71D8319600028BA2C /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 13C989A81D8319600028BA2C /* Build configuration list for PBXNativeTarget "BitriseStudioUITests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 13C989A91D8319600028BA2C /* Debug */, - 13C989AA1D8319600028BA2C /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 13C989751D83195F0028BA2C /* Project object */; -} -` - -const testIOSPbxprojContent = ` -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 13C4D5AB1DDDDED300D5DC29 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C4D5AA1DDDDED300D5DC29 /* AppDelegate.swift */; }; - 13C4D5AD1DDDDED300D5DC29 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C4D5AC1DDDDED300D5DC29 /* ViewController.swift */; }; - 13C4D5B01DDDDED300D5DC29 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 13C4D5AE1DDDDED300D5DC29 /* Main.storyboard */; }; - 13C4D5B21DDDDED300D5DC29 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13C4D5B11DDDDED300D5DC29 /* Assets.xcassets */; }; - 13C4D5B51DDDDED300D5DC29 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 13C4D5B31DDDDED300D5DC29 /* LaunchScreen.storyboard */; }; - 13C4D5C01DDDDED400D5DC29 /* BitriseFastlaneSampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C4D5BF1DDDDED400D5DC29 /* BitriseFastlaneSampleTests.swift */; }; - 13C4D5CB1DDDDED400D5DC29 /* BitriseFastlaneSampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C4D5CA1DDDDED400D5DC29 /* BitriseFastlaneSampleUITests.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 13C4D5BC1DDDDED400D5DC29 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 13C4D59F1DDDDED300D5DC29 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 13C4D5A61DDDDED300D5DC29; - remoteInfo = BitriseFastlaneSample; - }; - 13C4D5C71DDDDED400D5DC29 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 13C4D59F1DDDDED300D5DC29 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 13C4D5A61DDDDED300D5DC29; - remoteInfo = BitriseFastlaneSample; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 13C4D5A71DDDDED300D5DC29 /* BitriseFastlaneSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BitriseFastlaneSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 13C4D5AA1DDDDED300D5DC29 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 13C4D5AC1DDDDED300D5DC29 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 13C4D5AF1DDDDED300D5DC29 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 13C4D5B11DDDDED300D5DC29 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 13C4D5B41DDDDED300D5DC29 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 13C4D5B61DDDDED300D5DC29 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 13C4D5BB1DDDDED400D5DC29 /* BitriseFastlaneSampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BitriseFastlaneSampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 13C4D5BF1DDDDED400D5DC29 /* BitriseFastlaneSampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BitriseFastlaneSampleTests.swift; sourceTree = ""; }; - 13C4D5C11DDDDED400D5DC29 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 13C4D5C61DDDDED400D5DC29 /* BitriseFastlaneSampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BitriseFastlaneSampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 13C4D5CA1DDDDED400D5DC29 /* BitriseFastlaneSampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BitriseFastlaneSampleUITests.swift; sourceTree = ""; }; - 13C4D5CC1DDDDED400D5DC29 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 13C4D5A41DDDDED300D5DC29 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13C4D5B81DDDDED400D5DC29 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13C4D5C31DDDDED400D5DC29 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 13C4D59E1DDDDED300D5DC29 = { - isa = PBXGroup; - children = ( - 13C4D5A91DDDDED300D5DC29 /* BitriseFastlaneSample */, - 13C4D5BE1DDDDED400D5DC29 /* BitriseFastlaneSampleTests */, - 13C4D5C91DDDDED400D5DC29 /* BitriseFastlaneSampleUITests */, - 13C4D5A81DDDDED300D5DC29 /* Products */, - ); - sourceTree = ""; - }; - 13C4D5A81DDDDED300D5DC29 /* Products */ = { - isa = PBXGroup; - children = ( - 13C4D5A71DDDDED300D5DC29 /* BitriseFastlaneSample.app */, - 13C4D5BB1DDDDED400D5DC29 /* BitriseFastlaneSampleTests.xctest */, - 13C4D5C61DDDDED400D5DC29 /* BitriseFastlaneSampleUITests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 13C4D5A91DDDDED300D5DC29 /* BitriseFastlaneSample */ = { - isa = PBXGroup; - children = ( - 13C4D5AA1DDDDED300D5DC29 /* AppDelegate.swift */, - 13C4D5AC1DDDDED300D5DC29 /* ViewController.swift */, - 13C4D5AE1DDDDED300D5DC29 /* Main.storyboard */, - 13C4D5B11DDDDED300D5DC29 /* Assets.xcassets */, - 13C4D5B31DDDDED300D5DC29 /* LaunchScreen.storyboard */, - 13C4D5B61DDDDED300D5DC29 /* Info.plist */, - ); - path = BitriseFastlaneSample; - sourceTree = ""; - }; - 13C4D5BE1DDDDED400D5DC29 /* BitriseFastlaneSampleTests */ = { - isa = PBXGroup; - children = ( - 13C4D5BF1DDDDED400D5DC29 /* BitriseFastlaneSampleTests.swift */, - 13C4D5C11DDDDED400D5DC29 /* Info.plist */, - ); - path = BitriseFastlaneSampleTests; - sourceTree = ""; - }; - 13C4D5C91DDDDED400D5DC29 /* BitriseFastlaneSampleUITests */ = { - isa = PBXGroup; - children = ( - 13C4D5CA1DDDDED400D5DC29 /* BitriseFastlaneSampleUITests.swift */, - 13C4D5CC1DDDDED400D5DC29 /* Info.plist */, - ); - path = BitriseFastlaneSampleUITests; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 13C4D5A61DDDDED300D5DC29 /* BitriseFastlaneSample */ = { - isa = PBXNativeTarget; - buildConfigurationList = 13C4D5CF1DDDDED400D5DC29 /* Build configuration list for PBXNativeTarget "BitriseFastlaneSample" */; - buildPhases = ( - 13C4D5A31DDDDED300D5DC29 /* Sources */, - 13C4D5A41DDDDED300D5DC29 /* Frameworks */, - 13C4D5A51DDDDED300D5DC29 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = BitriseFastlaneSample; - productName = BitriseFastlaneSample; - productReference = 13C4D5A71DDDDED300D5DC29 /* BitriseFastlaneSample.app */; - productType = "com.apple.product-type.application"; - }; - 13C4D5BA1DDDDED400D5DC29 /* BitriseFastlaneSampleTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 13C4D5D21DDDDED400D5DC29 /* Build configuration list for PBXNativeTarget "BitriseFastlaneSampleTests" */; - buildPhases = ( - 13C4D5B71DDDDED400D5DC29 /* Sources */, - 13C4D5B81DDDDED400D5DC29 /* Frameworks */, - 13C4D5B91DDDDED400D5DC29 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 13C4D5BD1DDDDED400D5DC29 /* PBXTargetDependency */, - ); - name = BitriseFastlaneSampleTests; - productName = BitriseFastlaneSampleTests; - productReference = 13C4D5BB1DDDDED400D5DC29 /* BitriseFastlaneSampleTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 13C4D5C51DDDDED400D5DC29 /* BitriseFastlaneSampleUITests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 13C4D5D51DDDDED400D5DC29 /* Build configuration list for PBXNativeTarget "BitriseFastlaneSampleUITests" */; - buildPhases = ( - 13C4D5C21DDDDED400D5DC29 /* Sources */, - 13C4D5C31DDDDED400D5DC29 /* Frameworks */, - 13C4D5C41DDDDED400D5DC29 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 13C4D5C81DDDDED400D5DC29 /* PBXTargetDependency */, - ); - name = BitriseFastlaneSampleUITests; - productName = BitriseFastlaneSampleUITests; - productReference = 13C4D5C61DDDDED400D5DC29 /* BitriseFastlaneSampleUITests.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 13C4D59F1DDDDED300D5DC29 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 0810; - LastUpgradeCheck = 0810; - ORGANIZATIONNAME = "Krisztian Goedrei"; - TargetAttributes = { - 13C4D5A61DDDDED300D5DC29 = { - CreatedOnToolsVersion = 8.1; - DevelopmentTeam = 9NS44DLTN7; - ProvisioningStyle = Manual; - }; - 13C4D5BA1DDDDED400D5DC29 = { - CreatedOnToolsVersion = 8.1; - DevelopmentTeam = 72SA8V3WYL; - ProvisioningStyle = Automatic; - TestTargetID = 13C4D5A61DDDDED300D5DC29; - }; - 13C4D5C51DDDDED400D5DC29 = { - CreatedOnToolsVersion = 8.1; - DevelopmentTeam = 72SA8V3WYL; - ProvisioningStyle = Automatic; - TestTargetID = 13C4D5A61DDDDED300D5DC29; - }; - }; - }; - buildConfigurationList = 13C4D5A21DDDDED300D5DC29 /* Build configuration list for PBXProject "BitriseFastlaneSample" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 13C4D59E1DDDDED300D5DC29; - productRefGroup = 13C4D5A81DDDDED300D5DC29 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 13C4D5A61DDDDED300D5DC29 /* BitriseFastlaneSample */, - 13C4D5BA1DDDDED400D5DC29 /* BitriseFastlaneSampleTests */, - 13C4D5C51DDDDED400D5DC29 /* BitriseFastlaneSampleUITests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 13C4D5A51DDDDED300D5DC29 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 13C4D5B51DDDDED300D5DC29 /* LaunchScreen.storyboard in Resources */, - 13C4D5B21DDDDED300D5DC29 /* Assets.xcassets in Resources */, - 13C4D5B01DDDDED300D5DC29 /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13C4D5B91DDDDED400D5DC29 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13C4D5C41DDDDED400D5DC29 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 13C4D5A31DDDDED300D5DC29 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 13C4D5AD1DDDDED300D5DC29 /* ViewController.swift in Sources */, - 13C4D5AB1DDDDED300D5DC29 /* AppDelegate.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13C4D5B71DDDDED400D5DC29 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 13C4D5C01DDDDED400D5DC29 /* BitriseFastlaneSampleTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13C4D5C21DDDDED400D5DC29 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 13C4D5CB1DDDDED400D5DC29 /* BitriseFastlaneSampleUITests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 13C4D5BD1DDDDED400D5DC29 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 13C4D5A61DDDDED300D5DC29 /* BitriseFastlaneSample */; - targetProxy = 13C4D5BC1DDDDED400D5DC29 /* PBXContainerItemProxy */; - }; - 13C4D5C81DDDDED400D5DC29 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 13C4D5A61DDDDED300D5DC29 /* BitriseFastlaneSample */; - targetProxy = 13C4D5C71DDDDED400D5DC29 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 13C4D5AE1DDDDED300D5DC29 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 13C4D5AF1DDDDED300D5DC29 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 13C4D5B31DDDDED300D5DC29 /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 13C4D5B41DDDDED300D5DC29 /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 13C4D5CD1DDDDED400D5DC29 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.1; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 13C4D5CE1DDDDED400D5DC29 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.1; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 13C4D5D01DDDDED400D5DC29 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - DEVELOPMENT_TEAM = 9NS44DLTN7; - INFOPLIST_FILE = BitriseFastlaneSample/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.bitrise.BitriseFastlaneSample; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = "8e4701a8-01fb-4467-aad7-5a6c541795f0"; - PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.bitrise.BitriseFastlaneSample"; - SWIFT_VERSION = 3.0; - }; - name = Debug; - }; - 13C4D5D11DDDDED400D5DC29 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - DEVELOPMENT_TEAM = 9NS44DLTN7; - INFOPLIST_FILE = BitriseFastlaneSample/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.bitrise.BitriseFastlaneSample; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE = "8e4701a8-01fb-4467-aad7-5a6c541795f0"; - PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.bitrise.BitriseFastlaneSample"; - SWIFT_VERSION = 3.0; - }; - name = Release; - }; - 13C4D5D31DDDDED400D5DC29 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - BUNDLE_LOADER = "$(TEST_HOST)"; - DEVELOPMENT_TEAM = 72SA8V3WYL; - INFOPLIST_FILE = BitriseFastlaneSampleTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.bitrise.BitriseFastlaneSampleTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BitriseFastlaneSample.app/BitriseFastlaneSample"; - }; - name = Debug; - }; - 13C4D5D41DDDDED400D5DC29 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - BUNDLE_LOADER = "$(TEST_HOST)"; - DEVELOPMENT_TEAM = 72SA8V3WYL; - INFOPLIST_FILE = BitriseFastlaneSampleTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.bitrise.BitriseFastlaneSampleTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/BitriseFastlaneSample.app/BitriseFastlaneSample"; - }; - name = Release; - }; - 13C4D5D61DDDDED400D5DC29 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - DEVELOPMENT_TEAM = 72SA8V3WYL; - INFOPLIST_FILE = BitriseFastlaneSampleUITests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.bitrise.BitriseFastlaneSampleUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; - TEST_TARGET_NAME = BitriseFastlaneSample; - }; - name = Debug; - }; - 13C4D5D71DDDDED400D5DC29 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - DEVELOPMENT_TEAM = 72SA8V3WYL; - INFOPLIST_FILE = BitriseFastlaneSampleUITests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.bitrise.BitriseFastlaneSampleUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; - TEST_TARGET_NAME = BitriseFastlaneSample; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 13C4D5A21DDDDED300D5DC29 /* Build configuration list for PBXProject "BitriseFastlaneSample" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 13C4D5CD1DDDDED400D5DC29 /* Debug */, - 13C4D5CE1DDDDED400D5DC29 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 13C4D5CF1DDDDED400D5DC29 /* Build configuration list for PBXNativeTarget "BitriseFastlaneSample" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 13C4D5D01DDDDED400D5DC29 /* Debug */, - 13C4D5D11DDDDED400D5DC29 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 13C4D5D21DDDDED400D5DC29 /* Build configuration list for PBXNativeTarget "BitriseFastlaneSampleTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 13C4D5D31DDDDED400D5DC29 /* Debug */, - 13C4D5D41DDDDED400D5DC29 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 13C4D5D51DDDDED400D5DC29 /* Build configuration list for PBXNativeTarget "BitriseFastlaneSampleUITests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 13C4D5D61DDDDED400D5DC29 /* Debug */, - 13C4D5D71DDDDED400D5DC29 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 13C4D59F1DDDDED300D5DC29 /* Project object */; -} -` diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/xcscheme.go b/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/xcscheme.go deleted file mode 100644 index 81102847..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcodeproj/xcscheme.go +++ /dev/null @@ -1,250 +0,0 @@ -package xcodeproj - -import ( - "bufio" - "fmt" - "os" - "path" - "path/filepath" - "regexp" - "sort" - "strings" - - "github.com/bitrise-io/go-utils/fileutil" - "github.com/bitrise-io/go-utils/pathutil" -) - -// SchemeModel ... -type SchemeModel struct { - Name string - HasXCTest bool -} - -func filterSharedSchemeFilePaths(paths []string) []string { - isSharedSchemeFilePath := func(pth string) bool { - regexpPattern := filepath.Join(".*[/]?xcshareddata", "xcschemes", ".+[.]xcscheme") - regexp := regexp.MustCompile(regexpPattern) - return (regexp.FindString(pth) != "") - } - - filteredPaths := []string{} - for _, pth := range paths { - if isSharedSchemeFilePath(pth) { - filteredPaths = append(filteredPaths, pth) - } - } - - sort.Strings(filteredPaths) - - return filteredPaths -} - -func sharedSchemeFilePaths(projectOrWorkspacePth string) ([]string, error) { - filesInDir := func(dir string) ([]string, error) { - files := []string{} - if err := filepath.Walk(dir, func(path string, f os.FileInfo, err error) error { - files = append(files, path) - return nil - }); err != nil { - return []string{}, err - } - return files, nil - } - - paths, err := filesInDir(projectOrWorkspacePth) - if err != nil { - return []string{}, err - } - return filterSharedSchemeFilePaths(paths), nil -} - -// SchemeNameFromPath ... -func SchemeNameFromPath(schemePth string) string { - basename := filepath.Base(schemePth) - ext := filepath.Ext(schemePth) - if ext != XCSchemeExt { - return "" - } - return strings.TrimSuffix(basename, ext) -} - -func schemeFileContentContainsXCTestBuildAction(schemeFileContent string) (bool, error) { - testActionStartPattern := ".+)"`) - testableReferenceEndPattern := "" - isTestableReference := false - - xctestBuildableReferenceNameRegexp := regexp.MustCompile(`BuildableName = ".+.xctest"`) - - scanner := bufio.NewScanner(strings.NewReader(schemeFileContent)) - for scanner.Scan() { - line := scanner.Text() - - if strings.TrimSpace(line) == testActionEndPattern { - break - } - - if strings.TrimSpace(line) == testActionStartPattern { - isTestableAction = true - continue - } - - if !isTestableAction { - continue - } - - // TestAction - - if strings.TrimSpace(line) == testableReferenceEndPattern { - isTestableReference = false - continue - } - - if strings.TrimSpace(line) == testableReferenceStartPattern { - isTestableReference = true - continue - } - - if !isTestableReference { - continue - } - - // TestableReference - - if matches := testableReferenceSkippedRegexp.FindStringSubmatch(line); len(matches) > 1 { - skipped := matches[1] - if skipped != "NO" { - break - } - } - - if match := xctestBuildableReferenceNameRegexp.FindString(line); match != "" { - return true, nil - } - } - - if err := scanner.Err(); err != nil { - return false, err - } - - return false, nil -} - -// SchemeFileContainsXCTestBuildAction ... -func SchemeFileContainsXCTestBuildAction(schemeFilePth string) (bool, error) { - content, err := fileutil.ReadStringFromFile(schemeFilePth) - if err != nil { - return false, err - } - - return schemeFileContentContainsXCTestBuildAction(content) -} - -func sharedSchemes(projectOrWorkspacePth string) ([]SchemeModel, error) { - schemePaths, err := sharedSchemeFilePaths(projectOrWorkspacePth) - if err != nil { - return []SchemeModel{}, err - } - - schemes := []SchemeModel{} - for _, schemePth := range schemePaths { - schemeName := SchemeNameFromPath(schemePth) - - hasXCTest, err := SchemeFileContainsXCTestBuildAction(schemePth) - if err != nil { - return []SchemeModel{}, err - } - - schemes = append(schemes, SchemeModel{ - Name: schemeName, - HasXCTest: hasXCTest, - }) - } - - return schemes, nil -} - -// ProjectSharedSchemes ... -func ProjectSharedSchemes(projectPth string) ([]SchemeModel, error) { - return sharedSchemes(projectPth) -} - -// WorkspaceProjectReferences ... -func WorkspaceProjectReferences(workspace string) ([]string, error) { - projects := []string{} - - workspaceDir := filepath.Dir(workspace) - - xcworkspacedataPth := path.Join(workspace, "contents.xcworkspacedata") - if exist, err := pathutil.IsPathExists(xcworkspacedataPth); err != nil { - return []string{}, err - } else if !exist { - return []string{}, fmt.Errorf("contents.xcworkspacedata does not exist at: %s", xcworkspacedataPth) - } - - xcworkspacedataStr, err := fileutil.ReadStringFromFile(xcworkspacedataPth) - if err != nil { - return []string{}, err - } - - xcworkspacedataLines := strings.Split(xcworkspacedataStr, "\n") - fileRefStart := false - regexp := regexp.MustCompile(`location = "(.+):(.+).xcodeproj"`) - - for _, line := range xcworkspacedataLines { - if strings.Contains(line, "[A-Z0-9]+) /\* (?P.*) \*/ = {`) - endPBXNativeTargetPattern := `};` - isPBXNativeTarget := false - - // isa = PBXNativeTarget; - isaRegexp := regexp.MustCompile(`\s*isa = (?P.*);`) - - beginDependenciesPattern := `dependencies = (` - dependencieRegexp := regexp.MustCompile(`\s*(?P[A-Z0-9]+) /\* (?P.*) \*/,`) - endDependenciesPattern := `);` - isDependencies := false - - // name = SampleAppWithCocoapods; - nameRegexp := regexp.MustCompile(`\s*name = (?P.*);`) - // productReference = BAAFFEED19EE788800F3AC91 /* SampleAppWithCocoapodsTests.xctest */; - productReferenceRegexp := regexp.MustCompile(`\s*productReference = (?P[A-Z0-9]+) /\* (?P.*) \*/;`) - // productType = "com.apple.product-type.bundle.unit-test"; - productTypeRegexp := regexp.MustCompile(`\s*productType = (?P.*);`) - - scanner := bufio.NewScanner(strings.NewReader(pbxprojContent)) - for scanner.Scan() { - line := scanner.Text() - - if strings.TrimSpace(line) == endPBXNativeTargetSectionPattern { - break - } - - if strings.TrimSpace(line) == beginPBXNativeTargetSectionPattern { - isPBXNativeTargetSection = true - continue - } - - if !isPBXNativeTargetSection { - continue - } - - // PBXNativeTarget section - - if strings.TrimSpace(line) == endPBXNativeTargetPattern { - pbxNativeTarget := PBXNativeTarget{ - id: id, - isa: isa, - dependencies: dependencies, - name: name, - productPath: productPath, - productType: productType, - } - pbxNativeTargets = append(pbxNativeTargets, pbxNativeTarget) - - id = "" - isa = "" - name = "" - productPath = "" - productType = "" - dependencies = []string{} - - isPBXNativeTarget = false - continue - } - - if matches := beginPBXNativeTargetRegexp.FindStringSubmatch(line); len(matches) == 3 { - id = matches[1] - name = matches[2] - - isPBXNativeTarget = true - continue - } - - if !isPBXNativeTarget { - continue - } - - // PBXNativeTarget item - - if matches := isaRegexp.FindStringSubmatch(line); len(matches) == 2 { - isa = strings.Trim(matches[1], `"`) - } - - if matches := nameRegexp.FindStringSubmatch(line); len(matches) == 2 { - name = strings.Trim(matches[1], `"`) - } - - if matches := productTypeRegexp.FindStringSubmatch(line); len(matches) == 2 { - productType = strings.Trim(matches[1], `"`) - } - - if matches := productReferenceRegexp.FindStringSubmatch(line); len(matches) == 3 { - // productId := strings.Trim(matches[1], `"`) - productPath = strings.Trim(matches[2], `"`) - } - - if isDependencies && strings.TrimSpace(line) == endDependenciesPattern { - isDependencies = false - continue - } - - if strings.TrimSpace(line) == beginDependenciesPattern { - isDependencies = true - continue - } - - if !isDependencies { - continue - } - - // dependencies - if matches := dependencieRegexp.FindStringSubmatch(line); len(matches) == 3 { - dependencieID := strings.Trim(matches[1], `"`) - dependencieIsa := strings.Trim(matches[2], `"`) - - if dependencieIsa == "PBXTargetDependency" { - dependencies = append(dependencies, dependencieID) - } - } - } - - if err := scanner.Err(); err != nil { - return []PBXNativeTarget{}, err - } - - return pbxNativeTargets, nil -} - -func parsePBXTargetDependencies(pbxprojContent string) ([]PBXTargetDependency, error) { - pbxTargetDependencies := []PBXTargetDependency{} - - id := "" - isa := "" - target := "" - - beginPBXTargetDependencySectionPattern := `/* Begin PBXTargetDependency section */` - endPBXTargetDependencySectionPattern := `/* End PBXTargetDependency section */` - isPBXTargetDependencySection := false - - // BAAFFEEF19EE788800F3AC91 /* PBXTargetDependency */ = { - beginPBXTargetDependencyRegexp := regexp.MustCompile(`\s*(?P[A-Z0-9]+) /\* (?P.*) \*/ = {`) - endPBXTargetDependencyPattern := `};` - isPBXTargetDependency := false - - // isa = PBXTargetDependency; - isaRegexp := regexp.MustCompile(`\s*isa = (?P.*);`) - // target = BAAFFED019EE788800F3AC91 /* SampleAppWithCocoapods */; - targetRegexp := regexp.MustCompile(`\s*target = (?P[A-Z0-9]+) /\* (?P.*) \*/;`) - - scanner := bufio.NewScanner(strings.NewReader(pbxprojContent)) - for scanner.Scan() { - line := scanner.Text() - - if strings.TrimSpace(line) == endPBXTargetDependencySectionPattern { - break - } - - if strings.TrimSpace(line) == beginPBXTargetDependencySectionPattern { - isPBXTargetDependencySection = true - continue - } - - if !isPBXTargetDependencySection { - continue - } - - // PBXTargetDependency section - - if strings.TrimSpace(line) == endPBXTargetDependencyPattern { - pbxTargetDependency := PBXTargetDependency{ - id: id, - isa: isa, - target: target, - } - pbxTargetDependencies = append(pbxTargetDependencies, pbxTargetDependency) - - id = "" - isa = "" - target = "" - - isPBXTargetDependency = false - continue - } - - if matches := beginPBXTargetDependencyRegexp.FindStringSubmatch(line); len(matches) == 3 { - id = matches[1] - isa = matches[2] - - isPBXTargetDependency = true - continue - } - - if !isPBXTargetDependency { - continue - } - - // PBXTargetDependency item - - if matches := isaRegexp.FindStringSubmatch(line); len(matches) == 2 { - isa = strings.Trim(matches[1], `"`) - } - - if matches := targetRegexp.FindStringSubmatch(line); len(matches) == 3 { - targetID := strings.Trim(matches[1], `"`) - // targetName := strings.Trim(matches[2], `"`) - - target = targetID - } - } - - return pbxTargetDependencies, nil -} - -func targetDependencieWithID(dependencies []PBXTargetDependency, id string) (PBXTargetDependency, bool) { - for _, dependencie := range dependencies { - if dependencie.id == id { - return dependencie, true - } - } - return PBXTargetDependency{}, false -} - -func targetWithID(targets []PBXNativeTarget, id string) (PBXNativeTarget, bool) { - for _, target := range targets { - if target.id == id { - return target, true - } - } - return PBXNativeTarget{}, false -} - -func pbxprojContentTartgets(pbxprojContent string) ([]TargetModel, error) { - targetMap := map[string]TargetModel{} - - nativeTargets, err := parsePBXNativeTargets(pbxprojContent) - if err != nil { - return []TargetModel{}, err - } - - targetDependencies, err := parsePBXTargetDependencies(pbxprojContent) - if err != nil { - return []TargetModel{}, err - } - - // Add targets which has test targets - for _, target := range nativeTargets { - if path.Ext(target.productPath) == ".xctest" { - if len(target.dependencies) > 0 { - for _, dependencieID := range target.dependencies { - dependency, found := targetDependencieWithID(targetDependencies, dependencieID) - if found { - dependentTarget, found := targetWithID(nativeTargets, dependency.target) - if found { - targetMap[dependentTarget.name] = TargetModel{ - Name: dependentTarget.name, - HasXCTest: true, - } - } - } - } - } - } - } - - // Add targets which has NO test targets - for _, target := range nativeTargets { - if path.Ext(target.productPath) != ".xctest" { - _, found := targetMap[target.name] - if !found { - targetMap[target.name] = TargetModel{ - Name: target.name, - HasXCTest: false, - } - } - } - } - - targets := []TargetModel{} - for _, target := range targetMap { - targets = append(targets, target) - } - - return targets, nil -} - -// ProjectTargets ... -func ProjectTargets(projectPth string) ([]TargetModel, error) { - pbxProjPth := filepath.Join(projectPth, "project.pbxproj") - if exist, err := pathutil.IsPathExists(pbxProjPth); err != nil { - return []TargetModel{}, err - } else if !exist { - return []TargetModel{}, fmt.Errorf("project.pbxproj does not exist at: %s", pbxProjPth) - } - - content, err := fileutil.ReadStringFromFile(pbxProjPth) - if err != nil { - return []TargetModel{}, err - } - - return pbxprojContentTartgets(content) -} - -// WorkspaceTargets ... -func WorkspaceTargets(workspacePth string) ([]TargetModel, error) { - projects, err := WorkspaceProjectReferences(workspacePth) - if err != nil { - return []TargetModel{}, err - } - - targets := []TargetModel{} - for _, project := range projects { - projectTargets, err := ProjectTargets(project) - if err != nil { - return []TargetModel{}, err - } - - targets = append(targets, projectTargets...) - } - - return targets, nil -} diff --git a/vendor/github.com/bitrise-tools/go-xcode/xcpretty/xcpretty.go b/vendor/github.com/bitrise-tools/go-xcode/xcpretty/xcpretty.go deleted file mode 100644 index 360d8d14..00000000 --- a/vendor/github.com/bitrise-tools/go-xcode/xcpretty/xcpretty.go +++ /dev/null @@ -1,106 +0,0 @@ -package xcpretty - -import ( - "bytes" - "fmt" - "io" - "os" - - "github.com/bitrise-io/go-utils/command" - "github.com/bitrise-io/go-utils/log" - "github.com/bitrise-tools/go-xcode/xcodebuild" -) - -const ( - toolName = "xcpretty" -) - -// CommandModel ... -type CommandModel struct { - xcodebuildCommand xcodebuild.CommandModel - - customOptions []string -} - -// New ... -func New(xcodebuildCommand xcodebuild.CommandModel) *CommandModel { - return &CommandModel{ - xcodebuildCommand: xcodebuildCommand, - } -} - -// SetCustomOptions ... -func (c *CommandModel) SetCustomOptions(customOptions []string) *CommandModel { - c.customOptions = customOptions - return c -} - -func (c CommandModel) cmdSlice() []string { - slice := []string{toolName} - slice = append(slice, c.customOptions...) - return slice -} - -// Command ... -func (c CommandModel) Command() *command.Model { - cmdSlice := c.cmdSlice() - return command.New(cmdSlice[0]) -} - -// PrintableCmd ... -func (c CommandModel) PrintableCmd() string { - prettyCmdSlice := c.cmdSlice() - prettyCmdStr := command.PrintableCommandArgs(false, prettyCmdSlice) - - cmdStr := c.xcodebuildCommand.PrintableCmd() - - return fmt.Sprintf("set -o pipefail && %s | %s", cmdStr, prettyCmdStr) -} - -// Run ... -func (c CommandModel) Run() (string, error) { - prettyCmd := c.Command() - xcodebuildCmd := c.xcodebuildCommand.Command() - - // Configure cmd in- and outputs - pipeReader, pipeWriter := io.Pipe() - - var outBuffer bytes.Buffer - outWriter := io.MultiWriter(&outBuffer, pipeWriter) - - xcodebuildCmd.SetStdin(nil) - xcodebuildCmd.SetStdout(outWriter) - xcodebuildCmd.SetStderr(outWriter) - - prettyCmd.SetStdin(pipeReader) - prettyCmd.SetStdout(os.Stdout) - prettyCmd.SetStderr(os.Stdout) - - // Run - if err := xcodebuildCmd.GetCmd().Start(); err != nil { - out := outBuffer.String() - return out, err - } - if err := prettyCmd.GetCmd().Start(); err != nil { - out := outBuffer.String() - return out, err - } - - // Always close xcpretty outputs - defer func() { - if err := pipeWriter.Close(); err != nil { - log.Warnf("Failed to close xcodebuild-xcpretty pipe, error: %s", err) - } - - if err := prettyCmd.GetCmd().Wait(); err != nil { - log.Warnf("xcpretty command failed, error: %s", err) - } - }() - - if err := xcodebuildCmd.GetCmd().Wait(); err != nil { - out := outBuffer.String() - return out, err - } - - return outBuffer.String(), nil -} diff --git a/vendor/github.com/fullsailor/pkcs7/.travis.yml b/vendor/github.com/fullsailor/pkcs7/.travis.yml index c7154e46..bc120437 100644 --- a/vendor/github.com/fullsailor/pkcs7/.travis.yml +++ b/vendor/github.com/fullsailor/pkcs7/.travis.yml @@ -1,6 +1,7 @@ language: go go: - - 1.6 - - 1.7 + - 1.8 + - 1.9 + - "1.10" - tip diff --git a/vendor/github.com/fullsailor/pkcs7/ber.go b/vendor/github.com/fullsailor/pkcs7/ber.go index bf3e8042..89e96d30 100644 --- a/vendor/github.com/fullsailor/pkcs7/ber.go +++ b/vendor/github.com/fullsailor/pkcs7/ber.go @@ -5,7 +5,7 @@ import ( "errors" ) -var encodeIndent = 0 +// var encodeIndent = 0 type asn1Object interface { EncodeTo(writer *bytes.Buffer) error @@ -18,7 +18,7 @@ type asn1Structured struct { func (s asn1Structured) EncodeTo(out *bytes.Buffer) error { //fmt.Printf("%s--> tag: % X\n", strings.Repeat("| ", encodeIndent), s.tagBytes) - encodeIndent++ + //encodeIndent++ inner := new(bytes.Buffer) for _, obj := range s.content { err := obj.EncodeTo(inner) @@ -26,7 +26,7 @@ func (s asn1Structured) EncodeTo(out *bytes.Buffer) error { return err } } - encodeIndent-- + //encodeIndent-- out.Write(s.tagBytes) encodeLength(out, inner.Len()) out.Write(inner.Bytes()) diff --git a/vendor/github.com/fullsailor/pkcs7/ber_test.go b/vendor/github.com/fullsailor/pkcs7/ber_test.go deleted file mode 100644 index 19a0f514..00000000 --- a/vendor/github.com/fullsailor/pkcs7/ber_test.go +++ /dev/null @@ -1,97 +0,0 @@ -package pkcs7 - -import ( - "bytes" - "encoding/asn1" - "strings" - "testing" -) - -func TestBer2Der(t *testing.T) { - // indefinite length fixture - ber := []byte{0x30, 0x80, 0x02, 0x01, 0x01, 0x00, 0x00} - expected := []byte{0x30, 0x03, 0x02, 0x01, 0x01} - der, err := ber2der(ber) - if err != nil { - t.Fatalf("ber2der failed with error: %v", err) - } - if bytes.Compare(der, expected) != 0 { - t.Errorf("ber2der result did not match.\n\tExpected: % X\n\tActual: % X", expected, der) - } - - if der2, err := ber2der(der); err != nil { - t.Errorf("ber2der on DER bytes failed with error: %v", err) - } else { - if !bytes.Equal(der, der2) { - t.Error("ber2der is not idempotent") - } - } - var thing struct { - Number int - } - rest, err := asn1.Unmarshal(der, &thing) - if err != nil { - t.Errorf("Cannot parse resulting DER because: %v", err) - } else if len(rest) > 0 { - t.Errorf("Resulting DER has trailing data: % X", rest) - } -} - -func TestBer2Der_Negatives(t *testing.T) { - fixtures := []struct { - Input []byte - ErrorContains string - }{ - {[]byte{0x30, 0x85}, "length too long"}, - {[]byte{0x30, 0x84, 0x80, 0x0, 0x0, 0x0}, "length is negative"}, - {[]byte{0x30, 0x82, 0x0, 0x1}, "length has leading zero"}, - {[]byte{0x30, 0x80, 0x1, 0x2, 0x1, 0x2}, "Invalid BER format"}, - {[]byte{0x30, 0x03, 0x01, 0x02}, "length is more than available data"}, - } - - for _, fixture := range fixtures { - _, err := ber2der(fixture.Input) - if err == nil { - t.Errorf("No error thrown. Expected: %s", fixture.ErrorContains) - } - if !strings.Contains(err.Error(), fixture.ErrorContains) { - t.Errorf("Unexpected error thrown.\n\tExpected: /%s/\n\tActual: %s", fixture.ErrorContains, err.Error()) - } - } -} - -func TestBer2Der_NestedMultipleIndefinite(t *testing.T) { - // indefinite length fixture - ber := []byte{0x30, 0x80, 0x30, 0x80, 0x02, 0x01, 0x01, 0x00, 0x00, 0x30, 0x80, 0x02, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00} - expected := []byte{0x30, 0x0A, 0x30, 0x03, 0x02, 0x01, 0x01, 0x30, 0x03, 0x02, 0x01, 0x02} - - der, err := ber2der(ber) - if err != nil { - t.Fatalf("ber2der failed with error: %v", err) - } - if bytes.Compare(der, expected) != 0 { - t.Errorf("ber2der result did not match.\n\tExpected: % X\n\tActual: % X", expected, der) - } - - if der2, err := ber2der(der); err != nil { - t.Errorf("ber2der on DER bytes failed with error: %v", err) - } else { - if !bytes.Equal(der, der2) { - t.Error("ber2der is not idempotent") - } - } - var thing struct { - Nest1 struct { - Number int - } - Nest2 struct { - Number int - } - } - rest, err := asn1.Unmarshal(der, &thing) - if err != nil { - t.Errorf("Cannot parse resulting DER because: %v", err) - } else if len(rest) > 0 { - t.Errorf("Resulting DER has trailing data: % X", rest) - } -} diff --git a/vendor/github.com/fullsailor/pkcs7/pkcs7.go b/vendor/github.com/fullsailor/pkcs7/pkcs7.go index 8d5af853..0264466b 100644 --- a/vendor/github.com/fullsailor/pkcs7/pkcs7.go +++ b/vendor/github.com/fullsailor/pkcs7/pkcs7.go @@ -84,7 +84,7 @@ type recipientInfo struct { type encryptedContentInfo struct { ContentType asn1.ObjectIdentifier ContentEncryptionAlgorithm pkix.AlgorithmIdentifier - EncryptedContent asn1.RawValue `asn1:"tag:0,optional,explicit"` + EncryptedContent asn1.RawValue `asn1:"tag:0,optional"` } type attribute struct { @@ -222,6 +222,10 @@ func (p7 *PKCS7) Verify() (err error) { func verifySignature(p7 *PKCS7, signer signerInfo) error { signedData := p7.Content + hash, err := getHashForOID(signer.DigestAlgorithm.Algorithm) + if err != nil { + return err + } if len(signer.AuthenticatedAttributes) > 0 { // TODO(fullsailor): First check the content type match var digest []byte @@ -229,10 +233,6 @@ func verifySignature(p7 *PKCS7, signer signerInfo) error { if err != nil { return err } - hash, err := getHashForOID(signer.DigestAlgorithm.Algorithm) - if err != nil { - return err - } h := hash.New() h.Write(p7.Content) computed := h.Sum(nil) @@ -254,7 +254,18 @@ func verifySignature(p7 *PKCS7, signer signerInfo) error { return errors.New("pkcs7: No certificate for signer") } - algo := x509.SHA1WithRSA + algo := getSignatureAlgorithmFromAI(signer.DigestEncryptionAlgorithm) + if algo == x509.UnknownSignatureAlgorithm { + // I'm not sure what the spec here is, and the openssl sources were not + // helpful. But, this is what App Store receipts appear to do. + // The DigestEncryptionAlgorithm is just "rsaEncryption (PKCS #1)" + // But we're expecting a digest + encryption algorithm. So... we're going + // to determine an algorithm based on the DigestAlgorithm and this + // encryption algorithm. + if signer.DigestEncryptionAlgorithm.Algorithm.Equal(oidEncryptionAlgorithmRSA) { + algo = getRSASignatureAlgorithmForDigestAlgorithm(hash) + } + } return cert.CheckSignature(algo, signedData, signer.EncryptedDigest) } @@ -290,10 +301,21 @@ func getHashForOID(oid asn1.ObjectIdentifier) (crypto.Hash, error) { switch { case oid.Equal(oidDigestAlgorithmSHA1): return crypto.SHA1, nil + case oid.Equal(oidSHA256): + return crypto.SHA256, nil } return crypto.Hash(0), ErrUnsupportedAlgorithm } +func getRSASignatureAlgorithmForDigestAlgorithm(hash crypto.Hash) x509.SignatureAlgorithm { + for _, details := range signatureAlgorithmDetails { + if details.pubKeyAlgo == x509.RSA && details.hash == hash { + return details.algo + } + } + return x509.UnknownSignatureAlgorithm +} + // GetOnlySigner returns an x509.Certificate for the first signer of the signed // data payload. If there are more or less than one signer, nil is returned func (p7 *PKCS7) GetOnlySigner() *x509.Certificate { @@ -633,7 +655,7 @@ func (sd *SignedData) AddSigner(cert *x509.Certificate, pkey crypto.PrivateKey, signer := signerInfo{ AuthenticatedAttributes: finalAttrs, DigestAlgorithm: pkix.AlgorithmIdentifier{Algorithm: oidDigestAlgorithmSHA1}, - DigestEncryptionAlgorithm: pkix.AlgorithmIdentifier{Algorithm: oidEncryptionAlgorithmRSA}, + DigestEncryptionAlgorithm: pkix.AlgorithmIdentifier{Algorithm: oidSignatureSHA1WithRSA}, IssuerAndSerialNumber: ias, EncryptedDigest: signature, Version: 1, @@ -652,7 +674,7 @@ func (sd *SignedData) AddCertificate(cert *x509.Certificate) { // Detach removes content from the signed data struct to make it a detached signature. // This must be called right before Finish() func (sd *SignedData) Detach() { - sd.sd.ContentInfo = contentInfo{ContentType: oidSignedData} + sd.sd.ContentInfo = contentInfo{ContentType: oidData} } // Finish marshals the content and its signers diff --git a/vendor/github.com/fullsailor/pkcs7/pkcs7_test.go b/vendor/github.com/fullsailor/pkcs7/pkcs7_test.go deleted file mode 100644 index cbe2c5ca..00000000 --- a/vendor/github.com/fullsailor/pkcs7/pkcs7_test.go +++ /dev/null @@ -1,678 +0,0 @@ -package pkcs7 - -import ( - "bytes" - "crypto" - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "crypto/x509/pkix" - "encoding/asn1" - "encoding/pem" - "fmt" - "io" - "io/ioutil" - "math/big" - "os" - "os/exec" - "testing" - "time" -) - -func TestVerify(t *testing.T) { - fixture := UnmarshalTestFixture(SignedTestFixture) - p7, err := Parse(fixture.Input) - if err != nil { - t.Errorf("Parse encountered unexpected error: %v", err) - } - - if err := p7.Verify(); err != nil { - t.Errorf("Verify failed with error: %v", err) - } - expected := []byte("We the People") - if bytes.Compare(p7.Content, expected) != 0 { - t.Errorf("Signed content does not match.\n\tExpected:%s\n\tActual:%s", expected, p7.Content) - - } -} - -func TestVerifyEC2(t *testing.T) { - fixture := UnmarshalTestFixture(EC2IdentityDocumentFixture) - p7, err := Parse(fixture.Input) - if err != nil { - t.Errorf("Parse encountered unexpected error: %v", err) - } - p7.Certificates = []*x509.Certificate{fixture.Certificate} - if err := p7.Verify(); err != nil { - t.Errorf("Verify failed with error: %v", err) - } -} - -func TestVerifyAppStore(t *testing.T) { - fixture := UnmarshalTestFixture(AppStoreRecieptFixture) - p7, err := Parse(fixture.Input) - if err != nil { - t.Errorf("Parse encountered unexpected error: %v", err) - } - if err := p7.Verify(); err != nil { - t.Errorf("Verify failed with error: %v", err) - } -} - -func TestDecrypt(t *testing.T) { - fixture := UnmarshalTestFixture(EncryptedTestFixture) - p7, err := Parse(fixture.Input) - if err != nil { - t.Fatal(err) - } - content, err := p7.Decrypt(fixture.Certificate, fixture.PrivateKey) - if err != nil { - t.Errorf("Cannot Decrypt with error: %v", err) - } - expected := []byte("This is a test") - if bytes.Compare(content, expected) != 0 { - t.Errorf("Decrypted result does not match.\n\tExpected:%s\n\tActual:%s", expected, content) - } -} - -func TestDegenerateCertificate(t *testing.T) { - cert, err := createTestCertificate() - if err != nil { - t.Fatal(err) - } - deg, err := DegenerateCertificate(cert.Certificate.Raw) - if err != nil { - t.Fatal(err) - } - testOpenSSLParse(t, deg) - pem.Encode(os.Stdout, &pem.Block{Type: "PKCS7", Bytes: deg}) -} - -// writes the cert to a temporary file and tests that openssl can read it. -func testOpenSSLParse(t *testing.T, certBytes []byte) { - tmpCertFile, err := ioutil.TempFile("", "testCertificate") - if err != nil { - t.Fatal(err) - } - defer os.Remove(tmpCertFile.Name()) // clean up - - if _, err := tmpCertFile.Write(certBytes); err != nil { - t.Fatal(err) - } - - opensslCMD := exec.Command("openssl", "pkcs7", "-inform", "der", "-in", tmpCertFile.Name()) - _, err = opensslCMD.Output() - if err != nil { - t.Fatal(err) - } - - if err := tmpCertFile.Close(); err != nil { - t.Fatal(err) - } - -} - -func TestSign(t *testing.T) { - cert, err := createTestCertificate() - if err != nil { - t.Fatal(err) - } - content := []byte("Hello World") - for _, testDetach := range []bool{false, true} { - toBeSigned, err := NewSignedData(content) - if err != nil { - t.Fatalf("Cannot initialize signed data: %s", err) - } - if err := toBeSigned.AddSigner(cert.Certificate, cert.PrivateKey, SignerInfoConfig{}); err != nil { - t.Fatalf("Cannot add signer: %s", err) - } - if testDetach { - t.Log("Testing detached signature") - toBeSigned.Detach() - } else { - t.Log("Testing attached signature") - } - signed, err := toBeSigned.Finish() - if err != nil { - t.Fatalf("Cannot finish signing data: %s", err) - } - pem.Encode(os.Stdout, &pem.Block{Type: "PKCS7", Bytes: signed}) - p7, err := Parse(signed) - if err != nil { - t.Fatalf("Cannot parse our signed data: %s", err) - } - if testDetach { - p7.Content = content - } - if bytes.Compare(content, p7.Content) != 0 { - t.Errorf("Our content was not in the parsed data:\n\tExpected: %s\n\tActual: %s", content, p7.Content) - } - if err := p7.Verify(); err != nil { - t.Errorf("Cannot verify our signed data: %s", err) - } - } -} - -func ExampleSignedData() { - // generate a signing cert or load a key pair - cert, err := createTestCertificate() - if err != nil { - fmt.Printf("Cannot create test certificates: %s", err) - } - - // Initialize a SignedData struct with content to be signed - signedData, err := NewSignedData([]byte("Example data to be signed")) - if err != nil { - fmt.Printf("Cannot initialize signed data: %s", err) - } - - // Add the signing cert and private key - if err := signedData.AddSigner(cert.Certificate, cert.PrivateKey, SignerInfoConfig{}); err != nil { - fmt.Printf("Cannot add signer: %s", err) - } - - // Call Detach() is you want to remove content from the signature - // and generate an S/MIME detached signature - signedData.Detach() - - // Finish() to obtain the signature bytes - detachedSignature, err := signedData.Finish() - if err != nil { - fmt.Printf("Cannot finish signing data: %s", err) - } - pem.Encode(os.Stdout, &pem.Block{Type: "PKCS7", Bytes: detachedSignature}) -} - -func TestOpenSSLVerifyDetachedSignature(t *testing.T) { - rootCert, err := createTestCertificateByIssuer("PKCS7 Test Root CA", nil) - if err != nil { - t.Fatalf("Cannot generate root cert: %s", err) - } - signerCert, err := createTestCertificateByIssuer("PKCS7 Test Signer Cert", rootCert) - if err != nil { - t.Fatalf("Cannot generate signer cert: %s", err) - } - content := []byte("Hello World") - toBeSigned, err := NewSignedData(content) - if err != nil { - t.Fatalf("Cannot initialize signed data: %s", err) - } - if err := toBeSigned.AddSigner(signerCert.Certificate, signerCert.PrivateKey, SignerInfoConfig{}); err != nil { - t.Fatalf("Cannot add signer: %s", err) - } - toBeSigned.Detach() - signed, err := toBeSigned.Finish() - if err != nil { - t.Fatalf("Cannot finish signing data: %s", err) - } - - // write the root cert to a temp file - tmpRootCertFile, err := ioutil.TempFile("", "pkcs7TestRootCA") - if err != nil { - t.Fatal(err) - } - defer os.Remove(tmpRootCertFile.Name()) // clean up - fd, err := os.OpenFile(tmpRootCertFile.Name(), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755) - if err != nil { - t.Fatal(err) - } - pem.Encode(fd, &pem.Block{Type: "CERTIFICATE", Bytes: rootCert.Certificate.Raw}) - fd.Close() - - // write the signature to a temp file - tmpSignatureFile, err := ioutil.TempFile("", "pkcs7Signature") - if err != nil { - t.Fatal(err) - } - defer os.Remove(tmpSignatureFile.Name()) // clean up - ioutil.WriteFile(tmpSignatureFile.Name(), signed, 0755) - - // write the content to a temp file - tmpContentFile, err := ioutil.TempFile("", "pkcs7Content") - if err != nil { - t.Fatal(err) - } - defer os.Remove(tmpContentFile.Name()) // clean up - ioutil.WriteFile(tmpContentFile.Name(), content, 0755) - - // call openssl to verify the signature on the content using the root - opensslCMD := exec.Command("openssl", "smime", "-verify", - "-in", tmpSignatureFile.Name(), "-inform", "DER", - "-content", tmpContentFile.Name(), - "-CAfile", tmpRootCertFile.Name()) - out, err := opensslCMD.Output() - t.Logf("%s", out) - if err != nil { - t.Fatalf("openssl command failed with %s", err) - } -} - -func TestEncrypt(t *testing.T) { - modes := []int{ - EncryptionAlgorithmDESCBC, - EncryptionAlgorithmAES128GCM, - } - - for _, mode := range modes { - ContentEncryptionAlgorithm = mode - - plaintext := []byte("Hello Secret World!") - cert, err := createTestCertificate() - if err != nil { - t.Fatal(err) - } - encrypted, err := Encrypt(plaintext, []*x509.Certificate{cert.Certificate}) - if err != nil { - t.Fatal(err) - } - p7, err := Parse(encrypted) - if err != nil { - t.Fatalf("cannot Parse encrypted result: %s", err) - } - result, err := p7.Decrypt(cert.Certificate, cert.PrivateKey) - if err != nil { - t.Fatalf("cannot Decrypt encrypted result: %s", err) - } - if bytes.Compare(plaintext, result) != 0 { - t.Errorf("encrypted data does not match plaintext:\n\tExpected: %s\n\tActual: %s", plaintext, result) - } - } -} - -func TestUnmarshalSignedAttribute(t *testing.T) { - cert, err := createTestCertificate() - if err != nil { - t.Fatal(err) - } - content := []byte("Hello World") - toBeSigned, err := NewSignedData(content) - if err != nil { - t.Fatalf("Cannot initialize signed data: %s", err) - } - oidTest := asn1.ObjectIdentifier{2, 3, 4, 5, 6, 7} - testValue := "TestValue" - if err := toBeSigned.AddSigner(cert.Certificate, cert.PrivateKey, SignerInfoConfig{ - ExtraSignedAttributes: []Attribute{Attribute{Type: oidTest, Value: testValue}}, - }); err != nil { - t.Fatalf("Cannot add signer: %s", err) - } - signed, err := toBeSigned.Finish() - if err != nil { - t.Fatalf("Cannot finish signing data: %s", err) - } - p7, err := Parse(signed) - var actual string - err = p7.UnmarshalSignedAttribute(oidTest, &actual) - if err != nil { - t.Fatalf("Cannot unmarshal test value: %s", err) - } - if testValue != actual { - t.Errorf("Attribute does not match test value\n\tExpected: %s\n\tActual: %s", testValue, actual) - } -} - -func TestPad(t *testing.T) { - tests := []struct { - Original []byte - Expected []byte - BlockSize int - }{ - {[]byte{0x1, 0x2, 0x3, 0x10}, []byte{0x1, 0x2, 0x3, 0x10, 0x4, 0x4, 0x4, 0x4}, 8}, - {[]byte{0x1, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0}, []byte{0x1, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8}, 8}, - } - for _, test := range tests { - padded, err := pad(test.Original, test.BlockSize) - if err != nil { - t.Errorf("pad encountered error: %s", err) - continue - } - if bytes.Compare(test.Expected, padded) != 0 { - t.Errorf("pad results mismatch:\n\tExpected: %X\n\tActual: %X", test.Expected, padded) - } - } -} - -type certKeyPair struct { - Certificate *x509.Certificate - PrivateKey *rsa.PrivateKey -} - -func createTestCertificate() (certKeyPair, error) { - signer, err := createTestCertificateByIssuer("Eddard Stark", nil) - if err != nil { - return certKeyPair{}, err - } - fmt.Println("Created root cert") - pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: signer.Certificate.Raw}) - pair, err := createTestCertificateByIssuer("Jon Snow", signer) - if err != nil { - return certKeyPair{}, err - } - fmt.Println("Created signer cert") - pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: pair.Certificate.Raw}) - return *pair, nil -} - -func createTestCertificateByIssuer(name string, issuer *certKeyPair) (*certKeyPair, error) { - priv, err := rsa.GenerateKey(rand.Reader, 1024) - if err != nil { - return nil, err - } - serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 32) - serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) - if err != nil { - return nil, err - } - - template := x509.Certificate{ - SerialNumber: serialNumber, - SignatureAlgorithm: x509.SHA256WithRSA, - Subject: pkix.Name{ - CommonName: name, - Organization: []string{"Acme Co"}, - }, - NotBefore: time.Now(), - NotAfter: time.Now().AddDate(1, 0, 0), - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageEmailProtection}, - } - var issuerCert *x509.Certificate - var issuerKey crypto.PrivateKey - if issuer != nil { - issuerCert = issuer.Certificate - issuerKey = issuer.PrivateKey - } else { - template.IsCA = true - template.KeyUsage |= x509.KeyUsageCertSign - issuerCert = &template - issuerKey = priv - } - cert, err := x509.CreateCertificate(rand.Reader, &template, issuerCert, priv.Public(), issuerKey) - if err != nil { - return nil, err - } - leaf, err := x509.ParseCertificate(cert) - if err != nil { - return nil, err - } - return &certKeyPair{ - Certificate: leaf, - PrivateKey: priv, - }, nil -} - -type TestFixture struct { - Input []byte - Certificate *x509.Certificate - PrivateKey *rsa.PrivateKey -} - -func UnmarshalTestFixture(testPEMBlock string) TestFixture { - var result TestFixture - var derBlock *pem.Block - var pemBlock = []byte(testPEMBlock) - for { - derBlock, pemBlock = pem.Decode(pemBlock) - if derBlock == nil { - break - } - switch derBlock.Type { - case "PKCS7": - result.Input = derBlock.Bytes - case "CERTIFICATE": - result.Certificate, _ = x509.ParseCertificate(derBlock.Bytes) - case "PRIVATE KEY": - result.PrivateKey, _ = x509.ParsePKCS1PrivateKey(derBlock.Bytes) - } - } - - return result -} - -func MarshalTestFixture(t TestFixture, w io.Writer) { - if t.Input != nil { - pem.Encode(w, &pem.Block{Type: "PKCS7", Bytes: t.Input}) - } - if t.Certificate != nil { - pem.Encode(w, &pem.Block{Type: "CERTIFICATE", Bytes: t.Certificate.Raw}) - } - if t.PrivateKey != nil { - pem.Encode(w, &pem.Block{Type: "PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(t.PrivateKey)}) - } -} - -var SignedTestFixture = ` ------BEGIN PKCS7----- -MIIDVgYJKoZIhvcNAQcCoIIDRzCCA0MCAQExCTAHBgUrDgMCGjAcBgkqhkiG9w0B -BwGgDwQNV2UgdGhlIFBlb3BsZaCCAdkwggHVMIIBQKADAgECAgRpuDctMAsGCSqG -SIb3DQEBCzApMRAwDgYDVQQKEwdBY21lIENvMRUwEwYDVQQDEwxFZGRhcmQgU3Rh -cmswHhcNMTUwNTA2MDQyNDQ4WhcNMTYwNTA2MDQyNDQ4WjAlMRAwDgYDVQQKEwdB -Y21lIENvMREwDwYDVQQDEwhKb24gU25vdzCBnzANBgkqhkiG9w0BAQEFAAOBjQAw -gYkCgYEAqr+tTF4mZP5rMwlXp1y+crRtFpuLXF1zvBZiYMfIvAHwo1ta8E1IcyEP -J1jIiKMcwbzeo6kAmZzIJRCTezq9jwXUsKbQTvcfOH9HmjUmXBRWFXZYoQs/OaaF -a45deHmwEeMQkuSWEtYiVKKZXtJOtflKIT3MryJEDiiItMkdybUCAwEAAaMSMBAw -DgYDVR0PAQH/BAQDAgCgMAsGCSqGSIb3DQEBCwOBgQDK1EweZWRL+f7Z+J0kVzY8 -zXptcBaV4Lf5wGZJLJVUgp33bpLNpT3yadS++XQJ+cvtW3wADQzBSTMduyOF8Zf+ -L7TjjrQ2+F2HbNbKUhBQKudxTfv9dJHdKbD+ngCCdQJYkIy2YexsoNG0C8nQkggy -axZd/J69xDVx6pui3Sj8sDGCATYwggEyAgEBMDEwKTEQMA4GA1UEChMHQWNtZSBD -bzEVMBMGA1UEAxMMRWRkYXJkIFN0YXJrAgRpuDctMAcGBSsOAwIaoGEwGAYJKoZI -hvcNAQkDMQsGCSqGSIb3DQEHATAgBgkqhkiG9w0BCQUxExcRMTUwNTA2MDAyNDQ4 -LTA0MDAwIwYJKoZIhvcNAQkEMRYEFG9D7gcTh9zfKiYNJ1lgB0yTh4sZMAsGCSqG -SIb3DQEBAQSBgFF3sGDU9PtXty/QMtpcFa35vvIOqmWQAIZt93XAskQOnBq4OloX -iL9Ct7t1m4pzjRm0o9nDkbaSLZe7HKASHdCqijroScGlI8M+alJ8drHSFv6ZIjnM -FIwIf0B2Lko6nh9/6mUXq7tbbIHa3Gd1JUVire/QFFtmgRXMbXYk8SIS ------END PKCS7----- ------BEGIN CERTIFICATE----- -MIIB1TCCAUCgAwIBAgIEabg3LTALBgkqhkiG9w0BAQswKTEQMA4GA1UEChMHQWNt -ZSBDbzEVMBMGA1UEAxMMRWRkYXJkIFN0YXJrMB4XDTE1MDUwNjA0MjQ0OFoXDTE2 -MDUwNjA0MjQ0OFowJTEQMA4GA1UEChMHQWNtZSBDbzERMA8GA1UEAxMISm9uIFNu -b3cwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKq/rUxeJmT+azMJV6dcvnK0 -bRabi1xdc7wWYmDHyLwB8KNbWvBNSHMhDydYyIijHMG83qOpAJmcyCUQk3s6vY8F -1LCm0E73Hzh/R5o1JlwUVhV2WKELPzmmhWuOXXh5sBHjEJLklhLWIlSimV7STrX5 -SiE9zK8iRA4oiLTJHcm1AgMBAAGjEjAQMA4GA1UdDwEB/wQEAwIAoDALBgkqhkiG -9w0BAQsDgYEAytRMHmVkS/n+2fidJFc2PM16bXAWleC3+cBmSSyVVIKd926SzaU9 -8mnUvvl0CfnL7Vt8AA0MwUkzHbsjhfGX/i+04460Nvhdh2zWylIQUCrncU37/XSR -3Smw/p4AgnUCWJCMtmHsbKDRtAvJ0JIIMmsWXfyevcQ1ceqbot0o/LA= ------END CERTIFICATE----- ------BEGIN PRIVATE KEY----- -MIICXgIBAAKBgQCqv61MXiZk/mszCVenXL5ytG0Wm4tcXXO8FmJgx8i8AfCjW1rw -TUhzIQ8nWMiIoxzBvN6jqQCZnMglEJN7Or2PBdSwptBO9x84f0eaNSZcFFYVdlih -Cz85poVrjl14ebAR4xCS5JYS1iJUople0k61+UohPcyvIkQOKIi0yR3JtQIDAQAB -AoGBAIPLCR9N+IKxodq11lNXEaUFwMHXc1zqwP8no+2hpz3+nVfplqqubEJ4/PJY -5AgbJoIfnxVhyBXJXu7E+aD/OPneKZrgp58YvHKgGvvPyJg2gpC/1Fh0vQB0HNpI -1ZzIZUl8ZTUtVgtnCBUOh5JGI4bFokAqrT//Uvcfd+idgxqBAkEA1ZbP/Kseld14 -qbWmgmU5GCVxsZRxgR1j4lG3UVjH36KXMtRTm1atAam1uw3OEGa6Y3ANjpU52FaB -Hep5rkk4FQJBAMynMo1L1uiN5GP+KYLEF5kKRxK+FLjXR0ywnMh+gpGcZDcOae+J -+t1gLoWBIESH/Xt639T7smuSfrZSA9V0EyECQA8cvZiWDvLxmaEAXkipmtGPjKzQ -4PsOtkuEFqFl07aKDYKmLUg3aMROWrJidqsIabWxbvQgsNgSvs38EiH3wkUCQQCg -ndxb7piVXb9RBwm3OoU2tE1BlXMX+sVXmAkEhd2dwDsaxrI3sHf1xGXem5AimQRF -JBOFyaCnMotGNioSHY5hAkEAxyXcNixQ2RpLXJTQZtwnbk0XDcbgB+fBgXnv/4f3 -BCvcu85DqJeJyQv44Oe1qsXEX9BfcQIOVaoep35RPlKi9g== ------END PRIVATE KEY-----` - -// Content is "This is a test" -var EncryptedTestFixture = ` ------BEGIN PKCS7----- -MIIBFwYJKoZIhvcNAQcDoIIBCDCCAQQCAQAxgcowgccCAQAwMjApMRAwDgYDVQQK -EwdBY21lIENvMRUwEwYDVQQDEwxFZGRhcmQgU3RhcmsCBQDL+CvWMAsGCSqGSIb3 -DQEBAQSBgKyP/5WlRTZD3dWMrLOX6QRNDrXEkQjhmToRwFZdY3LgUh25ZU0S/q4G -dHPV21Fv9lQD+q7l3vfeHw8M6Z1PKi9sHMVfxAkQpvaI96DTIT3YHtuLC1w3geCO -8eFWTq2qS4WChSuS/yhYosjA1kTkE0eLnVZcGw0z/WVuEZznkdyIMDIGCSqGSIb3 -DQEHATARBgUrDgMCBwQImpKsUyMPpQigEgQQRcWWrCRXqpD5Njs0GkJl+g== ------END PKCS7----- ------BEGIN CERTIFICATE----- -MIIB1jCCAUGgAwIBAgIFAMv4K9YwCwYJKoZIhvcNAQELMCkxEDAOBgNVBAoTB0Fj -bWUgQ28xFTATBgNVBAMTDEVkZGFyZCBTdGFyazAeFw0xNTA1MDYwMzU2NDBaFw0x -NjA1MDYwMzU2NDBaMCUxEDAOBgNVBAoTB0FjbWUgQ28xETAPBgNVBAMTCEpvbiBT -bm93MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDK6NU0R0eiCYVquU4RcjKc -LzGfx0aa1lMr2TnLQUSeLFZHFxsyyMXXuMPig3HK4A7SGFHupO+/1H/sL4xpH5zg -8+Zg2r8xnnney7abxcuv0uATWSIeKlNnb1ZO1BAxFnESc3GtyOCr2dUwZHX5mRVP -+Zxp2ni5qHNraf3wE2VPIQIDAQABoxIwEDAOBgNVHQ8BAf8EBAMCAKAwCwYJKoZI -hvcNAQELA4GBAIr2F7wsqmEU/J/kLyrCgEVXgaV/sKZq4pPNnzS0tBYk8fkV3V18 -sBJyHKRLL/wFZASvzDcVGCplXyMdAOCyfd8jO3F9Ac/xdlz10RrHJT75hNu3a7/n -9KNwKhfN4A1CQv2x372oGjRhCW5bHNCWx4PIVeNzCyq/KZhyY9sxHE6f ------END CERTIFICATE----- ------BEGIN PRIVATE KEY----- -MIICXgIBAAKBgQDK6NU0R0eiCYVquU4RcjKcLzGfx0aa1lMr2TnLQUSeLFZHFxsy -yMXXuMPig3HK4A7SGFHupO+/1H/sL4xpH5zg8+Zg2r8xnnney7abxcuv0uATWSIe -KlNnb1ZO1BAxFnESc3GtyOCr2dUwZHX5mRVP+Zxp2ni5qHNraf3wE2VPIQIDAQAB -AoGBALyvnSt7KUquDen7nXQtvJBudnf9KFPt//OjkdHHxNZNpoF/JCSqfQeoYkeu -MdAVYNLQGMiRifzZz4dDhA9xfUAuy7lcGQcMCxEQ1dwwuFaYkawbS0Tvy2PFlq2d -H5/HeDXU4EDJ3BZg0eYj2Bnkt1sJI35UKQSxblQ0MY2q0uFBAkEA5MMOogkgUx1C -67S1tFqMUSM8D0mZB0O5vOJZC5Gtt2Urju6vywge2ArExWRXlM2qGl8afFy2SgSv -Xk5eybcEiQJBAOMRwwbEoW5NYHuFFbSJyWll4n71CYuWuQOCzehDPyTb80WFZGLV -i91kFIjeERyq88eDE5xVB3ZuRiXqaShO/9kCQQCKOEkpInaDgZSjskZvuJ47kByD -6CYsO4GIXQMMeHML8ncFH7bb6AYq5ybJVb2NTU7QLFJmfeYuhvIm+xdOreRxAkEA -o5FC5Jg2FUfFzZSDmyZ6IONUsdF/i78KDV5nRv1R+hI6/oRlWNCtTNBv/lvBBd6b -dseUE9QoaQZsn5lpILEvmQJAZ0B+Or1rAYjnbjnUhdVZoy9kC4Zov+4UH3N/BtSy -KJRWUR0wTWfZBPZ5hAYZjTBEAFULaYCXlQKsODSp0M1aQA== ------END PRIVATE KEY-----` - -var EC2IdentityDocumentFixture = ` ------BEGIN PKCS7----- -MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAaCA -JIAEggGmewogICJwcml2YXRlSXAiIDogIjE3Mi4zMC4wLjI1MiIsCiAgImRldnBh -eVByb2R1Y3RDb2RlcyIgOiBudWxsLAogICJhdmFpbGFiaWxpdHlab25lIiA6ICJ1 -cy1lYXN0LTFhIiwKICAidmVyc2lvbiIgOiAiMjAxMC0wOC0zMSIsCiAgImluc3Rh -bmNlSWQiIDogImktZjc5ZmU1NmMiLAogICJiaWxsaW5nUHJvZHVjdHMiIDogbnVs -bCwKICAiaW5zdGFuY2VUeXBlIiA6ICJ0Mi5taWNybyIsCiAgImFjY291bnRJZCIg -OiAiMTIxNjU5MDE0MzM0IiwKICAiaW1hZ2VJZCIgOiAiYW1pLWZjZTNjNjk2IiwK -ICAicGVuZGluZ1RpbWUiIDogIjIwMTYtMDQtMDhUMDM6MDE6MzhaIiwKICAiYXJj -aGl0ZWN0dXJlIiA6ICJ4ODZfNjQiLAogICJrZXJuZWxJZCIgOiBudWxsLAogICJy -YW1kaXNrSWQiIDogbnVsbCwKICAicmVnaW9uIiA6ICJ1cy1lYXN0LTEiCn0AAAAA -AAAxggEYMIIBFAIBATBpMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5n -dG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2Vi -IFNlcnZpY2VzIExMQwIJAJa6SNnlXhpnMAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0B -CQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0xNjA0MDgwMzAxNDRaMCMG -CSqGSIb3DQEJBDEWBBTuUc28eBXmImAautC+wOjqcFCBVjAJBgcqhkjOOAQDBC8w -LQIVAKA54NxGHWWCz5InboDmY/GHs33nAhQ6O/ZI86NwjA9Vz3RNMUJrUPU5tAAA -AAAAAA== ------END PKCS7----- ------BEGIN CERTIFICATE----- -MIIC7TCCAq0CCQCWukjZ5V4aZzAJBgcqhkjOOAQDMFwxCzAJBgNVBAYTAlVTMRkw -FwYDVQQIExBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYD -VQQKExdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAeFw0xMjAxMDUxMjU2MTJaFw0z -ODAxMDUxMjU2MTJaMFwxCzAJBgNVBAYTAlVTMRkwFwYDVQQIExBXYXNoaW5ndG9u -IFN0YXRlMRAwDgYDVQQHEwdTZWF0dGxlMSAwHgYDVQQKExdBbWF6b24gV2ViIFNl -cnZpY2VzIExMQzCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQCjkvcS2bb1VQ4yt/5e -ih5OO6kK/n1Lzllr7D8ZwtQP8fOEpp5E2ng+D6Ud1Z1gYipr58Kj3nssSNpI6bX3 -VyIQzK7wLclnd/YozqNNmgIyZecN7EglK9ITHJLP+x8FtUpt3QbyYXJdmVMegN6P -hviYt5JH/nYl4hh3Pa1HJdskgQIVALVJ3ER11+Ko4tP6nwvHwh6+ERYRAoGBAI1j -k+tkqMVHuAFcvAGKocTgsjJem6/5qomzJuKDmbJNu9Qxw3rAotXau8Qe+MBcJl/U -hhy1KHVpCGl9fueQ2s6IL0CaO/buycU1CiYQk40KNHCcHfNiZbdlx1E9rpUp7bnF -lRa2v1ntMX3caRVDdbtPEWmdxSCYsYFDk4mZrOLBA4GEAAKBgEbmeve5f8LIE/Gf -MNmP9CM5eovQOGx5ho8WqD+aTebs+k2tn92BBPqeZqpWRa5P/+jrdKml1qx4llHW -MXrs3IgIb6+hUIB+S8dz8/mmO0bpr76RoZVCXYab2CZedFut7qc3WUH9+EUAH5mw -vSeDCOUMYQR7R9LINYwouHIziqQYMAkGByqGSM44BAMDLwAwLAIUWXBlk40xTwSw -7HX32MxXYruse9ACFBNGmdX2ZBrVNGrN9N2f6ROk0k9K ------END CERTIFICATE-----` - -var AppStoreRecieptFixture = ` ------BEGIN PKCS7----- -MIITtgYJKoZIhvcNAQcCoIITpzCCE6MCAQExCzAJBgUrDgMCGgUAMIIDVwYJKoZI -hvcNAQcBoIIDSASCA0QxggNAMAoCAQgCAQEEAhYAMAoCARQCAQEEAgwAMAsCAQEC -AQEEAwIBADALAgEDAgEBBAMMATEwCwIBCwIBAQQDAgEAMAsCAQ8CAQEEAwIBADAL -AgEQAgEBBAMCAQAwCwIBGQIBAQQDAgEDMAwCAQoCAQEEBBYCNCswDAIBDgIBAQQE -AgIAjTANAgENAgEBBAUCAwFgvTANAgETAgEBBAUMAzEuMDAOAgEJAgEBBAYCBFAy -NDcwGAIBAgIBAQQQDA5jb20uemhpaHUudGVzdDAYAgEEAgECBBCS+ZODNMHwT1Nz -gWYDXyWZMBsCAQACAQEEEwwRUHJvZHVjdGlvblNhbmRib3gwHAIBBQIBAQQU4nRh -YCEZx70Flzv7hvJRjJZckYIwHgIBDAIBAQQWFhQyMDE2LTA3LTIzVDA2OjIxOjEx -WjAeAgESAgEBBBYWFDIwMTMtMDgtMDFUMDc6MDA6MDBaMD0CAQYCAQEENbR21I+a -8+byMXo3NPRoDWQmSXQF2EcCeBoD4GaL//ZCRETp9rGFPSg1KekCP7Kr9HAqw09m -MEICAQcCAQEEOlVJozYYBdugybShbiiMsejDMNeCbZq6CrzGBwW6GBy+DGWxJI91 -Y3ouXN4TZUhuVvLvN1b0m5T3ggQwggFaAgERAgEBBIIBUDGCAUwwCwICBqwCAQEE -AhYAMAsCAgatAgEBBAIMADALAgIGsAIBAQQCFgAwCwICBrICAQEEAgwAMAsCAgaz -AgEBBAIMADALAgIGtAIBAQQCDAAwCwICBrUCAQEEAgwAMAsCAga2AgEBBAIMADAM -AgIGpQIBAQQDAgEBMAwCAgarAgEBBAMCAQEwDAICBq4CAQEEAwIBADAMAgIGrwIB -AQQDAgEAMAwCAgaxAgEBBAMCAQAwGwICBqcCAQEEEgwQMTAwMDAwMDIyNTMyNTkw -MTAbAgIGqQIBAQQSDBAxMDAwMDAwMjI1MzI1OTAxMB8CAgaoAgEBBBYWFDIwMTYt -MDctMjNUMDY6MjE6MTFaMB8CAgaqAgEBBBYWFDIwMTYtMDctMjNUMDY6MjE6MTFa -MCACAgamAgEBBBcMFWNvbS56aGlodS50ZXN0LnRlc3RfMaCCDmUwggV8MIIEZKAD -AgECAggO61eH554JjTANBgkqhkiG9w0BAQUFADCBljELMAkGA1UEBhMCVVMxEzAR -BgNVBAoMCkFwcGxlIEluYy4xLDAqBgNVBAsMI0FwcGxlIFdvcmxkd2lkZSBEZXZl -bG9wZXIgUmVsYXRpb25zMUQwQgYDVQQDDDtBcHBsZSBXb3JsZHdpZGUgRGV2ZWxv -cGVyIFJlbGF0aW9ucyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNTExMTMw -MjE1MDlaFw0yMzAyMDcyMTQ4NDdaMIGJMTcwNQYDVQQDDC5NYWMgQXBwIFN0b3Jl -IGFuZCBpVHVuZXMgU3RvcmUgUmVjZWlwdCBTaWduaW5nMSwwKgYDVQQLDCNBcHBs -ZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczETMBEGA1UECgwKQXBwbGUg -SW5jLjELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQClz4H9JaKBW9aH7SPaMxyO4iPApcQmyz3Gn+xKDVWG/6QC15fKOVRtfX+yVBid -xCxScY5ke4LOibpJ1gjltIhxzz9bRi7GxB24A6lYogQ+IXjV27fQjhKNg0xbKmg3 -k8LyvR7E0qEMSlhSqxLj7d0fmBWQNS3CzBLKjUiB91h4VGvojDE2H0oGDEdU8zeQ -uLKSiX1fpIVK4cCc4Lqku4KXY/Qrk8H9Pm/KwfU8qY9SGsAlCnYO3v6Z/v/Ca/Vb -XqxzUUkIVonMQ5DMjoEC0KCXtlyxoWlph5AQaCYmObgdEHOwCl3Fc9DfdjvYLdmI -HuPsB8/ijtDT+iZVge/iA0kjAgMBAAGjggHXMIIB0zA/BggrBgEFBQcBAQQzMDEw -LwYIKwYBBQUHMAGGI2h0dHA6Ly9vY3NwLmFwcGxlLmNvbS9vY3NwMDMtd3dkcjA0 -MB0GA1UdDgQWBBSRpJz8xHa3n6CK9E31jzZd7SsEhTAMBgNVHRMBAf8EAjAAMB8G -A1UdIwQYMBaAFIgnFwmpthhgi+zruvZHWcVSVKO3MIIBHgYDVR0gBIIBFTCCAREw -ggENBgoqhkiG92NkBQYBMIH+MIHDBggrBgEFBQcCAjCBtgyBs1JlbGlhbmNlIG9u -IHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0YW5j -ZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1zIGFuZCBjb25k -aXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBjZXJ0aWZpY2F0 -aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMDYGCCsGAQUFBwIBFipodHRwOi8vd3d3 -LmFwcGxlLmNvbS9jZXJ0aWZpY2F0ZWF1dGhvcml0eS8wDgYDVR0PAQH/BAQDAgeA -MBAGCiqGSIb3Y2QGCwEEAgUAMA0GCSqGSIb3DQEBBQUAA4IBAQANphvTLj3jWysH -bkKWbNPojEMwgl/gXNGNvr0PvRr8JZLbjIXDgFnf4+LXLgUUrA3btrj+/DUufMut -F2uOfx/kd7mxZ5W0E16mGYZ2+FogledjjA9z/Ojtxh+umfhlSFyg4Cg6wBA3Lbmg -BDkfc7nIBf3y3n8aKipuKwH8oCBc2et9J6Yz+PWY4L5E27FMZ/xuCk/J4gao0pfz -p45rUaJahHVl0RYEYuPBX/UIqc9o2ZIAycGMs/iNAGS6WGDAfK+PdcppuVsq1h1o -bphC9UynNxmbzDscehlD86Ntv0hgBgw2kivs3hi1EdotI9CO/KBpnBcbnoB7OUdF -MGEvxxOoMIIEIjCCAwqgAwIBAgIIAd68xDltoBAwDQYJKoZIhvcNAQEFBQAwYjEL -MAkGA1UEBhMCVVMxEzARBgNVBAoTCkFwcGxlIEluYy4xJjAkBgNVBAsTHUFwcGxl -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1BcHBsZSBSb290IENB -MB4XDTEzMDIwNzIxNDg0N1oXDTIzMDIwNzIxNDg0N1owgZYxCzAJBgNVBAYTAlVT -MRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3JsZHdpZGUg -RGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3aWRlIERl -dmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKOFSmy1aqyCQ5SOmM7uxfuH8mkbw0 -U3rOfGOAYXdkXqUHI7Y5/lAtFVZYcC1+xG7BSoU+L/DehBqhV8mvexj/avoVEkkV -CBmsqtsqMu2WY2hSFT2Miuy/axiV4AOsAX2XBWfODoWVN2rtCbauZ81RZJ/GXNG8 -V25nNYB2NqSHgW44j9grFU57Jdhav06DwY3Sk9UacbVgnJ0zTlX5ElgMhrgWDcHl -d0WNUEi6Ky3klIXh6MSdxmilsKP8Z35wugJZS3dCkTm59c3hTO/AO0iMpuUhXf1q -arunFjVg0uat80YpyejDi+l5wGphZxWy8P3laLxiX27Pmd3vG2P+kmWrAgMBAAGj -gaYwgaMwHQYDVR0OBBYEFIgnFwmpthhgi+zruvZHWcVSVKO3MA8GA1UdEwEB/wQF -MAMBAf8wHwYDVR0jBBgwFoAUK9BpR5R2Cf70a40uQKb3R01/CF4wLgYDVR0fBCcw -JTAjoCGgH4YdaHR0cDovL2NybC5hcHBsZS5jb20vcm9vdC5jcmwwDgYDVR0PAQH/ -BAQDAgGGMBAGCiqGSIb3Y2QGAgEEAgUAMA0GCSqGSIb3DQEBBQUAA4IBAQBPz+9Z -viz1smwvj+4ThzLoBTWobot9yWkMudkXvHcs1Gfi/ZptOllc34MBvbKuKmFysa/N -w0Uwj6ODDc4dR7Txk4qjdJukw5hyhzs+r0ULklS5MruQGFNrCk4QttkdUGwhgAqJ -TleMa1s8Pab93vcNIx0LSiaHP7qRkkykGRIZbVf1eliHe2iK5IaMSuviSRSqpd1V -AKmuu0swruGgsbwpgOYJd+W+NKIByn/c4grmO7i77LpilfMFY0GCzQ87HUyVpNur -+cmV6U/kTecmmYHpvPm0KdIBembhLoz2IYrF+Hjhga6/05Cdqa3zr/04GpZnMBxR -pVzscYqCtGwPDBUfMIIEuzCCA6OgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBiMQsw -CQYDVQQGEwJVUzETMBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUg -Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0Ew -HhcNMDYwNDI1MjE0MDM2WhcNMzUwMjA5MjE0MDM2WjBiMQswCQYDVQQGEwJVUzET -MBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkxFjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQDkkakJH5HbHkdQ6wXtXnmELes2oldMVeyLGYne -+Uts9QerIjAC6Bg++FAJ039BqJj50cpmnCRrEdCju+QbKsMflZ56DKRHi1vUFjcz -y8QPTc4UadHJGXL1XQ7Vf1+b8iUDulWPTV0N8WQ1IxVLFVkds5T39pyez1C6wVhQ -Z48ItCD3y6wsIG9wtj8BMIy3Q88PnT3zK0koGsj+zrW5DtleHNbLPbU6rfQPDgCS -C7EhFi501TwN22IWq6NxkkdTVcGvL0Gz+PvjcM3mo0xFfh9Ma1CWQYnEdGILEINB -hzOKgbEwWOxaBDKMaLOPHd5lc/9nXmW8Sdh2nzMUZaF3lMktAgMBAAGjggF6MIIB -djAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUK9Bp -R5R2Cf70a40uQKb3R01/CF4wHwYDVR0jBBgwFoAUK9BpR5R2Cf70a40uQKb3R01/ -CF4wggERBgNVHSAEggEIMIIBBDCCAQAGCSqGSIb3Y2QFATCB8jAqBggrBgEFBQcC -ARYeaHR0cHM6Ly93d3cuYXBwbGUuY29tL2FwcGxlY2EvMIHDBggrBgEFBQcCAjCB -thqBs1JlbGlhbmNlIG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFz -c3VtZXMgYWNjZXB0YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJk -IHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5 -IGFuZCBjZXJ0aWZpY2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMA0GCSqGSIb3 -DQEBBQUAA4IBAQBcNplMLXi37Yyb3PN3m/J20ncwT8EfhYOFG5k9RzfyqZtAjizU -sZAS2L70c5vu0mQPy3lPNNiiPvl4/2vIB+x9OYOLUyDTOMSxv5pPCmv/K/xZpwUJ -fBdAVhEedNO3iyM7R6PVbyTi69G3cN8PReEnyvFteO3ntRcXqNx+IjXKJdXZD9Zr -1KIkIxH3oayPc4FgxhtbCS+SsvhESPBgOJ4V9T0mZyCKM2r3DYLP3uujL/lTaltk -wGMzd/c6ByxW69oPIQ7aunMZT7XZNn/Bh1XZp5m5MkL72NVxnn6hUrcbvZNCJBIq -xw8dtk2cXmPIS4AXUKqK1drk/NAJBzewdXUhMYIByzCCAccCAQEwgaMwgZYxCzAJ -BgNVBAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBX -b3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29y -bGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkCCA7rV4fnngmNMAkGBSsOAwIaBQAwDQYJKoZIhvcNAQEBBQAEggEAasPtnide -NWyfUtewW9OSgcQA8pW+5tWMR0469cBPZR84uJa0gyfmPspySvbNOAwnrwzZHYLa -ujOxZLip4DUw4F5s3QwUa3y4BXpF4J+NSn9XNvxNtnT/GcEQtCuFwgJ0o3F0ilhv -MTHrwiwyx/vr+uNDqlORK8lfK+1qNp+A/kzh8eszMrn4JSeTh9ZYxLHE56WkTQGD -VZXl0gKgxSOmDrcp1eQxdlymzrPv9U60wUJ0bkPfrU9qZj3mJrmrkQk61JTe3j6/ -QfjfFBG9JG2mUmYQP1KQ3SypGHzDW8vngvsGu//tNU0NFfOqQu4bYU4VpQl0nPtD -4B85NkrgvQsWAQ== ------END PKCS7-----` diff --git a/vendor/github.com/fullsailor/pkcs7/x509.go b/vendor/github.com/fullsailor/pkcs7/x509.go new file mode 100644 index 00000000..195fd0e4 --- /dev/null +++ b/vendor/github.com/fullsailor/pkcs7/x509.go @@ -0,0 +1,133 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the go/golang LICENSE file. + +package pkcs7 + +// These are private constants and functions from the crypto/x509 package that +// are useful when dealing with signatures verified by x509 certificates + +import ( + "bytes" + "crypto" + "crypto/x509" + "crypto/x509/pkix" + "encoding/asn1" +) + +var ( + oidSignatureMD2WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2} + oidSignatureMD5WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4} + oidSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5} + oidSignatureSHA256WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11} + oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12} + oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13} + oidSignatureRSAPSS = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10} + oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3} + oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2} + oidSignatureECDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1} + oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2} + oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3} + oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4} + + oidSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1} + oidSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2} + oidSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3} + + oidMGF1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 8} + + // oidISOSignatureSHA1WithRSA means the same as oidSignatureSHA1WithRSA + // but it's specified by ISO. Microsoft's makecert.exe has been known + // to produce certificates with this OID. + oidISOSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 29} +) + +var signatureAlgorithmDetails = []struct { + algo x509.SignatureAlgorithm + name string + oid asn1.ObjectIdentifier + pubKeyAlgo x509.PublicKeyAlgorithm + hash crypto.Hash +}{ + {x509.MD2WithRSA, "MD2-RSA", oidSignatureMD2WithRSA, x509.RSA, crypto.Hash(0) /* no value for MD2 */}, + {x509.MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, x509.RSA, crypto.MD5}, + {x509.SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, x509.RSA, crypto.SHA1}, + {x509.SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, x509.RSA, crypto.SHA1}, + {x509.SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, x509.RSA, crypto.SHA256}, + {x509.SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, x509.RSA, crypto.SHA384}, + {x509.SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, x509.RSA, crypto.SHA512}, + {x509.SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA256}, + {x509.SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA384}, + {x509.SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA512}, + {x509.DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, x509.DSA, crypto.SHA1}, + {x509.DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, x509.DSA, crypto.SHA256}, + {x509.ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, x509.ECDSA, crypto.SHA1}, + {x509.ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, x509.ECDSA, crypto.SHA256}, + {x509.ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, x509.ECDSA, crypto.SHA384}, + {x509.ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, x509.ECDSA, crypto.SHA512}, +} + +// pssParameters reflects the parameters in an AlgorithmIdentifier that +// specifies RSA PSS. See https://tools.ietf.org/html/rfc3447#appendix-A.2.3 +type pssParameters struct { + // The following three fields are not marked as + // optional because the default values specify SHA-1, + // which is no longer suitable for use in signatures. + Hash pkix.AlgorithmIdentifier `asn1:"explicit,tag:0"` + MGF pkix.AlgorithmIdentifier `asn1:"explicit,tag:1"` + SaltLength int `asn1:"explicit,tag:2"` + TrailerField int `asn1:"optional,explicit,tag:3,default:1"` +} + +// asn1.NullBytes is not available prior to Go 1.9 +var nullBytes = []byte{5, 0} + +func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) x509.SignatureAlgorithm { + if !ai.Algorithm.Equal(oidSignatureRSAPSS) { + for _, details := range signatureAlgorithmDetails { + if ai.Algorithm.Equal(details.oid) { + return details.algo + } + } + return x509.UnknownSignatureAlgorithm + } + + // RSA PSS is special because it encodes important parameters + // in the Parameters. + + var params pssParameters + if _, err := asn1.Unmarshal(ai.Parameters.FullBytes, ¶ms); err != nil { + return x509.UnknownSignatureAlgorithm + } + + var mgf1HashFunc pkix.AlgorithmIdentifier + if _, err := asn1.Unmarshal(params.MGF.Parameters.FullBytes, &mgf1HashFunc); err != nil { + return x509.UnknownSignatureAlgorithm + } + + // PSS is greatly overburdened with options. This code forces + // them into three buckets by requiring that the MGF1 hash + // function always match the message hash function (as + // recommended in + // https://tools.ietf.org/html/rfc3447#section-8.1), that the + // salt length matches the hash length, and that the trailer + // field has the default value. + if !bytes.Equal(params.Hash.Parameters.FullBytes, nullBytes) || + !params.MGF.Algorithm.Equal(oidMGF1) || + !mgf1HashFunc.Algorithm.Equal(params.Hash.Algorithm) || + !bytes.Equal(mgf1HashFunc.Parameters.FullBytes, nullBytes) || + params.TrailerField != 1 { + return x509.UnknownSignatureAlgorithm + } + + switch { + case params.Hash.Algorithm.Equal(oidSHA256) && params.SaltLength == 32: + return x509.SHA256WithRSAPSS + case params.Hash.Algorithm.Equal(oidSHA384) && params.SaltLength == 48: + return x509.SHA384WithRSAPSS + case params.Hash.Algorithm.Equal(oidSHA512) && params.SaltLength == 64: + return x509.SHA512WithRSAPSS + } + + return x509.UnknownSignatureAlgorithm +} diff --git a/vendor/github.com/gorilla/mux/.travis.yml b/vendor/github.com/gorilla/mux/.travis.yml new file mode 100644 index 00000000..d003ad92 --- /dev/null +++ b/vendor/github.com/gorilla/mux/.travis.yml @@ -0,0 +1,24 @@ +language: go + + +matrix: + include: + - go: 1.7.x + - go: 1.8.x + - go: 1.9.x + - go: 1.10.x + - go: 1.11.x + - go: 1.x + env: LATEST=true + - go: tip + allow_failures: + - go: tip + +install: + - # Skip + +script: + - go get -t -v ./... + - diff -u <(echo -n) <(gofmt -d .) + - if [[ "$LATEST" = true ]]; then go vet .; fi + - go test -v -race ./... diff --git a/vendor/github.com/gorilla/mux/AUTHORS b/vendor/github.com/gorilla/mux/AUTHORS new file mode 100644 index 00000000..b722392e --- /dev/null +++ b/vendor/github.com/gorilla/mux/AUTHORS @@ -0,0 +1,8 @@ +# This is the official list of gorilla/mux authors for copyright purposes. +# +# Please keep the list sorted. + +Google LLC (https://opensource.google.com/) +Kamil Kisielk +Matt Silverlock +Rodrigo Moraes (https://github.com/moraes) diff --git a/vendor/github.com/gorilla/mux/ISSUE_TEMPLATE.md b/vendor/github.com/gorilla/mux/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..232be82e --- /dev/null +++ b/vendor/github.com/gorilla/mux/ISSUE_TEMPLATE.md @@ -0,0 +1,11 @@ +**What version of Go are you running?** (Paste the output of `go version`) + + +**What version of gorilla/mux are you at?** (Paste the output of `git rev-parse HEAD` inside `$GOPATH/src/github.com/gorilla/mux`) + + +**Describe your problem** (and what you have tried so far) + + +**Paste a minimal, runnable, reproduction of your issue below** (use backticks to format it) + diff --git a/vendor/github.com/gorilla/mux/LICENSE b/vendor/github.com/gorilla/mux/LICENSE new file mode 100644 index 00000000..6903df63 --- /dev/null +++ b/vendor/github.com/gorilla/mux/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2012-2018 The Gorilla Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/gorilla/mux/README.md b/vendor/github.com/gorilla/mux/README.md new file mode 100644 index 00000000..c661599a --- /dev/null +++ b/vendor/github.com/gorilla/mux/README.md @@ -0,0 +1,649 @@ +# gorilla/mux + +[![GoDoc](https://godoc.org/github.com/gorilla/mux?status.svg)](https://godoc.org/github.com/gorilla/mux) +[![Build Status](https://travis-ci.org/gorilla/mux.svg?branch=master)](https://travis-ci.org/gorilla/mux) +[![Sourcegraph](https://sourcegraph.com/github.com/gorilla/mux/-/badge.svg)](https://sourcegraph.com/github.com/gorilla/mux?badge) + +![Gorilla Logo](http://www.gorillatoolkit.org/static/images/gorilla-icon-64.png) + +https://www.gorillatoolkit.org/pkg/mux + +Package `gorilla/mux` implements a request router and dispatcher for matching incoming requests to +their respective handler. + +The name mux stands for "HTTP request multiplexer". Like the standard `http.ServeMux`, `mux.Router` matches incoming requests against a list of registered routes and calls a handler for the route that matches the URL or other conditions. The main features are: + +* It implements the `http.Handler` interface so it is compatible with the standard `http.ServeMux`. +* Requests can be matched based on URL host, path, path prefix, schemes, header and query values, HTTP methods or using custom matchers. +* URL hosts, paths and query values can have variables with an optional regular expression. +* Registered URLs can be built, or "reversed", which helps maintaining references to resources. +* Routes can be used as subrouters: nested routes are only tested if the parent route matches. This is useful to define groups of routes that share common conditions like a host, a path prefix or other repeated attributes. As a bonus, this optimizes request matching. + +--- + +* [Install](#install) +* [Examples](#examples) +* [Matching Routes](#matching-routes) +* [Static Files](#static-files) +* [Registered URLs](#registered-urls) +* [Walking Routes](#walking-routes) +* [Graceful Shutdown](#graceful-shutdown) +* [Middleware](#middleware) +* [Testing Handlers](#testing-handlers) +* [Full Example](#full-example) + +--- + +## Install + +With a [correctly configured](https://golang.org/doc/install#testing) Go toolchain: + +```sh +go get -u github.com/gorilla/mux +``` + +## Examples + +Let's start registering a couple of URL paths and handlers: + +```go +func main() { + r := mux.NewRouter() + r.HandleFunc("/", HomeHandler) + r.HandleFunc("/products", ProductsHandler) + r.HandleFunc("/articles", ArticlesHandler) + http.Handle("/", r) +} +``` + +Here we register three routes mapping URL paths to handlers. This is equivalent to how `http.HandleFunc()` works: if an incoming request URL matches one of the paths, the corresponding handler is called passing (`http.ResponseWriter`, `*http.Request`) as parameters. + +Paths can have variables. They are defined using the format `{name}` or `{name:pattern}`. If a regular expression pattern is not defined, the matched variable will be anything until the next slash. For example: + +```go +r := mux.NewRouter() +r.HandleFunc("/products/{key}", ProductHandler) +r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler) +r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler) +``` + +The names are used to create a map of route variables which can be retrieved calling `mux.Vars()`: + +```go +func ArticlesCategoryHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + w.WriteHeader(http.StatusOK) + fmt.Fprintf(w, "Category: %v\n", vars["category"]) +} +``` + +And this is all you need to know about the basic usage. More advanced options are explained below. + +### Matching Routes + +Routes can also be restricted to a domain or subdomain. Just define a host pattern to be matched. They can also have variables: + +```go +r := mux.NewRouter() +// Only matches if domain is "www.example.com". +r.Host("www.example.com") +// Matches a dynamic subdomain. +r.Host("{subdomain:[a-z]+}.example.com") +``` + +There are several other matchers that can be added. To match path prefixes: + +```go +r.PathPrefix("/products/") +``` + +...or HTTP methods: + +```go +r.Methods("GET", "POST") +``` + +...or URL schemes: + +```go +r.Schemes("https") +``` + +...or header values: + +```go +r.Headers("X-Requested-With", "XMLHttpRequest") +``` + +...or query values: + +```go +r.Queries("key", "value") +``` + +...or to use a custom matcher function: + +```go +r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool { + return r.ProtoMajor == 0 +}) +``` + +...and finally, it is possible to combine several matchers in a single route: + +```go +r.HandleFunc("/products", ProductsHandler). + Host("www.example.com"). + Methods("GET"). + Schemes("http") +``` + +Routes are tested in the order they were added to the router. If two routes match, the first one wins: + +```go +r := mux.NewRouter() +r.HandleFunc("/specific", specificHandler) +r.PathPrefix("/").Handler(catchAllHandler) +``` + +Setting the same matching conditions again and again can be boring, so we have a way to group several routes that share the same requirements. We call it "subrouting". + +For example, let's say we have several URLs that should only match when the host is `www.example.com`. Create a route for that host and get a "subrouter" from it: + +```go +r := mux.NewRouter() +s := r.Host("www.example.com").Subrouter() +``` + +Then register routes in the subrouter: + +```go +s.HandleFunc("/products/", ProductsHandler) +s.HandleFunc("/products/{key}", ProductHandler) +s.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler) +``` + +The three URL paths we registered above will only be tested if the domain is `www.example.com`, because the subrouter is tested first. This is not only convenient, but also optimizes request matching. You can create subrouters combining any attribute matchers accepted by a route. + +Subrouters can be used to create domain or path "namespaces": you define subrouters in a central place and then parts of the app can register its paths relatively to a given subrouter. + +There's one more thing about subroutes. When a subrouter has a path prefix, the inner routes use it as base for their paths: + +```go +r := mux.NewRouter() +s := r.PathPrefix("/products").Subrouter() +// "/products/" +s.HandleFunc("/", ProductsHandler) +// "/products/{key}/" +s.HandleFunc("/{key}/", ProductHandler) +// "/products/{key}/details" +s.HandleFunc("/{key}/details", ProductDetailsHandler) +``` + + +### Static Files + +Note that the path provided to `PathPrefix()` represents a "wildcard": calling +`PathPrefix("/static/").Handler(...)` means that the handler will be passed any +request that matches "/static/\*". This makes it easy to serve static files with mux: + +```go +func main() { + var dir string + + flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir") + flag.Parse() + r := mux.NewRouter() + + // This will serve files under http://localhost:8000/static/ + r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir)))) + + srv := &http.Server{ + Handler: r, + Addr: "127.0.0.1:8000", + // Good practice: enforce timeouts for servers you create! + WriteTimeout: 15 * time.Second, + ReadTimeout: 15 * time.Second, + } + + log.Fatal(srv.ListenAndServe()) +} +``` + +### Registered URLs + +Now let's see how to build registered URLs. + +Routes can be named. All routes that define a name can have their URLs built, or "reversed". We define a name calling `Name()` on a route. For example: + +```go +r := mux.NewRouter() +r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). + Name("article") +``` + +To build a URL, get the route and call the `URL()` method, passing a sequence of key/value pairs for the route variables. For the previous route, we would do: + +```go +url, err := r.Get("article").URL("category", "technology", "id", "42") +``` + +...and the result will be a `url.URL` with the following path: + +``` +"/articles/technology/42" +``` + +This also works for host and query value variables: + +```go +r := mux.NewRouter() +r.Host("{subdomain}.example.com"). + Path("/articles/{category}/{id:[0-9]+}"). + Queries("filter", "{filter}"). + HandlerFunc(ArticleHandler). + Name("article") + +// url.String() will be "http://news.example.com/articles/technology/42?filter=gorilla" +url, err := r.Get("article").URL("subdomain", "news", + "category", "technology", + "id", "42", + "filter", "gorilla") +``` + +All variables defined in the route are required, and their values must conform to the corresponding patterns. These requirements guarantee that a generated URL will always match a registered route -- the only exception is for explicitly defined "build-only" routes which never match. + +Regex support also exists for matching Headers within a route. For example, we could do: + +```go +r.HeadersRegexp("Content-Type", "application/(text|json)") +``` + +...and the route will match both requests with a Content-Type of `application/json` as well as `application/text` + +There's also a way to build only the URL host or path for a route: use the methods `URLHost()` or `URLPath()` instead. For the previous route, we would do: + +```go +// "http://news.example.com/" +host, err := r.Get("article").URLHost("subdomain", "news") + +// "/articles/technology/42" +path, err := r.Get("article").URLPath("category", "technology", "id", "42") +``` + +And if you use subrouters, host and path defined separately can be built as well: + +```go +r := mux.NewRouter() +s := r.Host("{subdomain}.example.com").Subrouter() +s.Path("/articles/{category}/{id:[0-9]+}"). + HandlerFunc(ArticleHandler). + Name("article") + +// "http://news.example.com/articles/technology/42" +url, err := r.Get("article").URL("subdomain", "news", + "category", "technology", + "id", "42") +``` + +### Walking Routes + +The `Walk` function on `mux.Router` can be used to visit all of the routes that are registered on a router. For example, +the following prints all of the registered routes: + +```go +package main + +import ( + "fmt" + "net/http" + "strings" + + "github.com/gorilla/mux" +) + +func handler(w http.ResponseWriter, r *http.Request) { + return +} + +func main() { + r := mux.NewRouter() + r.HandleFunc("/", handler) + r.HandleFunc("/products", handler).Methods("POST") + r.HandleFunc("/articles", handler).Methods("GET") + r.HandleFunc("/articles/{id}", handler).Methods("GET", "PUT") + r.HandleFunc("/authors", handler).Queries("surname", "{surname}") + err := r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error { + pathTemplate, err := route.GetPathTemplate() + if err == nil { + fmt.Println("ROUTE:", pathTemplate) + } + pathRegexp, err := route.GetPathRegexp() + if err == nil { + fmt.Println("Path regexp:", pathRegexp) + } + queriesTemplates, err := route.GetQueriesTemplates() + if err == nil { + fmt.Println("Queries templates:", strings.Join(queriesTemplates, ",")) + } + queriesRegexps, err := route.GetQueriesRegexp() + if err == nil { + fmt.Println("Queries regexps:", strings.Join(queriesRegexps, ",")) + } + methods, err := route.GetMethods() + if err == nil { + fmt.Println("Methods:", strings.Join(methods, ",")) + } + fmt.Println() + return nil + }) + + if err != nil { + fmt.Println(err) + } + + http.Handle("/", r) +} +``` + +### Graceful Shutdown + +Go 1.8 introduced the ability to [gracefully shutdown](https://golang.org/doc/go1.8#http_shutdown) a `*http.Server`. Here's how to do that alongside `mux`: + +```go +package main + +import ( + "context" + "flag" + "log" + "net/http" + "os" + "os/signal" + "time" + + "github.com/gorilla/mux" +) + +func main() { + var wait time.Duration + flag.DurationVar(&wait, "graceful-timeout", time.Second * 15, "the duration for which the server gracefully wait for existing connections to finish - e.g. 15s or 1m") + flag.Parse() + + r := mux.NewRouter() + // Add your routes as needed + + srv := &http.Server{ + Addr: "0.0.0.0:8080", + // Good practice to set timeouts to avoid Slowloris attacks. + WriteTimeout: time.Second * 15, + ReadTimeout: time.Second * 15, + IdleTimeout: time.Second * 60, + Handler: r, // Pass our instance of gorilla/mux in. + } + + // Run our server in a goroutine so that it doesn't block. + go func() { + if err := srv.ListenAndServe(); err != nil { + log.Println(err) + } + }() + + c := make(chan os.Signal, 1) + // We'll accept graceful shutdowns when quit via SIGINT (Ctrl+C) + // SIGKILL, SIGQUIT or SIGTERM (Ctrl+/) will not be caught. + signal.Notify(c, os.Interrupt) + + // Block until we receive our signal. + <-c + + // Create a deadline to wait for. + ctx, cancel := context.WithTimeout(context.Background(), wait) + defer cancel() + // Doesn't block if no connections, but will otherwise wait + // until the timeout deadline. + srv.Shutdown(ctx) + // Optionally, you could run srv.Shutdown in a goroutine and block on + // <-ctx.Done() if your application should wait for other services + // to finalize based on context cancellation. + log.Println("shutting down") + os.Exit(0) +} +``` + +### Middleware + +Mux supports the addition of middlewares to a [Router](https://godoc.org/github.com/gorilla/mux#Router), which are executed in the order they are added if a match is found, including its subrouters. +Middlewares are (typically) small pieces of code which take one request, do something with it, and pass it down to another middleware or the final handler. Some common use cases for middleware are request logging, header manipulation, or `ResponseWriter` hijacking. + +Mux middlewares are defined using the de facto standard type: + +```go +type MiddlewareFunc func(http.Handler) http.Handler +``` + +Typically, the returned handler is a closure which does something with the http.ResponseWriter and http.Request passed to it, and then calls the handler passed as parameter to the MiddlewareFunc. This takes advantage of closures being able access variables from the context where they are created, while retaining the signature enforced by the receivers. + +A very basic middleware which logs the URI of the request being handled could be written as: + +```go +func loggingMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Do stuff here + log.Println(r.RequestURI) + // Call the next handler, which can be another middleware in the chain, or the final handler. + next.ServeHTTP(w, r) + }) +} +``` + +Middlewares can be added to a router using `Router.Use()`: + +```go +r := mux.NewRouter() +r.HandleFunc("/", handler) +r.Use(loggingMiddleware) +``` + +A more complex authentication middleware, which maps session token to users, could be written as: + +```go +// Define our struct +type authenticationMiddleware struct { + tokenUsers map[string]string +} + +// Initialize it somewhere +func (amw *authenticationMiddleware) Populate() { + amw.tokenUsers["00000000"] = "user0" + amw.tokenUsers["aaaaaaaa"] = "userA" + amw.tokenUsers["05f717e5"] = "randomUser" + amw.tokenUsers["deadbeef"] = "user0" +} + +// Middleware function, which will be called for each request +func (amw *authenticationMiddleware) Middleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + token := r.Header.Get("X-Session-Token") + + if user, found := amw.tokenUsers[token]; found { + // We found the token in our map + log.Printf("Authenticated user %s\n", user) + // Pass down the request to the next middleware (or final handler) + next.ServeHTTP(w, r) + } else { + // Write an error and stop the handler chain + http.Error(w, "Forbidden", http.StatusForbidden) + } + }) +} +``` + +```go +r := mux.NewRouter() +r.HandleFunc("/", handler) + +amw := authenticationMiddleware{} +amw.Populate() + +r.Use(amw.Middleware) +``` + +Note: The handler chain will be stopped if your middleware doesn't call `next.ServeHTTP()` with the corresponding parameters. This can be used to abort a request if the middleware writer wants to. Middlewares _should_ write to `ResponseWriter` if they _are_ going to terminate the request, and they _should not_ write to `ResponseWriter` if they _are not_ going to terminate it. + +### Testing Handlers + +Testing handlers in a Go web application is straightforward, and _mux_ doesn't complicate this any further. Given two files: `endpoints.go` and `endpoints_test.go`, here's how we'd test an application using _mux_. + +First, our simple HTTP handler: + +```go +// endpoints.go +package main + +func HealthCheckHandler(w http.ResponseWriter, r *http.Request) { + // A very simple health check. + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + + // In the future we could report back on the status of our DB, or our cache + // (e.g. Redis) by performing a simple PING, and include them in the response. + io.WriteString(w, `{"alive": true}`) +} + +func main() { + r := mux.NewRouter() + r.HandleFunc("/health", HealthCheckHandler) + + log.Fatal(http.ListenAndServe("localhost:8080", r)) +} +``` + +Our test code: + +```go +// endpoints_test.go +package main + +import ( + "net/http" + "net/http/httptest" + "testing" +) + +func TestHealthCheckHandler(t *testing.T) { + // Create a request to pass to our handler. We don't have any query parameters for now, so we'll + // pass 'nil' as the third parameter. + req, err := http.NewRequest("GET", "/health", nil) + if err != nil { + t.Fatal(err) + } + + // We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response. + rr := httptest.NewRecorder() + handler := http.HandlerFunc(HealthCheckHandler) + + // Our handlers satisfy http.Handler, so we can call their ServeHTTP method + // directly and pass in our Request and ResponseRecorder. + handler.ServeHTTP(rr, req) + + // Check the status code is what we expect. + if status := rr.Code; status != http.StatusOK { + t.Errorf("handler returned wrong status code: got %v want %v", + status, http.StatusOK) + } + + // Check the response body is what we expect. + expected := `{"alive": true}` + if rr.Body.String() != expected { + t.Errorf("handler returned unexpected body: got %v want %v", + rr.Body.String(), expected) + } +} +``` + +In the case that our routes have [variables](#examples), we can pass those in the request. We could write +[table-driven tests](https://dave.cheney.net/2013/06/09/writing-table-driven-tests-in-go) to test multiple +possible route variables as needed. + +```go +// endpoints.go +func main() { + r := mux.NewRouter() + // A route with a route variable: + r.HandleFunc("/metrics/{type}", MetricsHandler) + + log.Fatal(http.ListenAndServe("localhost:8080", r)) +} +``` + +Our test file, with a table-driven test of `routeVariables`: + +```go +// endpoints_test.go +func TestMetricsHandler(t *testing.T) { + tt := []struct{ + routeVariable string + shouldPass bool + }{ + {"goroutines", true}, + {"heap", true}, + {"counters", true}, + {"queries", true}, + {"adhadaeqm3k", false}, + } + + for _, tc := range tt { + path := fmt.Sprintf("/metrics/%s", tc.routeVariable) + req, err := http.NewRequest("GET", path, nil) + if err != nil { + t.Fatal(err) + } + + rr := httptest.NewRecorder() + + // Need to create a router that we can pass the request through so that the vars will be added to the context + router := mux.NewRouter() + router.HandleFunc("/metrics/{type}", MetricsHandler) + router.ServeHTTP(rr, req) + + // In this case, our MetricsHandler returns a non-200 response + // for a route variable it doesn't know about. + if rr.Code == http.StatusOK && !tc.shouldPass { + t.Errorf("handler should have failed on routeVariable %s: got %v want %v", + tc.routeVariable, rr.Code, http.StatusOK) + } + } +} +``` + +## Full Example + +Here's a complete, runnable example of a small `mux` based server: + +```go +package main + +import ( + "net/http" + "log" + "github.com/gorilla/mux" +) + +func YourHandler(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("Gorilla!\n")) +} + +func main() { + r := mux.NewRouter() + // Routes consist of a path and a handler function. + r.HandleFunc("/", YourHandler) + + // Bind to a port and pass our router in + log.Fatal(http.ListenAndServe(":8000", r)) +} +``` + +## License + +BSD licensed. See the LICENSE file for details. diff --git a/vendor/github.com/gorilla/mux/context.go b/vendor/github.com/gorilla/mux/context.go new file mode 100644 index 00000000..665940a2 --- /dev/null +++ b/vendor/github.com/gorilla/mux/context.go @@ -0,0 +1,18 @@ +package mux + +import ( + "context" + "net/http" +) + +func contextGet(r *http.Request, key interface{}) interface{} { + return r.Context().Value(key) +} + +func contextSet(r *http.Request, key, val interface{}) *http.Request { + if val == nil { + return r + } + + return r.WithContext(context.WithValue(r.Context(), key, val)) +} diff --git a/vendor/github.com/gorilla/mux/doc.go b/vendor/github.com/gorilla/mux/doc.go new file mode 100644 index 00000000..38957dee --- /dev/null +++ b/vendor/github.com/gorilla/mux/doc.go @@ -0,0 +1,306 @@ +// Copyright 2012 The Gorilla Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +/* +Package mux implements a request router and dispatcher. + +The name mux stands for "HTTP request multiplexer". Like the standard +http.ServeMux, mux.Router matches incoming requests against a list of +registered routes and calls a handler for the route that matches the URL +or other conditions. The main features are: + + * Requests can be matched based on URL host, path, path prefix, schemes, + header and query values, HTTP methods or using custom matchers. + * URL hosts, paths and query values can have variables with an optional + regular expression. + * Registered URLs can be built, or "reversed", which helps maintaining + references to resources. + * Routes can be used as subrouters: nested routes are only tested if the + parent route matches. This is useful to define groups of routes that + share common conditions like a host, a path prefix or other repeated + attributes. As a bonus, this optimizes request matching. + * It implements the http.Handler interface so it is compatible with the + standard http.ServeMux. + +Let's start registering a couple of URL paths and handlers: + + func main() { + r := mux.NewRouter() + r.HandleFunc("/", HomeHandler) + r.HandleFunc("/products", ProductsHandler) + r.HandleFunc("/articles", ArticlesHandler) + http.Handle("/", r) + } + +Here we register three routes mapping URL paths to handlers. This is +equivalent to how http.HandleFunc() works: if an incoming request URL matches +one of the paths, the corresponding handler is called passing +(http.ResponseWriter, *http.Request) as parameters. + +Paths can have variables. They are defined using the format {name} or +{name:pattern}. If a regular expression pattern is not defined, the matched +variable will be anything until the next slash. For example: + + r := mux.NewRouter() + r.HandleFunc("/products/{key}", ProductHandler) + r.HandleFunc("/articles/{category}/", ArticlesCategoryHandler) + r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler) + +Groups can be used inside patterns, as long as they are non-capturing (?:re). For example: + + r.HandleFunc("/articles/{category}/{sort:(?:asc|desc|new)}", ArticlesCategoryHandler) + +The names are used to create a map of route variables which can be retrieved +calling mux.Vars(): + + vars := mux.Vars(request) + category := vars["category"] + +Note that if any capturing groups are present, mux will panic() during parsing. To prevent +this, convert any capturing groups to non-capturing, e.g. change "/{sort:(asc|desc)}" to +"/{sort:(?:asc|desc)}". This is a change from prior versions which behaved unpredictably +when capturing groups were present. + +And this is all you need to know about the basic usage. More advanced options +are explained below. + +Routes can also be restricted to a domain or subdomain. Just define a host +pattern to be matched. They can also have variables: + + r := mux.NewRouter() + // Only matches if domain is "www.example.com". + r.Host("www.example.com") + // Matches a dynamic subdomain. + r.Host("{subdomain:[a-z]+}.domain.com") + +There are several other matchers that can be added. To match path prefixes: + + r.PathPrefix("/products/") + +...or HTTP methods: + + r.Methods("GET", "POST") + +...or URL schemes: + + r.Schemes("https") + +...or header values: + + r.Headers("X-Requested-With", "XMLHttpRequest") + +...or query values: + + r.Queries("key", "value") + +...or to use a custom matcher function: + + r.MatcherFunc(func(r *http.Request, rm *RouteMatch) bool { + return r.ProtoMajor == 0 + }) + +...and finally, it is possible to combine several matchers in a single route: + + r.HandleFunc("/products", ProductsHandler). + Host("www.example.com"). + Methods("GET"). + Schemes("http") + +Setting the same matching conditions again and again can be boring, so we have +a way to group several routes that share the same requirements. +We call it "subrouting". + +For example, let's say we have several URLs that should only match when the +host is "www.example.com". Create a route for that host and get a "subrouter" +from it: + + r := mux.NewRouter() + s := r.Host("www.example.com").Subrouter() + +Then register routes in the subrouter: + + s.HandleFunc("/products/", ProductsHandler) + s.HandleFunc("/products/{key}", ProductHandler) + s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler) + +The three URL paths we registered above will only be tested if the domain is +"www.example.com", because the subrouter is tested first. This is not +only convenient, but also optimizes request matching. You can create +subrouters combining any attribute matchers accepted by a route. + +Subrouters can be used to create domain or path "namespaces": you define +subrouters in a central place and then parts of the app can register its +paths relatively to a given subrouter. + +There's one more thing about subroutes. When a subrouter has a path prefix, +the inner routes use it as base for their paths: + + r := mux.NewRouter() + s := r.PathPrefix("/products").Subrouter() + // "/products/" + s.HandleFunc("/", ProductsHandler) + // "/products/{key}/" + s.HandleFunc("/{key}/", ProductHandler) + // "/products/{key}/details" + s.HandleFunc("/{key}/details", ProductDetailsHandler) + +Note that the path provided to PathPrefix() represents a "wildcard": calling +PathPrefix("/static/").Handler(...) means that the handler will be passed any +request that matches "/static/*". This makes it easy to serve static files with mux: + + func main() { + var dir string + + flag.StringVar(&dir, "dir", ".", "the directory to serve files from. Defaults to the current dir") + flag.Parse() + r := mux.NewRouter() + + // This will serve files under http://localhost:8000/static/ + r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir(dir)))) + + srv := &http.Server{ + Handler: r, + Addr: "127.0.0.1:8000", + // Good practice: enforce timeouts for servers you create! + WriteTimeout: 15 * time.Second, + ReadTimeout: 15 * time.Second, + } + + log.Fatal(srv.ListenAndServe()) + } + +Now let's see how to build registered URLs. + +Routes can be named. All routes that define a name can have their URLs built, +or "reversed". We define a name calling Name() on a route. For example: + + r := mux.NewRouter() + r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). + Name("article") + +To build a URL, get the route and call the URL() method, passing a sequence of +key/value pairs for the route variables. For the previous route, we would do: + + url, err := r.Get("article").URL("category", "technology", "id", "42") + +...and the result will be a url.URL with the following path: + + "/articles/technology/42" + +This also works for host and query value variables: + + r := mux.NewRouter() + r.Host("{subdomain}.domain.com"). + Path("/articles/{category}/{id:[0-9]+}"). + Queries("filter", "{filter}"). + HandlerFunc(ArticleHandler). + Name("article") + + // url.String() will be "http://news.domain.com/articles/technology/42?filter=gorilla" + url, err := r.Get("article").URL("subdomain", "news", + "category", "technology", + "id", "42", + "filter", "gorilla") + +All variables defined in the route are required, and their values must +conform to the corresponding patterns. These requirements guarantee that a +generated URL will always match a registered route -- the only exception is +for explicitly defined "build-only" routes which never match. + +Regex support also exists for matching Headers within a route. For example, we could do: + + r.HeadersRegexp("Content-Type", "application/(text|json)") + +...and the route will match both requests with a Content-Type of `application/json` as well as +`application/text` + +There's also a way to build only the URL host or path for a route: +use the methods URLHost() or URLPath() instead. For the previous route, +we would do: + + // "http://news.domain.com/" + host, err := r.Get("article").URLHost("subdomain", "news") + + // "/articles/technology/42" + path, err := r.Get("article").URLPath("category", "technology", "id", "42") + +And if you use subrouters, host and path defined separately can be built +as well: + + r := mux.NewRouter() + s := r.Host("{subdomain}.domain.com").Subrouter() + s.Path("/articles/{category}/{id:[0-9]+}"). + HandlerFunc(ArticleHandler). + Name("article") + + // "http://news.domain.com/articles/technology/42" + url, err := r.Get("article").URL("subdomain", "news", + "category", "technology", + "id", "42") + +Mux supports the addition of middlewares to a Router, which are executed in the order they are added if a match is found, including its subrouters. Middlewares are (typically) small pieces of code which take one request, do something with it, and pass it down to another middleware or the final handler. Some common use cases for middleware are request logging, header manipulation, or ResponseWriter hijacking. + + type MiddlewareFunc func(http.Handler) http.Handler + +Typically, the returned handler is a closure which does something with the http.ResponseWriter and http.Request passed to it, and then calls the handler passed as parameter to the MiddlewareFunc (closures can access variables from the context where they are created). + +A very basic middleware which logs the URI of the request being handled could be written as: + + func simpleMw(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + // Do stuff here + log.Println(r.RequestURI) + // Call the next handler, which can be another middleware in the chain, or the final handler. + next.ServeHTTP(w, r) + }) + } + +Middlewares can be added to a router using `Router.Use()`: + + r := mux.NewRouter() + r.HandleFunc("/", handler) + r.Use(simpleMw) + +A more complex authentication middleware, which maps session token to users, could be written as: + + // Define our struct + type authenticationMiddleware struct { + tokenUsers map[string]string + } + + // Initialize it somewhere + func (amw *authenticationMiddleware) Populate() { + amw.tokenUsers["00000000"] = "user0" + amw.tokenUsers["aaaaaaaa"] = "userA" + amw.tokenUsers["05f717e5"] = "randomUser" + amw.tokenUsers["deadbeef"] = "user0" + } + + // Middleware function, which will be called for each request + func (amw *authenticationMiddleware) Middleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + token := r.Header.Get("X-Session-Token") + + if user, found := amw.tokenUsers[token]; found { + // We found the token in our map + log.Printf("Authenticated user %s\n", user) + next.ServeHTTP(w, r) + } else { + http.Error(w, "Forbidden", http.StatusForbidden) + } + }) + } + + r := mux.NewRouter() + r.HandleFunc("/", handler) + + amw := authenticationMiddleware{} + amw.Populate() + + r.Use(amw.Middleware) + +Note: The handler chain will be stopped if your middleware doesn't call `next.ServeHTTP()` with the corresponding parameters. This can be used to abort a request if the middleware writer wants to. + +*/ +package mux diff --git a/vendor/github.com/gorilla/mux/go.mod b/vendor/github.com/gorilla/mux/go.mod new file mode 100644 index 00000000..cfc8ede5 --- /dev/null +++ b/vendor/github.com/gorilla/mux/go.mod @@ -0,0 +1 @@ +module github.com/gorilla/mux diff --git a/vendor/github.com/gorilla/mux/middleware.go b/vendor/github.com/gorilla/mux/middleware.go new file mode 100644 index 00000000..ceb812ce --- /dev/null +++ b/vendor/github.com/gorilla/mux/middleware.go @@ -0,0 +1,72 @@ +package mux + +import ( + "net/http" + "strings" +) + +// MiddlewareFunc is a function which receives an http.Handler and returns another http.Handler. +// Typically, the returned handler is a closure which does something with the http.ResponseWriter and http.Request passed +// to it, and then calls the handler passed as parameter to the MiddlewareFunc. +type MiddlewareFunc func(http.Handler) http.Handler + +// middleware interface is anything which implements a MiddlewareFunc named Middleware. +type middleware interface { + Middleware(handler http.Handler) http.Handler +} + +// Middleware allows MiddlewareFunc to implement the middleware interface. +func (mw MiddlewareFunc) Middleware(handler http.Handler) http.Handler { + return mw(handler) +} + +// Use appends a MiddlewareFunc to the chain. Middleware can be used to intercept or otherwise modify requests and/or responses, and are executed in the order that they are applied to the Router. +func (r *Router) Use(mwf ...MiddlewareFunc) { + for _, fn := range mwf { + r.middlewares = append(r.middlewares, fn) + } +} + +// useInterface appends a middleware to the chain. Middleware can be used to intercept or otherwise modify requests and/or responses, and are executed in the order that they are applied to the Router. +func (r *Router) useInterface(mw middleware) { + r.middlewares = append(r.middlewares, mw) +} + +// CORSMethodMiddleware sets the Access-Control-Allow-Methods response header +// on a request, by matching routes based only on paths. It also handles +// OPTIONS requests, by settings Access-Control-Allow-Methods, and then +// returning without calling the next http handler. +func CORSMethodMiddleware(r *Router) MiddlewareFunc { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + var allMethods []string + + err := r.Walk(func(route *Route, _ *Router, _ []*Route) error { + for _, m := range route.matchers { + if _, ok := m.(*routeRegexp); ok { + if m.Match(req, &RouteMatch{}) { + methods, err := route.GetMethods() + if err != nil { + return err + } + + allMethods = append(allMethods, methods...) + } + break + } + } + return nil + }) + + if err == nil { + w.Header().Set("Access-Control-Allow-Methods", strings.Join(append(allMethods, "OPTIONS"), ",")) + + if req.Method == "OPTIONS" { + return + } + } + + next.ServeHTTP(w, req) + }) + } +} diff --git a/vendor/github.com/gorilla/mux/mux.go b/vendor/github.com/gorilla/mux/mux.go new file mode 100644 index 00000000..a2cd193e --- /dev/null +++ b/vendor/github.com/gorilla/mux/mux.go @@ -0,0 +1,607 @@ +// Copyright 2012 The Gorilla Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mux + +import ( + "errors" + "fmt" + "net/http" + "path" + "regexp" +) + +var ( + // ErrMethodMismatch is returned when the method in the request does not match + // the method defined against the route. + ErrMethodMismatch = errors.New("method is not allowed") + // ErrNotFound is returned when no route match is found. + ErrNotFound = errors.New("no matching route was found") +) + +// NewRouter returns a new router instance. +func NewRouter() *Router { + return &Router{namedRoutes: make(map[string]*Route)} +} + +// Router registers routes to be matched and dispatches a handler. +// +// It implements the http.Handler interface, so it can be registered to serve +// requests: +// +// var router = mux.NewRouter() +// +// func main() { +// http.Handle("/", router) +// } +// +// Or, for Google App Engine, register it in a init() function: +// +// func init() { +// http.Handle("/", router) +// } +// +// This will send all incoming requests to the router. +type Router struct { + // Configurable Handler to be used when no route matches. + NotFoundHandler http.Handler + + // Configurable Handler to be used when the request method does not match the route. + MethodNotAllowedHandler http.Handler + + // Routes to be matched, in order. + routes []*Route + + // Routes by name for URL building. + namedRoutes map[string]*Route + + // If true, do not clear the request context after handling the request. + // + // Deprecated: No effect when go1.7+ is used, since the context is stored + // on the request itself. + KeepContext bool + + // Slice of middlewares to be called after a match is found + middlewares []middleware + + // configuration shared with `Route` + routeConf +} + +// common route configuration shared between `Router` and `Route` +type routeConf struct { + // If true, "/path/foo%2Fbar/to" will match the path "/path/{var}/to" + useEncodedPath bool + + // If true, when the path pattern is "/path/", accessing "/path" will + // redirect to the former and vice versa. + strictSlash bool + + // If true, when the path pattern is "/path//to", accessing "/path//to" + // will not redirect + skipClean bool + + // Manager for the variables from host and path. + regexp routeRegexpGroup + + // List of matchers. + matchers []matcher + + // The scheme used when building URLs. + buildScheme string + + buildVarsFunc BuildVarsFunc +} + +// returns an effective deep copy of `routeConf` +func copyRouteConf(r routeConf) routeConf { + c := r + + if r.regexp.path != nil { + c.regexp.path = copyRouteRegexp(r.regexp.path) + } + + if r.regexp.host != nil { + c.regexp.host = copyRouteRegexp(r.regexp.host) + } + + c.regexp.queries = make([]*routeRegexp, 0, len(r.regexp.queries)) + for _, q := range r.regexp.queries { + c.regexp.queries = append(c.regexp.queries, copyRouteRegexp(q)) + } + + c.matchers = make([]matcher, 0, len(r.matchers)) + for _, m := range r.matchers { + c.matchers = append(c.matchers, m) + } + + return c +} + +func copyRouteRegexp(r *routeRegexp) *routeRegexp { + c := *r + return &c +} + +// Match attempts to match the given request against the router's registered routes. +// +// If the request matches a route of this router or one of its subrouters the Route, +// Handler, and Vars fields of the the match argument are filled and this function +// returns true. +// +// If the request does not match any of this router's or its subrouters' routes +// then this function returns false. If available, a reason for the match failure +// will be filled in the match argument's MatchErr field. If the match failure type +// (eg: not found) has a registered handler, the handler is assigned to the Handler +// field of the match argument. +func (r *Router) Match(req *http.Request, match *RouteMatch) bool { + for _, route := range r.routes { + if route.Match(req, match) { + // Build middleware chain if no error was found + if match.MatchErr == nil { + for i := len(r.middlewares) - 1; i >= 0; i-- { + match.Handler = r.middlewares[i].Middleware(match.Handler) + } + } + return true + } + } + + if match.MatchErr == ErrMethodMismatch { + if r.MethodNotAllowedHandler != nil { + match.Handler = r.MethodNotAllowedHandler + return true + } + + return false + } + + // Closest match for a router (includes sub-routers) + if r.NotFoundHandler != nil { + match.Handler = r.NotFoundHandler + match.MatchErr = ErrNotFound + return true + } + + match.MatchErr = ErrNotFound + return false +} + +// ServeHTTP dispatches the handler registered in the matched route. +// +// When there is a match, the route variables can be retrieved calling +// mux.Vars(request). +func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { + if !r.skipClean { + path := req.URL.Path + if r.useEncodedPath { + path = req.URL.EscapedPath() + } + // Clean path to canonical form and redirect. + if p := cleanPath(path); p != path { + + // Added 3 lines (Philip Schlump) - It was dropping the query string and #whatever from query. + // This matches with fix in go 1.2 r.c. 4 for same problem. Go Issue: + // http://code.google.com/p/go/issues/detail?id=5252 + url := *req.URL + url.Path = p + p = url.String() + + w.Header().Set("Location", p) + w.WriteHeader(http.StatusMovedPermanently) + return + } + } + var match RouteMatch + var handler http.Handler + if r.Match(req, &match) { + handler = match.Handler + req = setVars(req, match.Vars) + req = setCurrentRoute(req, match.Route) + } + + if handler == nil && match.MatchErr == ErrMethodMismatch { + handler = methodNotAllowedHandler() + } + + if handler == nil { + handler = http.NotFoundHandler() + } + + handler.ServeHTTP(w, req) +} + +// Get returns a route registered with the given name. +func (r *Router) Get(name string) *Route { + return r.namedRoutes[name] +} + +// GetRoute returns a route registered with the given name. This method +// was renamed to Get() and remains here for backwards compatibility. +func (r *Router) GetRoute(name string) *Route { + return r.namedRoutes[name] +} + +// StrictSlash defines the trailing slash behavior for new routes. The initial +// value is false. +// +// When true, if the route path is "/path/", accessing "/path" will perform a redirect +// to the former and vice versa. In other words, your application will always +// see the path as specified in the route. +// +// When false, if the route path is "/path", accessing "/path/" will not match +// this route and vice versa. +// +// The re-direct is a HTTP 301 (Moved Permanently). Note that when this is set for +// routes with a non-idempotent method (e.g. POST, PUT), the subsequent re-directed +// request will be made as a GET by most clients. Use middleware or client settings +// to modify this behaviour as needed. +// +// Special case: when a route sets a path prefix using the PathPrefix() method, +// strict slash is ignored for that route because the redirect behavior can't +// be determined from a prefix alone. However, any subrouters created from that +// route inherit the original StrictSlash setting. +func (r *Router) StrictSlash(value bool) *Router { + r.strictSlash = value + return r +} + +// SkipClean defines the path cleaning behaviour for new routes. The initial +// value is false. Users should be careful about which routes are not cleaned +// +// When true, if the route path is "/path//to", it will remain with the double +// slash. This is helpful if you have a route like: /fetch/http://xkcd.com/534/ +// +// When false, the path will be cleaned, so /fetch/http://xkcd.com/534/ will +// become /fetch/http/xkcd.com/534 +func (r *Router) SkipClean(value bool) *Router { + r.skipClean = value + return r +} + +// UseEncodedPath tells the router to match the encoded original path +// to the routes. +// For eg. "/path/foo%2Fbar/to" will match the path "/path/{var}/to". +// +// If not called, the router will match the unencoded path to the routes. +// For eg. "/path/foo%2Fbar/to" will match the path "/path/foo/bar/to" +func (r *Router) UseEncodedPath() *Router { + r.useEncodedPath = true + return r +} + +// ---------------------------------------------------------------------------- +// Route factories +// ---------------------------------------------------------------------------- + +// NewRoute registers an empty route. +func (r *Router) NewRoute() *Route { + // initialize a route with a copy of the parent router's configuration + route := &Route{routeConf: copyRouteConf(r.routeConf), namedRoutes: r.namedRoutes} + r.routes = append(r.routes, route) + return route +} + +// Name registers a new route with a name. +// See Route.Name(). +func (r *Router) Name(name string) *Route { + return r.NewRoute().Name(name) +} + +// Handle registers a new route with a matcher for the URL path. +// See Route.Path() and Route.Handler(). +func (r *Router) Handle(path string, handler http.Handler) *Route { + return r.NewRoute().Path(path).Handler(handler) +} + +// HandleFunc registers a new route with a matcher for the URL path. +// See Route.Path() and Route.HandlerFunc(). +func (r *Router) HandleFunc(path string, f func(http.ResponseWriter, + *http.Request)) *Route { + return r.NewRoute().Path(path).HandlerFunc(f) +} + +// Headers registers a new route with a matcher for request header values. +// See Route.Headers(). +func (r *Router) Headers(pairs ...string) *Route { + return r.NewRoute().Headers(pairs...) +} + +// Host registers a new route with a matcher for the URL host. +// See Route.Host(). +func (r *Router) Host(tpl string) *Route { + return r.NewRoute().Host(tpl) +} + +// MatcherFunc registers a new route with a custom matcher function. +// See Route.MatcherFunc(). +func (r *Router) MatcherFunc(f MatcherFunc) *Route { + return r.NewRoute().MatcherFunc(f) +} + +// Methods registers a new route with a matcher for HTTP methods. +// See Route.Methods(). +func (r *Router) Methods(methods ...string) *Route { + return r.NewRoute().Methods(methods...) +} + +// Path registers a new route with a matcher for the URL path. +// See Route.Path(). +func (r *Router) Path(tpl string) *Route { + return r.NewRoute().Path(tpl) +} + +// PathPrefix registers a new route with a matcher for the URL path prefix. +// See Route.PathPrefix(). +func (r *Router) PathPrefix(tpl string) *Route { + return r.NewRoute().PathPrefix(tpl) +} + +// Queries registers a new route with a matcher for URL query values. +// See Route.Queries(). +func (r *Router) Queries(pairs ...string) *Route { + return r.NewRoute().Queries(pairs...) +} + +// Schemes registers a new route with a matcher for URL schemes. +// See Route.Schemes(). +func (r *Router) Schemes(schemes ...string) *Route { + return r.NewRoute().Schemes(schemes...) +} + +// BuildVarsFunc registers a new route with a custom function for modifying +// route variables before building a URL. +func (r *Router) BuildVarsFunc(f BuildVarsFunc) *Route { + return r.NewRoute().BuildVarsFunc(f) +} + +// Walk walks the router and all its sub-routers, calling walkFn for each route +// in the tree. The routes are walked in the order they were added. Sub-routers +// are explored depth-first. +func (r *Router) Walk(walkFn WalkFunc) error { + return r.walk(walkFn, []*Route{}) +} + +// SkipRouter is used as a return value from WalkFuncs to indicate that the +// router that walk is about to descend down to should be skipped. +var SkipRouter = errors.New("skip this router") + +// WalkFunc is the type of the function called for each route visited by Walk. +// At every invocation, it is given the current route, and the current router, +// and a list of ancestor routes that lead to the current route. +type WalkFunc func(route *Route, router *Router, ancestors []*Route) error + +func (r *Router) walk(walkFn WalkFunc, ancestors []*Route) error { + for _, t := range r.routes { + err := walkFn(t, r, ancestors) + if err == SkipRouter { + continue + } + if err != nil { + return err + } + for _, sr := range t.matchers { + if h, ok := sr.(*Router); ok { + ancestors = append(ancestors, t) + err := h.walk(walkFn, ancestors) + if err != nil { + return err + } + ancestors = ancestors[:len(ancestors)-1] + } + } + if h, ok := t.handler.(*Router); ok { + ancestors = append(ancestors, t) + err := h.walk(walkFn, ancestors) + if err != nil { + return err + } + ancestors = ancestors[:len(ancestors)-1] + } + } + return nil +} + +// ---------------------------------------------------------------------------- +// Context +// ---------------------------------------------------------------------------- + +// RouteMatch stores information about a matched route. +type RouteMatch struct { + Route *Route + Handler http.Handler + Vars map[string]string + + // MatchErr is set to appropriate matching error + // It is set to ErrMethodMismatch if there is a mismatch in + // the request method and route method + MatchErr error +} + +type contextKey int + +const ( + varsKey contextKey = iota + routeKey +) + +// Vars returns the route variables for the current request, if any. +func Vars(r *http.Request) map[string]string { + if rv := contextGet(r, varsKey); rv != nil { + return rv.(map[string]string) + } + return nil +} + +// CurrentRoute returns the matched route for the current request, if any. +// This only works when called inside the handler of the matched route +// because the matched route is stored in the request context which is cleared +// after the handler returns, unless the KeepContext option is set on the +// Router. +func CurrentRoute(r *http.Request) *Route { + if rv := contextGet(r, routeKey); rv != nil { + return rv.(*Route) + } + return nil +} + +func setVars(r *http.Request, val interface{}) *http.Request { + return contextSet(r, varsKey, val) +} + +func setCurrentRoute(r *http.Request, val interface{}) *http.Request { + return contextSet(r, routeKey, val) +} + +// ---------------------------------------------------------------------------- +// Helpers +// ---------------------------------------------------------------------------- + +// cleanPath returns the canonical path for p, eliminating . and .. elements. +// Borrowed from the net/http package. +func cleanPath(p string) string { + if p == "" { + return "/" + } + if p[0] != '/' { + p = "/" + p + } + np := path.Clean(p) + // path.Clean removes trailing slash except for root; + // put the trailing slash back if necessary. + if p[len(p)-1] == '/' && np != "/" { + np += "/" + } + + return np +} + +// uniqueVars returns an error if two slices contain duplicated strings. +func uniqueVars(s1, s2 []string) error { + for _, v1 := range s1 { + for _, v2 := range s2 { + if v1 == v2 { + return fmt.Errorf("mux: duplicated route variable %q", v2) + } + } + } + return nil +} + +// checkPairs returns the count of strings passed in, and an error if +// the count is not an even number. +func checkPairs(pairs ...string) (int, error) { + length := len(pairs) + if length%2 != 0 { + return length, fmt.Errorf( + "mux: number of parameters must be multiple of 2, got %v", pairs) + } + return length, nil +} + +// mapFromPairsToString converts variadic string parameters to a +// string to string map. +func mapFromPairsToString(pairs ...string) (map[string]string, error) { + length, err := checkPairs(pairs...) + if err != nil { + return nil, err + } + m := make(map[string]string, length/2) + for i := 0; i < length; i += 2 { + m[pairs[i]] = pairs[i+1] + } + return m, nil +} + +// mapFromPairsToRegex converts variadic string parameters to a +// string to regex map. +func mapFromPairsToRegex(pairs ...string) (map[string]*regexp.Regexp, error) { + length, err := checkPairs(pairs...) + if err != nil { + return nil, err + } + m := make(map[string]*regexp.Regexp, length/2) + for i := 0; i < length; i += 2 { + regex, err := regexp.Compile(pairs[i+1]) + if err != nil { + return nil, err + } + m[pairs[i]] = regex + } + return m, nil +} + +// matchInArray returns true if the given string value is in the array. +func matchInArray(arr []string, value string) bool { + for _, v := range arr { + if v == value { + return true + } + } + return false +} + +// matchMapWithString returns true if the given key/value pairs exist in a given map. +func matchMapWithString(toCheck map[string]string, toMatch map[string][]string, canonicalKey bool) bool { + for k, v := range toCheck { + // Check if key exists. + if canonicalKey { + k = http.CanonicalHeaderKey(k) + } + if values := toMatch[k]; values == nil { + return false + } else if v != "" { + // If value was defined as an empty string we only check that the + // key exists. Otherwise we also check for equality. + valueExists := false + for _, value := range values { + if v == value { + valueExists = true + break + } + } + if !valueExists { + return false + } + } + } + return true +} + +// matchMapWithRegex returns true if the given key/value pairs exist in a given map compiled against +// the given regex +func matchMapWithRegex(toCheck map[string]*regexp.Regexp, toMatch map[string][]string, canonicalKey bool) bool { + for k, v := range toCheck { + // Check if key exists. + if canonicalKey { + k = http.CanonicalHeaderKey(k) + } + if values := toMatch[k]; values == nil { + return false + } else if v != nil { + // If value was defined as an empty string we only check that the + // key exists. Otherwise we also check for equality. + valueExists := false + for _, value := range values { + if v.MatchString(value) { + valueExists = true + break + } + } + if !valueExists { + return false + } + } + } + return true +} + +// methodNotAllowed replies to the request with an HTTP status code 405. +func methodNotAllowed(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusMethodNotAllowed) +} + +// methodNotAllowedHandler returns a simple request handler +// that replies to each request with a status code 405. +func methodNotAllowedHandler() http.Handler { return http.HandlerFunc(methodNotAllowed) } diff --git a/vendor/github.com/gorilla/mux/regexp.go b/vendor/github.com/gorilla/mux/regexp.go new file mode 100644 index 00000000..ac1abcd4 --- /dev/null +++ b/vendor/github.com/gorilla/mux/regexp.go @@ -0,0 +1,345 @@ +// Copyright 2012 The Gorilla Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mux + +import ( + "bytes" + "fmt" + "net/http" + "net/url" + "regexp" + "strconv" + "strings" +) + +type routeRegexpOptions struct { + strictSlash bool + useEncodedPath bool +} + +type regexpType int + +const ( + regexpTypePath regexpType = 0 + regexpTypeHost regexpType = 1 + regexpTypePrefix regexpType = 2 + regexpTypeQuery regexpType = 3 +) + +// newRouteRegexp parses a route template and returns a routeRegexp, +// used to match a host, a path or a query string. +// +// It will extract named variables, assemble a regexp to be matched, create +// a "reverse" template to build URLs and compile regexps to validate variable +// values used in URL building. +// +// Previously we accepted only Python-like identifiers for variable +// names ([a-zA-Z_][a-zA-Z0-9_]*), but currently the only restriction is that +// name and pattern can't be empty, and names can't contain a colon. +func newRouteRegexp(tpl string, typ regexpType, options routeRegexpOptions) (*routeRegexp, error) { + // Check if it is well-formed. + idxs, errBraces := braceIndices(tpl) + if errBraces != nil { + return nil, errBraces + } + // Backup the original. + template := tpl + // Now let's parse it. + defaultPattern := "[^/]+" + if typ == regexpTypeQuery { + defaultPattern = ".*" + } else if typ == regexpTypeHost { + defaultPattern = "[^.]+" + } + // Only match strict slash if not matching + if typ != regexpTypePath { + options.strictSlash = false + } + // Set a flag for strictSlash. + endSlash := false + if options.strictSlash && strings.HasSuffix(tpl, "/") { + tpl = tpl[:len(tpl)-1] + endSlash = true + } + varsN := make([]string, len(idxs)/2) + varsR := make([]*regexp.Regexp, len(idxs)/2) + pattern := bytes.NewBufferString("") + pattern.WriteByte('^') + reverse := bytes.NewBufferString("") + var end int + var err error + for i := 0; i < len(idxs); i += 2 { + // Set all values we are interested in. + raw := tpl[end:idxs[i]] + end = idxs[i+1] + parts := strings.SplitN(tpl[idxs[i]+1:end-1], ":", 2) + name := parts[0] + patt := defaultPattern + if len(parts) == 2 { + patt = parts[1] + } + // Name or pattern can't be empty. + if name == "" || patt == "" { + return nil, fmt.Errorf("mux: missing name or pattern in %q", + tpl[idxs[i]:end]) + } + // Build the regexp pattern. + fmt.Fprintf(pattern, "%s(?P<%s>%s)", regexp.QuoteMeta(raw), varGroupName(i/2), patt) + + // Build the reverse template. + fmt.Fprintf(reverse, "%s%%s", raw) + + // Append variable name and compiled pattern. + varsN[i/2] = name + varsR[i/2], err = regexp.Compile(fmt.Sprintf("^%s$", patt)) + if err != nil { + return nil, err + } + } + // Add the remaining. + raw := tpl[end:] + pattern.WriteString(regexp.QuoteMeta(raw)) + if options.strictSlash { + pattern.WriteString("[/]?") + } + if typ == regexpTypeQuery { + // Add the default pattern if the query value is empty + if queryVal := strings.SplitN(template, "=", 2)[1]; queryVal == "" { + pattern.WriteString(defaultPattern) + } + } + if typ != regexpTypePrefix { + pattern.WriteByte('$') + } + + var wildcardHostPort bool + if typ == regexpTypeHost { + if !strings.Contains(pattern.String(), ":") { + wildcardHostPort = true + } + } + reverse.WriteString(raw) + if endSlash { + reverse.WriteByte('/') + } + // Compile full regexp. + reg, errCompile := regexp.Compile(pattern.String()) + if errCompile != nil { + return nil, errCompile + } + + // Check for capturing groups which used to work in older versions + if reg.NumSubexp() != len(idxs)/2 { + panic(fmt.Sprintf("route %s contains capture groups in its regexp. ", template) + + "Only non-capturing groups are accepted: e.g. (?:pattern) instead of (pattern)") + } + + // Done! + return &routeRegexp{ + template: template, + regexpType: typ, + options: options, + regexp: reg, + reverse: reverse.String(), + varsN: varsN, + varsR: varsR, + wildcardHostPort: wildcardHostPort, + }, nil +} + +// routeRegexp stores a regexp to match a host or path and information to +// collect and validate route variables. +type routeRegexp struct { + // The unmodified template. + template string + // The type of match + regexpType regexpType + // Options for matching + options routeRegexpOptions + // Expanded regexp. + regexp *regexp.Regexp + // Reverse template. + reverse string + // Variable names. + varsN []string + // Variable regexps (validators). + varsR []*regexp.Regexp + // Wildcard host-port (no strict port match in hostname) + wildcardHostPort bool +} + +// Match matches the regexp against the URL host or path. +func (r *routeRegexp) Match(req *http.Request, match *RouteMatch) bool { + if r.regexpType == regexpTypeHost { + host := getHost(req) + if r.wildcardHostPort { + // Don't be strict on the port match + if i := strings.Index(host, ":"); i != -1 { + host = host[:i] + } + } + return r.regexp.MatchString(host) + } else { + if r.regexpType == regexpTypeQuery { + return r.matchQueryString(req) + } + path := req.URL.Path + if r.options.useEncodedPath { + path = req.URL.EscapedPath() + } + return r.regexp.MatchString(path) + } +} + +// url builds a URL part using the given values. +func (r *routeRegexp) url(values map[string]string) (string, error) { + urlValues := make([]interface{}, len(r.varsN)) + for k, v := range r.varsN { + value, ok := values[v] + if !ok { + return "", fmt.Errorf("mux: missing route variable %q", v) + } + if r.regexpType == regexpTypeQuery { + value = url.QueryEscape(value) + } + urlValues[k] = value + } + rv := fmt.Sprintf(r.reverse, urlValues...) + if !r.regexp.MatchString(rv) { + // The URL is checked against the full regexp, instead of checking + // individual variables. This is faster but to provide a good error + // message, we check individual regexps if the URL doesn't match. + for k, v := range r.varsN { + if !r.varsR[k].MatchString(values[v]) { + return "", fmt.Errorf( + "mux: variable %q doesn't match, expected %q", values[v], + r.varsR[k].String()) + } + } + } + return rv, nil +} + +// getURLQuery returns a single query parameter from a request URL. +// For a URL with foo=bar&baz=ding, we return only the relevant key +// value pair for the routeRegexp. +func (r *routeRegexp) getURLQuery(req *http.Request) string { + if r.regexpType != regexpTypeQuery { + return "" + } + templateKey := strings.SplitN(r.template, "=", 2)[0] + for key, vals := range req.URL.Query() { + if key == templateKey && len(vals) > 0 { + return key + "=" + vals[0] + } + } + return "" +} + +func (r *routeRegexp) matchQueryString(req *http.Request) bool { + return r.regexp.MatchString(r.getURLQuery(req)) +} + +// braceIndices returns the first level curly brace indices from a string. +// It returns an error in case of unbalanced braces. +func braceIndices(s string) ([]int, error) { + var level, idx int + var idxs []int + for i := 0; i < len(s); i++ { + switch s[i] { + case '{': + if level++; level == 1 { + idx = i + } + case '}': + if level--; level == 0 { + idxs = append(idxs, idx, i+1) + } else if level < 0 { + return nil, fmt.Errorf("mux: unbalanced braces in %q", s) + } + } + } + if level != 0 { + return nil, fmt.Errorf("mux: unbalanced braces in %q", s) + } + return idxs, nil +} + +// varGroupName builds a capturing group name for the indexed variable. +func varGroupName(idx int) string { + return "v" + strconv.Itoa(idx) +} + +// ---------------------------------------------------------------------------- +// routeRegexpGroup +// ---------------------------------------------------------------------------- + +// routeRegexpGroup groups the route matchers that carry variables. +type routeRegexpGroup struct { + host *routeRegexp + path *routeRegexp + queries []*routeRegexp +} + +// setMatch extracts the variables from the URL once a route matches. +func (v routeRegexpGroup) setMatch(req *http.Request, m *RouteMatch, r *Route) { + // Store host variables. + if v.host != nil { + host := getHost(req) + matches := v.host.regexp.FindStringSubmatchIndex(host) + if len(matches) > 0 { + extractVars(host, matches, v.host.varsN, m.Vars) + } + } + path := req.URL.Path + if r.useEncodedPath { + path = req.URL.EscapedPath() + } + // Store path variables. + if v.path != nil { + matches := v.path.regexp.FindStringSubmatchIndex(path) + if len(matches) > 0 { + extractVars(path, matches, v.path.varsN, m.Vars) + // Check if we should redirect. + if v.path.options.strictSlash { + p1 := strings.HasSuffix(path, "/") + p2 := strings.HasSuffix(v.path.template, "/") + if p1 != p2 { + u, _ := url.Parse(req.URL.String()) + if p1 { + u.Path = u.Path[:len(u.Path)-1] + } else { + u.Path += "/" + } + m.Handler = http.RedirectHandler(u.String(), http.StatusMovedPermanently) + } + } + } + } + // Store query string variables. + for _, q := range v.queries { + queryURL := q.getURLQuery(req) + matches := q.regexp.FindStringSubmatchIndex(queryURL) + if len(matches) > 0 { + extractVars(queryURL, matches, q.varsN, m.Vars) + } + } +} + +// getHost tries its best to return the request host. +// According to section 14.23 of RFC 2616 the Host header +// can include the port number if the default value of 80 is not used. +func getHost(r *http.Request) string { + if r.URL.IsAbs() { + return r.URL.Host + } + return r.Host +} + +func extractVars(input string, matches []int, names []string, output map[string]string) { + for i, name := range names { + output[name] = input[matches[2*i+2]:matches[2*i+3]] + } +} diff --git a/vendor/github.com/gorilla/mux/route.go b/vendor/github.com/gorilla/mux/route.go new file mode 100644 index 00000000..8479c68c --- /dev/null +++ b/vendor/github.com/gorilla/mux/route.go @@ -0,0 +1,710 @@ +// Copyright 2012 The Gorilla Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mux + +import ( + "errors" + "fmt" + "net/http" + "net/url" + "regexp" + "strings" +) + +// Route stores information to match a request and build URLs. +type Route struct { + // Request handler for the route. + handler http.Handler + // If true, this route never matches: it is only used to build URLs. + buildOnly bool + // The name used to build URLs. + name string + // Error resulted from building a route. + err error + + // "global" reference to all named routes + namedRoutes map[string]*Route + + // config possibly passed in from `Router` + routeConf +} + +// SkipClean reports whether path cleaning is enabled for this route via +// Router.SkipClean. +func (r *Route) SkipClean() bool { + return r.skipClean +} + +// Match matches the route against the request. +func (r *Route) Match(req *http.Request, match *RouteMatch) bool { + if r.buildOnly || r.err != nil { + return false + } + + var matchErr error + + // Match everything. + for _, m := range r.matchers { + if matched := m.Match(req, match); !matched { + if _, ok := m.(methodMatcher); ok { + matchErr = ErrMethodMismatch + continue + } + + // Ignore ErrNotFound errors. These errors arise from match call + // to Subrouters. + // + // This prevents subsequent matching subrouters from failing to + // run middleware. If not ignored, the middleware would see a + // non-nil MatchErr and be skipped, even when there was a + // matching route. + if match.MatchErr == ErrNotFound { + match.MatchErr = nil + } + + matchErr = nil + return false + } + } + + if matchErr != nil { + match.MatchErr = matchErr + return false + } + + if match.MatchErr == ErrMethodMismatch { + // We found a route which matches request method, clear MatchErr + match.MatchErr = nil + // Then override the mis-matched handler + match.Handler = r.handler + } + + // Yay, we have a match. Let's collect some info about it. + if match.Route == nil { + match.Route = r + } + if match.Handler == nil { + match.Handler = r.handler + } + if match.Vars == nil { + match.Vars = make(map[string]string) + } + + // Set variables. + r.regexp.setMatch(req, match, r) + return true +} + +// ---------------------------------------------------------------------------- +// Route attributes +// ---------------------------------------------------------------------------- + +// GetError returns an error resulted from building the route, if any. +func (r *Route) GetError() error { + return r.err +} + +// BuildOnly sets the route to never match: it is only used to build URLs. +func (r *Route) BuildOnly() *Route { + r.buildOnly = true + return r +} + +// Handler -------------------------------------------------------------------- + +// Handler sets a handler for the route. +func (r *Route) Handler(handler http.Handler) *Route { + if r.err == nil { + r.handler = handler + } + return r +} + +// HandlerFunc sets a handler function for the route. +func (r *Route) HandlerFunc(f func(http.ResponseWriter, *http.Request)) *Route { + return r.Handler(http.HandlerFunc(f)) +} + +// GetHandler returns the handler for the route, if any. +func (r *Route) GetHandler() http.Handler { + return r.handler +} + +// Name ----------------------------------------------------------------------- + +// Name sets the name for the route, used to build URLs. +// It is an error to call Name more than once on a route. +func (r *Route) Name(name string) *Route { + if r.name != "" { + r.err = fmt.Errorf("mux: route already has name %q, can't set %q", + r.name, name) + } + if r.err == nil { + r.name = name + r.namedRoutes[name] = r + } + return r +} + +// GetName returns the name for the route, if any. +func (r *Route) GetName() string { + return r.name +} + +// ---------------------------------------------------------------------------- +// Matchers +// ---------------------------------------------------------------------------- + +// matcher types try to match a request. +type matcher interface { + Match(*http.Request, *RouteMatch) bool +} + +// addMatcher adds a matcher to the route. +func (r *Route) addMatcher(m matcher) *Route { + if r.err == nil { + r.matchers = append(r.matchers, m) + } + return r +} + +// addRegexpMatcher adds a host or path matcher and builder to a route. +func (r *Route) addRegexpMatcher(tpl string, typ regexpType) error { + if r.err != nil { + return r.err + } + if typ == regexpTypePath || typ == regexpTypePrefix { + if len(tpl) > 0 && tpl[0] != '/' { + return fmt.Errorf("mux: path must start with a slash, got %q", tpl) + } + if r.regexp.path != nil { + tpl = strings.TrimRight(r.regexp.path.template, "/") + tpl + } + } + rr, err := newRouteRegexp(tpl, typ, routeRegexpOptions{ + strictSlash: r.strictSlash, + useEncodedPath: r.useEncodedPath, + }) + if err != nil { + return err + } + for _, q := range r.regexp.queries { + if err = uniqueVars(rr.varsN, q.varsN); err != nil { + return err + } + } + if typ == regexpTypeHost { + if r.regexp.path != nil { + if err = uniqueVars(rr.varsN, r.regexp.path.varsN); err != nil { + return err + } + } + r.regexp.host = rr + } else { + if r.regexp.host != nil { + if err = uniqueVars(rr.varsN, r.regexp.host.varsN); err != nil { + return err + } + } + if typ == regexpTypeQuery { + r.regexp.queries = append(r.regexp.queries, rr) + } else { + r.regexp.path = rr + } + } + r.addMatcher(rr) + return nil +} + +// Headers -------------------------------------------------------------------- + +// headerMatcher matches the request against header values. +type headerMatcher map[string]string + +func (m headerMatcher) Match(r *http.Request, match *RouteMatch) bool { + return matchMapWithString(m, r.Header, true) +} + +// Headers adds a matcher for request header values. +// It accepts a sequence of key/value pairs to be matched. For example: +// +// r := mux.NewRouter() +// r.Headers("Content-Type", "application/json", +// "X-Requested-With", "XMLHttpRequest") +// +// The above route will only match if both request header values match. +// If the value is an empty string, it will match any value if the key is set. +func (r *Route) Headers(pairs ...string) *Route { + if r.err == nil { + var headers map[string]string + headers, r.err = mapFromPairsToString(pairs...) + return r.addMatcher(headerMatcher(headers)) + } + return r +} + +// headerRegexMatcher matches the request against the route given a regex for the header +type headerRegexMatcher map[string]*regexp.Regexp + +func (m headerRegexMatcher) Match(r *http.Request, match *RouteMatch) bool { + return matchMapWithRegex(m, r.Header, true) +} + +// HeadersRegexp accepts a sequence of key/value pairs, where the value has regex +// support. For example: +// +// r := mux.NewRouter() +// r.HeadersRegexp("Content-Type", "application/(text|json)", +// "X-Requested-With", "XMLHttpRequest") +// +// The above route will only match if both the request header matches both regular expressions. +// If the value is an empty string, it will match any value if the key is set. +// Use the start and end of string anchors (^ and $) to match an exact value. +func (r *Route) HeadersRegexp(pairs ...string) *Route { + if r.err == nil { + var headers map[string]*regexp.Regexp + headers, r.err = mapFromPairsToRegex(pairs...) + return r.addMatcher(headerRegexMatcher(headers)) + } + return r +} + +// Host ----------------------------------------------------------------------- + +// Host adds a matcher for the URL host. +// It accepts a template with zero or more URL variables enclosed by {}. +// Variables can define an optional regexp pattern to be matched: +// +// - {name} matches anything until the next dot. +// +// - {name:pattern} matches the given regexp pattern. +// +// For example: +// +// r := mux.NewRouter() +// r.Host("www.example.com") +// r.Host("{subdomain}.domain.com") +// r.Host("{subdomain:[a-z]+}.domain.com") +// +// Variable names must be unique in a given route. They can be retrieved +// calling mux.Vars(request). +func (r *Route) Host(tpl string) *Route { + r.err = r.addRegexpMatcher(tpl, regexpTypeHost) + return r +} + +// MatcherFunc ---------------------------------------------------------------- + +// MatcherFunc is the function signature used by custom matchers. +type MatcherFunc func(*http.Request, *RouteMatch) bool + +// Match returns the match for a given request. +func (m MatcherFunc) Match(r *http.Request, match *RouteMatch) bool { + return m(r, match) +} + +// MatcherFunc adds a custom function to be used as request matcher. +func (r *Route) MatcherFunc(f MatcherFunc) *Route { + return r.addMatcher(f) +} + +// Methods -------------------------------------------------------------------- + +// methodMatcher matches the request against HTTP methods. +type methodMatcher []string + +func (m methodMatcher) Match(r *http.Request, match *RouteMatch) bool { + return matchInArray(m, r.Method) +} + +// Methods adds a matcher for HTTP methods. +// It accepts a sequence of one or more methods to be matched, e.g.: +// "GET", "POST", "PUT". +func (r *Route) Methods(methods ...string) *Route { + for k, v := range methods { + methods[k] = strings.ToUpper(v) + } + return r.addMatcher(methodMatcher(methods)) +} + +// Path ----------------------------------------------------------------------- + +// Path adds a matcher for the URL path. +// It accepts a template with zero or more URL variables enclosed by {}. The +// template must start with a "/". +// Variables can define an optional regexp pattern to be matched: +// +// - {name} matches anything until the next slash. +// +// - {name:pattern} matches the given regexp pattern. +// +// For example: +// +// r := mux.NewRouter() +// r.Path("/products/").Handler(ProductsHandler) +// r.Path("/products/{key}").Handler(ProductsHandler) +// r.Path("/articles/{category}/{id:[0-9]+}"). +// Handler(ArticleHandler) +// +// Variable names must be unique in a given route. They can be retrieved +// calling mux.Vars(request). +func (r *Route) Path(tpl string) *Route { + r.err = r.addRegexpMatcher(tpl, regexpTypePath) + return r +} + +// PathPrefix ----------------------------------------------------------------- + +// PathPrefix adds a matcher for the URL path prefix. This matches if the given +// template is a prefix of the full URL path. See Route.Path() for details on +// the tpl argument. +// +// Note that it does not treat slashes specially ("/foobar/" will be matched by +// the prefix "/foo") so you may want to use a trailing slash here. +// +// Also note that the setting of Router.StrictSlash() has no effect on routes +// with a PathPrefix matcher. +func (r *Route) PathPrefix(tpl string) *Route { + r.err = r.addRegexpMatcher(tpl, regexpTypePrefix) + return r +} + +// Query ---------------------------------------------------------------------- + +// Queries adds a matcher for URL query values. +// It accepts a sequence of key/value pairs. Values may define variables. +// For example: +// +// r := mux.NewRouter() +// r.Queries("foo", "bar", "id", "{id:[0-9]+}") +// +// The above route will only match if the URL contains the defined queries +// values, e.g.: ?foo=bar&id=42. +// +// If the value is an empty string, it will match any value if the key is set. +// +// Variables can define an optional regexp pattern to be matched: +// +// - {name} matches anything until the next slash. +// +// - {name:pattern} matches the given regexp pattern. +func (r *Route) Queries(pairs ...string) *Route { + length := len(pairs) + if length%2 != 0 { + r.err = fmt.Errorf( + "mux: number of parameters must be multiple of 2, got %v", pairs) + return nil + } + for i := 0; i < length; i += 2 { + if r.err = r.addRegexpMatcher(pairs[i]+"="+pairs[i+1], regexpTypeQuery); r.err != nil { + return r + } + } + + return r +} + +// Schemes -------------------------------------------------------------------- + +// schemeMatcher matches the request against URL schemes. +type schemeMatcher []string + +func (m schemeMatcher) Match(r *http.Request, match *RouteMatch) bool { + return matchInArray(m, r.URL.Scheme) +} + +// Schemes adds a matcher for URL schemes. +// It accepts a sequence of schemes to be matched, e.g.: "http", "https". +func (r *Route) Schemes(schemes ...string) *Route { + for k, v := range schemes { + schemes[k] = strings.ToLower(v) + } + if len(schemes) > 0 { + r.buildScheme = schemes[0] + } + return r.addMatcher(schemeMatcher(schemes)) +} + +// BuildVarsFunc -------------------------------------------------------------- + +// BuildVarsFunc is the function signature used by custom build variable +// functions (which can modify route variables before a route's URL is built). +type BuildVarsFunc func(map[string]string) map[string]string + +// BuildVarsFunc adds a custom function to be used to modify build variables +// before a route's URL is built. +func (r *Route) BuildVarsFunc(f BuildVarsFunc) *Route { + if r.buildVarsFunc != nil { + // compose the old and new functions + old := r.buildVarsFunc + r.buildVarsFunc = func(m map[string]string) map[string]string { + return f(old(m)) + } + } else { + r.buildVarsFunc = f + } + return r +} + +// Subrouter ------------------------------------------------------------------ + +// Subrouter creates a subrouter for the route. +// +// It will test the inner routes only if the parent route matched. For example: +// +// r := mux.NewRouter() +// s := r.Host("www.example.com").Subrouter() +// s.HandleFunc("/products/", ProductsHandler) +// s.HandleFunc("/products/{key}", ProductHandler) +// s.HandleFunc("/articles/{category}/{id:[0-9]+}"), ArticleHandler) +// +// Here, the routes registered in the subrouter won't be tested if the host +// doesn't match. +func (r *Route) Subrouter() *Router { + // initialize a subrouter with a copy of the parent route's configuration + router := &Router{routeConf: copyRouteConf(r.routeConf), namedRoutes: r.namedRoutes} + r.addMatcher(router) + return router +} + +// ---------------------------------------------------------------------------- +// URL building +// ---------------------------------------------------------------------------- + +// URL builds a URL for the route. +// +// It accepts a sequence of key/value pairs for the route variables. For +// example, given this route: +// +// r := mux.NewRouter() +// r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). +// Name("article") +// +// ...a URL for it can be built using: +// +// url, err := r.Get("article").URL("category", "technology", "id", "42") +// +// ...which will return an url.URL with the following path: +// +// "/articles/technology/42" +// +// This also works for host variables: +// +// r := mux.NewRouter() +// r.Host("{subdomain}.domain.com"). +// HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler). +// Name("article") +// +// // url.String() will be "http://news.domain.com/articles/technology/42" +// url, err := r.Get("article").URL("subdomain", "news", +// "category", "technology", +// "id", "42") +// +// All variables defined in the route are required, and their values must +// conform to the corresponding patterns. +func (r *Route) URL(pairs ...string) (*url.URL, error) { + if r.err != nil { + return nil, r.err + } + values, err := r.prepareVars(pairs...) + if err != nil { + return nil, err + } + var scheme, host, path string + queries := make([]string, 0, len(r.regexp.queries)) + if r.regexp.host != nil { + if host, err = r.regexp.host.url(values); err != nil { + return nil, err + } + scheme = "http" + if r.buildScheme != "" { + scheme = r.buildScheme + } + } + if r.regexp.path != nil { + if path, err = r.regexp.path.url(values); err != nil { + return nil, err + } + } + for _, q := range r.regexp.queries { + var query string + if query, err = q.url(values); err != nil { + return nil, err + } + queries = append(queries, query) + } + return &url.URL{ + Scheme: scheme, + Host: host, + Path: path, + RawQuery: strings.Join(queries, "&"), + }, nil +} + +// URLHost builds the host part of the URL for a route. See Route.URL(). +// +// The route must have a host defined. +func (r *Route) URLHost(pairs ...string) (*url.URL, error) { + if r.err != nil { + return nil, r.err + } + if r.regexp.host == nil { + return nil, errors.New("mux: route doesn't have a host") + } + values, err := r.prepareVars(pairs...) + if err != nil { + return nil, err + } + host, err := r.regexp.host.url(values) + if err != nil { + return nil, err + } + u := &url.URL{ + Scheme: "http", + Host: host, + } + if r.buildScheme != "" { + u.Scheme = r.buildScheme + } + return u, nil +} + +// URLPath builds the path part of the URL for a route. See Route.URL(). +// +// The route must have a path defined. +func (r *Route) URLPath(pairs ...string) (*url.URL, error) { + if r.err != nil { + return nil, r.err + } + if r.regexp.path == nil { + return nil, errors.New("mux: route doesn't have a path") + } + values, err := r.prepareVars(pairs...) + if err != nil { + return nil, err + } + path, err := r.regexp.path.url(values) + if err != nil { + return nil, err + } + return &url.URL{ + Path: path, + }, nil +} + +// GetPathTemplate returns the template used to build the +// route match. +// This is useful for building simple REST API documentation and for instrumentation +// against third-party services. +// An error will be returned if the route does not define a path. +func (r *Route) GetPathTemplate() (string, error) { + if r.err != nil { + return "", r.err + } + if r.regexp.path == nil { + return "", errors.New("mux: route doesn't have a path") + } + return r.regexp.path.template, nil +} + +// GetPathRegexp returns the expanded regular expression used to match route path. +// This is useful for building simple REST API documentation and for instrumentation +// against third-party services. +// An error will be returned if the route does not define a path. +func (r *Route) GetPathRegexp() (string, error) { + if r.err != nil { + return "", r.err + } + if r.regexp.path == nil { + return "", errors.New("mux: route does not have a path") + } + return r.regexp.path.regexp.String(), nil +} + +// GetQueriesRegexp returns the expanded regular expressions used to match the +// route queries. +// This is useful for building simple REST API documentation and for instrumentation +// against third-party services. +// An error will be returned if the route does not have queries. +func (r *Route) GetQueriesRegexp() ([]string, error) { + if r.err != nil { + return nil, r.err + } + if r.regexp.queries == nil { + return nil, errors.New("mux: route doesn't have queries") + } + var queries []string + for _, query := range r.regexp.queries { + queries = append(queries, query.regexp.String()) + } + return queries, nil +} + +// GetQueriesTemplates returns the templates used to build the +// query matching. +// This is useful for building simple REST API documentation and for instrumentation +// against third-party services. +// An error will be returned if the route does not define queries. +func (r *Route) GetQueriesTemplates() ([]string, error) { + if r.err != nil { + return nil, r.err + } + if r.regexp.queries == nil { + return nil, errors.New("mux: route doesn't have queries") + } + var queries []string + for _, query := range r.regexp.queries { + queries = append(queries, query.template) + } + return queries, nil +} + +// GetMethods returns the methods the route matches against +// This is useful for building simple REST API documentation and for instrumentation +// against third-party services. +// An error will be returned if route does not have methods. +func (r *Route) GetMethods() ([]string, error) { + if r.err != nil { + return nil, r.err + } + for _, m := range r.matchers { + if methods, ok := m.(methodMatcher); ok { + return []string(methods), nil + } + } + return nil, errors.New("mux: route doesn't have methods") +} + +// GetHostTemplate returns the template used to build the +// route match. +// This is useful for building simple REST API documentation and for instrumentation +// against third-party services. +// An error will be returned if the route does not define a host. +func (r *Route) GetHostTemplate() (string, error) { + if r.err != nil { + return "", r.err + } + if r.regexp.host == nil { + return "", errors.New("mux: route doesn't have a host") + } + return r.regexp.host.template, nil +} + +// prepareVars converts the route variable pairs into a map. If the route has a +// BuildVarsFunc, it is invoked. +func (r *Route) prepareVars(pairs ...string) (map[string]string, error) { + m, err := mapFromPairsToString(pairs...) + if err != nil { + return nil, err + } + return r.buildVars(m), nil +} + +func (r *Route) buildVars(m map[string]string) map[string]string { + if r.buildVarsFunc != nil { + m = r.buildVarsFunc(m) + } + return m +} diff --git a/vendor/github.com/gorilla/mux/test_helpers.go b/vendor/github.com/gorilla/mux/test_helpers.go new file mode 100644 index 00000000..32ecffde --- /dev/null +++ b/vendor/github.com/gorilla/mux/test_helpers.go @@ -0,0 +1,19 @@ +// Copyright 2012 The Gorilla Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package mux + +import "net/http" + +// SetURLVars sets the URL variables for the given request, to be accessed via +// mux.Vars for testing route behaviour. Arguments are not modified, a shallow +// copy is returned. +// +// This API should only be used for testing purposes; it provides a way to +// inject variables into the request context. Alternatively, URL variables +// can be set by making a route that captures the required variables, +// starting a server and sending the request to that server. +func SetURLVars(r *http.Request, val map[string]string) *http.Request { + return setVars(r, val) +} diff --git a/vendor/github.com/hashicorp/go-version/.travis.yml b/vendor/github.com/hashicorp/go-version/.travis.yml index 3f45b1e8..01c5dc21 100644 --- a/vendor/github.com/hashicorp/go-version/.travis.yml +++ b/vendor/github.com/hashicorp/go-version/.travis.yml @@ -1,12 +1,13 @@ language: go go: - - 1.0 - - 1.1 - 1.2 - 1.3 - 1.4 - 1.9 + - "1.10" + - 1.11 + - 1.12 script: - go test diff --git a/vendor/github.com/hashicorp/go-version/constraint.go b/vendor/github.com/hashicorp/go-version/constraint.go index 8c73df06..d0557596 100644 --- a/vendor/github.com/hashicorp/go-version/constraint.go +++ b/vendor/github.com/hashicorp/go-version/constraint.go @@ -2,6 +2,7 @@ package version import ( "fmt" + "reflect" "regexp" "strings" ) @@ -113,6 +114,26 @@ func parseSingle(v string) (*Constraint, error) { }, nil } +func prereleaseCheck(v, c *Version) bool { + switch vPre, cPre := v.Prerelease() != "", c.Prerelease() != ""; { + case cPre && vPre: + // A constraint with a pre-release can only match a pre-release version + // with the same base segments. + return reflect.DeepEqual(c.Segments64(), v.Segments64()) + + case !cPre && vPre: + // A constraint without a pre-release can only match a version without a + // pre-release. + return false + + case cPre && !vPre: + // OK, except with the pessimistic operator + case !cPre && !vPre: + // OK + } + return true +} + //------------------------------------------------------------------- // Constraint functions //------------------------------------------------------------------- @@ -126,22 +147,27 @@ func constraintNotEqual(v, c *Version) bool { } func constraintGreaterThan(v, c *Version) bool { - return v.Compare(c) == 1 + return prereleaseCheck(v, c) && v.Compare(c) == 1 } func constraintLessThan(v, c *Version) bool { - return v.Compare(c) == -1 + return prereleaseCheck(v, c) && v.Compare(c) == -1 } func constraintGreaterThanEqual(v, c *Version) bool { - return v.Compare(c) >= 0 + return prereleaseCheck(v, c) && v.Compare(c) >= 0 } func constraintLessThanEqual(v, c *Version) bool { - return v.Compare(c) <= 0 + return prereleaseCheck(v, c) && v.Compare(c) <= 0 } func constraintPessimistic(v, c *Version) bool { + // Using a pessimistic constraint with a pre-release, restricts versions to pre-releases + if !prereleaseCheck(v, c) || (c.Prerelease() != "" && v.Prerelease() == "") { + return false + } + // If the version being checked is naturally less than the constraint, then there // is no way for the version to be valid against the constraint if v.LessThan(c) { diff --git a/vendor/github.com/hashicorp/go-version/constraint_test.go b/vendor/github.com/hashicorp/go-version/constraint_test.go deleted file mode 100644 index 2e733a46..00000000 --- a/vendor/github.com/hashicorp/go-version/constraint_test.go +++ /dev/null @@ -1,113 +0,0 @@ -package version - -import ( - "testing" -) - -func TestNewConstraint(t *testing.T) { - cases := []struct { - input string - count int - err bool - }{ - {">= 1.2", 1, false}, - {"1.0", 1, false}, - {">= 1.x", 0, true}, - {">= 1.2, < 1.0", 2, false}, - - // Out of bounds - {"11387778780781445675529500000000000000000", 0, true}, - } - - for _, tc := range cases { - v, err := NewConstraint(tc.input) - if tc.err && err == nil { - t.Fatalf("expected error for input: %s", tc.input) - } else if !tc.err && err != nil { - t.Fatalf("error for input %s: %s", tc.input, err) - } - - if len(v) != tc.count { - t.Fatalf("input: %s\nexpected len: %d\nactual: %d", - tc.input, tc.count, len(v)) - } - } -} - -func TestConstraintCheck(t *testing.T) { - cases := []struct { - constraint string - version string - check bool - }{ - {">= 1.0, < 1.2", "1.1.5", true}, - {"< 1.0, < 1.2", "1.1.5", false}, - {"= 1.0", "1.1.5", false}, - {"= 1.0", "1.0.0", true}, - {"1.0", "1.0.0", true}, - {"~> 1.0", "2.0", false}, - {"~> 1.0", "1.1", true}, - {"~> 1.0", "1.2.3", true}, - {"~> 1.0.0", "1.2.3", false}, - {"~> 1.0.0", "1.0.7", true}, - {"~> 1.0.0", "1.1.0", false}, - {"~> 1.0.7", "1.0.4", false}, - {"~> 1.0.7", "1.0.7", true}, - {"~> 1.0.7", "1.0.8", true}, - {"~> 1.0.7", "1.0.7.5", true}, - {"~> 1.0.7", "1.0.6.99", false}, - {"~> 1.0.7", "1.0.8.0", true}, - {"~> 1.0.9.5", "1.0.9.5", true}, - {"~> 1.0.9.5", "1.0.9.4", false}, - {"~> 1.0.9.5", "1.0.9.6", true}, - {"~> 1.0.9.5", "1.0.9.5.0", true}, - {"~> 1.0.9.5", "1.0.9.5.1", true}, - } - - for _, tc := range cases { - c, err := NewConstraint(tc.constraint) - if err != nil { - t.Fatalf("err: %s", err) - } - - v, err := NewVersion(tc.version) - if err != nil { - t.Fatalf("err: %s", err) - } - - actual := c.Check(v) - expected := tc.check - if actual != expected { - t.Fatalf("Version: %s\nConstraint: %s\nExpected: %#v", - tc.version, tc.constraint, expected) - } - } -} - -func TestConstraintsString(t *testing.T) { - cases := []struct { - constraint string - result string - }{ - {">= 1.0, < 1.2", ""}, - {"~> 1.0.7", ""}, - } - - for _, tc := range cases { - c, err := NewConstraint(tc.constraint) - if err != nil { - t.Fatalf("err: %s", err) - } - - actual := c.String() - expected := tc.result - if expected == "" { - expected = tc.constraint - } - - if actual != expected { - t.Fatalf("Constraint: %s\nExpected: %#v\nActual: %s", - tc.constraint, expected, actual) - } - } -} diff --git a/vendor/github.com/hashicorp/go-version/go.mod b/vendor/github.com/hashicorp/go-version/go.mod new file mode 100644 index 00000000..f5285555 --- /dev/null +++ b/vendor/github.com/hashicorp/go-version/go.mod @@ -0,0 +1 @@ +module github.com/hashicorp/go-version diff --git a/vendor/github.com/hashicorp/go-version/version.go b/vendor/github.com/hashicorp/go-version/version.go index dfe509ca..1032c560 100644 --- a/vendor/github.com/hashicorp/go-version/version.go +++ b/vendor/github.com/hashicorp/go-version/version.go @@ -10,14 +10,25 @@ import ( ) // The compiled regular expression used to test the validity of a version. -var versionRegexp *regexp.Regexp +var ( + versionRegexp *regexp.Regexp + semverRegexp *regexp.Regexp +) // The raw regular expression string used for testing the validity // of a version. -const VersionRegexpRaw string = `v?([0-9]+(\.[0-9]+)*?)` + - `(-?([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + - `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + - `?` +const ( + VersionRegexpRaw string = `v?([0-9]+(\.[0-9]+)*?)` + + `(-([0-9]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)|(-?([A-Za-z\-~]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)))?` + + `(\+([0-9A-Za-z\-~]+(\.[0-9A-Za-z\-~]+)*))?` + + `?` + + // SemverRegexpRaw requires a separator between version and prerelease + SemverRegexpRaw string = `v?([0-9]+(\.[0-9]+)*?)` + + `(-([0-9]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)|(-([A-Za-z\-~]+[0-9A-Za-z\-~]*(\.[0-9A-Za-z\-~]+)*)))?` + + `(\+([0-9A-Za-z\-~]+(\.[0-9A-Za-z\-~]+)*))?` + + `?` +) // Version represents a single version. type Version struct { @@ -25,16 +36,29 @@ type Version struct { pre string segments []int64 si int + original string } func init() { versionRegexp = regexp.MustCompile("^" + VersionRegexpRaw + "$") + semverRegexp = regexp.MustCompile("^" + SemverRegexpRaw + "$") } // NewVersion parses the given version and returns a new // Version. func NewVersion(v string) (*Version, error) { - matches := versionRegexp.FindStringSubmatch(v) + return newVersion(v, versionRegexp) +} + +// NewSemver parses the given version and returns a new +// Version that adheres strictly to SemVer specs +// https://semver.org/ +func NewSemver(v string) (*Version, error) { + return newVersion(v, semverRegexp) +} + +func newVersion(v string, pattern *regexp.Regexp) (*Version, error) { + matches := pattern.FindStringSubmatch(v) if matches == nil { return nil, fmt.Errorf("Malformed version: %s", v) } @@ -59,11 +83,17 @@ func NewVersion(v string) (*Version, error) { segments = append(segments, 0) } + pre := matches[7] + if pre == "" { + pre = matches[4] + } + return &Version{ - metadata: matches[7], - pre: matches[4], + metadata: matches[10], + pre: pre, segments: segments, si: si, + original: v, }, nil } @@ -82,7 +112,7 @@ func Must(v *Version, err error) *Version { // or larger than the other version, respectively. // // If you want boolean results, use the LessThan, Equal, -// or GreaterThan methods. +// GreaterThan, GreaterThanOrEqual or LessThanOrEqual methods. func (v *Version) Compare(other *Version) int { // A quick, efficient equality check if v.String() == other.String() { @@ -166,14 +196,16 @@ func comparePart(preSelf string, preOther string) int { return 0 } + var selfInt int64 selfNumeric := true - _, err := strconv.ParseInt(preSelf, 10, 64) + selfInt, err := strconv.ParseInt(preSelf, 10, 64) if err != nil { selfNumeric = false } + var otherInt int64 otherNumeric := true - _, err = strconv.ParseInt(preOther, 10, 64) + otherInt, err = strconv.ParseInt(preOther, 10, 64) if err != nil { otherNumeric = false } @@ -197,7 +229,9 @@ func comparePart(preSelf string, preOther string) int { return -1 } else if !selfNumeric && otherNumeric { return 1 - } else if preSelf > preOther { + } else if !selfNumeric && !otherNumeric && preSelf > preOther { + return 1 + } else if selfInt > otherInt { return 1 } @@ -254,11 +288,21 @@ func (v *Version) GreaterThan(o *Version) bool { return v.Compare(o) > 0 } +// GreaterThanOrEqualTo tests if this version is greater than or equal to another version. +func (v *Version) GreaterThanOrEqual(o *Version) bool { + return v.Compare(o) >= 0 +} + // LessThan tests if this version is less than another version. func (v *Version) LessThan(o *Version) bool { return v.Compare(o) < 0 } +// LessThanOrEqualTo tests if this version is less than or equal to another version. +func (v *Version) LessThanOrEqual(o *Version) bool { + return v.Compare(o) <= 0 +} + // Metadata returns any metadata that was part of the version // string. // @@ -297,11 +341,19 @@ func (v *Version) Segments() []int { // for a version "1.2.3-beta", segments will return a slice of // 1, 2, 3. func (v *Version) Segments64() []int64 { - return v.segments + result := make([]int64, len(v.segments)) + copy(result, v.segments) + return result } // String returns the full version string included pre-release // and metadata information. +// +// This value is rebuilt according to the parsed segments and other +// information. Therefore, ambiguities in the version string such as +// prefixed zeroes (1.04.0 => 1.4.0), `v` prefix (v1.0.0 => 1.0.0), and +// missing parts (1.0 => 1.0.0) will be made into a canonicalized form +// as shown in the parenthesized examples. func (v *Version) String() string { var buf bytes.Buffer fmtParts := make([]string, len(v.segments)) @@ -320,3 +372,9 @@ func (v *Version) String() string { return buf.String() } + +// Original returns the original parsed version as-is, including any +// potential whitespace, `v` prefix, etc. +func (v *Version) Original() string { + return v.original +} diff --git a/vendor/github.com/hashicorp/go-version/version_collection_test.go b/vendor/github.com/hashicorp/go-version/version_collection_test.go deleted file mode 100644 index 14783d7e..00000000 --- a/vendor/github.com/hashicorp/go-version/version_collection_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package version - -import ( - "reflect" - "sort" - "testing" -) - -func TestCollection(t *testing.T) { - versionsRaw := []string{ - "1.1.1", - "1.0", - "1.2", - "2", - "0.7.1", - } - - versions := make([]*Version, len(versionsRaw)) - for i, raw := range versionsRaw { - v, err := NewVersion(raw) - if err != nil { - t.Fatalf("err: %s", err) - } - - versions[i] = v - } - - sort.Sort(Collection(versions)) - - actual := make([]string, len(versions)) - for i, v := range versions { - actual[i] = v.String() - } - - expected := []string{ - "0.7.1", - "1.0.0", - "1.1.1", - "1.2.0", - "2.0.0", - } - - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("bad: %#v", actual) - } -} diff --git a/vendor/github.com/hashicorp/go-version/version_test.go b/vendor/github.com/hashicorp/go-version/version_test.go deleted file mode 100644 index ec1f558d..00000000 --- a/vendor/github.com/hashicorp/go-version/version_test.go +++ /dev/null @@ -1,257 +0,0 @@ -package version - -import ( - "reflect" - "testing" -) - -func TestNewVersion(t *testing.T) { - cases := []struct { - version string - err bool - }{ - {"1.2.3", false}, - {"1.0", false}, - {"1", false}, - {"1.2.beta", true}, - {"foo", true}, - {"1.2-5", false}, - {"1.2-beta.5", false}, - {"\n1.2", true}, - {"1.2.0-x.Y.0+metadata", false}, - {"1.2.0-x.Y.0+metadata-width-hypen", false}, - {"1.2.3-rc1-with-hypen", false}, - {"1.2.3.4", false}, - {"1.2.0.4-x.Y.0+metadata", false}, - {"1.2.0.4-x.Y.0+metadata-width-hypen", false}, - {"1.2.3.4-rc1-with-hypen", false}, - {"1.2.3.4", false}, - {"v1.2.3", false}, - {"foo1.2.3", true}, - {"1.7rc2", false}, - {"v1.7rc2", false}, - } - - for _, tc := range cases { - _, err := NewVersion(tc.version) - if tc.err && err == nil { - t.Fatalf("expected error for version: %s", tc.version) - } else if !tc.err && err != nil { - t.Fatalf("error for version %s: %s", tc.version, err) - } - } -} - -func TestVersionCompare(t *testing.T) { - cases := []struct { - v1 string - v2 string - expected int - }{ - {"1.2.3", "1.4.5", -1}, - {"1.2-beta", "1.2-beta", 0}, - {"1.2", "1.1.4", 1}, - {"1.2", "1.2-beta", 1}, - {"1.2+foo", "1.2+beta", 0}, - {"v1.2", "v1.2-beta", 1}, - {"v1.2+foo", "v1.2+beta", 0}, - {"v1.2.3.4", "v1.2.3.4", 0}, - {"v1.2.0.0", "v1.2", 0}, - {"v1.2.0.0.1", "v1.2", 1}, - {"v1.2", "v1.2.0.0", 0}, - {"v1.2", "v1.2.0.0.1", -1}, - {"v1.2.0.0", "v1.2.0.0.1", -1}, - {"v1.2.3.0", "v1.2.3.4", -1}, - {"1.7rc2", "1.7rc1", 1}, - {"1.7rc2", "1.7", -1}, - } - - for _, tc := range cases { - v1, err := NewVersion(tc.v1) - if err != nil { - t.Fatalf("err: %s", err) - } - - v2, err := NewVersion(tc.v2) - if err != nil { - t.Fatalf("err: %s", err) - } - - actual := v1.Compare(v2) - expected := tc.expected - if actual != expected { - t.Fatalf( - "%s <=> %s\nexpected: %d\nactual: %d", - tc.v1, tc.v2, - expected, actual) - } - } -} - -func TestComparePreReleases(t *testing.T) { - cases := []struct { - v1 string - v2 string - expected int - }{ - {"1.2-beta.2", "1.2-beta.2", 0}, - {"1.2-beta.1", "1.2-beta.2", -1}, - {"3.2-alpha.1", "3.2-alpha", 1}, - {"1.2-beta.2", "1.2-beta.1", 1}, - {"1.2-beta", "1.2-beta.3", -1}, - {"1.2-alpha", "1.2-beta.3", -1}, - {"1.2-beta", "1.2-alpha.3", 1}, - {"3.0-alpha.3", "3.0-rc.1", -1}, - {"3.0-alpha3", "3.0-rc1", -1}, - {"3.0-alpha.1", "3.0-alpha.beta", -1}, - {"5.4-alpha", "5.4-alpha.beta", 1}, - {"v1.2-beta.2", "v1.2-beta.2", 0}, - {"v1.2-beta.1", "v1.2-beta.2", -1}, - {"v3.2-alpha.1", "v3.2-alpha", 1}, - {"v3.2-rc.1-1-g123", "v3.2-rc.2", 1}, - } - - for _, tc := range cases { - v1, err := NewVersion(tc.v1) - if err != nil { - t.Fatalf("err: %s", err) - } - - v2, err := NewVersion(tc.v2) - if err != nil { - t.Fatalf("err: %s", err) - } - - actual := v1.Compare(v2) - expected := tc.expected - if actual != expected { - t.Fatalf( - "%s <=> %s\nexpected: %d\nactual: %d", - tc.v1, tc.v2, - expected, actual) - } - } -} - -func TestVersionMetadata(t *testing.T) { - cases := []struct { - version string - expected string - }{ - {"1.2.3", ""}, - {"1.2-beta", ""}, - {"1.2.0-x.Y.0", ""}, - {"1.2.0-x.Y.0+metadata", "metadata"}, - } - - for _, tc := range cases { - v, err := NewVersion(tc.version) - if err != nil { - t.Fatalf("err: %s", err) - } - - actual := v.Metadata() - expected := tc.expected - if actual != expected { - t.Fatalf("expected: %s\nactual: %s", expected, actual) - } - } -} - -func TestVersionPrerelease(t *testing.T) { - cases := []struct { - version string - expected string - }{ - {"1.2.3", ""}, - {"1.2-beta", "beta"}, - {"1.2.0-x.Y.0", "x.Y.0"}, - {"1.2.0-x.Y.0+metadata", "x.Y.0"}, - } - - for _, tc := range cases { - v, err := NewVersion(tc.version) - if err != nil { - t.Fatalf("err: %s", err) - } - - actual := v.Prerelease() - expected := tc.expected - if actual != expected { - t.Fatalf("expected: %s\nactual: %s", expected, actual) - } - } -} - -func TestVersionSegments(t *testing.T) { - cases := []struct { - version string - expected []int - }{ - {"1.2.3", []int{1, 2, 3}}, - {"1.2-beta", []int{1, 2, 0}}, - {"1-x.Y.0", []int{1, 0, 0}}, - {"1.2.0-x.Y.0+metadata", []int{1, 2, 0}}, - } - - for _, tc := range cases { - v, err := NewVersion(tc.version) - if err != nil { - t.Fatalf("err: %s", err) - } - - actual := v.Segments() - expected := tc.expected - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("expected: %#v\nactual: %#v", expected, actual) - } - } -} - -func TestVersionSegments64(t *testing.T) { - cases := []struct { - version string - expected []int64 - }{ - {"1.2.3", []int64{1, 2, 3}}, - {"1.2-beta", []int64{1, 2, 0}}, - {"1-x.Y.0", []int64{1, 0, 0}}, - {"1.2.0-x.Y.0+metadata", []int64{1, 2, 0}}, - {"1.4.9223372036854775807", []int64{1, 4, 9223372036854775807}}, - } - - for _, tc := range cases { - v, err := NewVersion(tc.version) - if err != nil { - t.Fatalf("err: %s", err) - } - - actual := v.Segments64() - expected := tc.expected - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("expected: %#v\nactual: %#v", expected, actual) - } - } -} - -func TestVersionString(t *testing.T) { - cases := [][]string{ - {"1.2.3", "1.2.3"}, - {"1.2-beta", "1.2.0-beta"}, - {"1.2.0-x.Y.0", "1.2.0-x.Y.0"}, - {"1.2.0-x.Y.0+metadata", "1.2.0-x.Y.0+metadata"}, - } - - for _, tc := range cases { - v, err := NewVersion(tc[0]) - if err != nil { - t.Fatalf("err: %s", err) - } - - actual := v.String() - expected := tc[1] - if actual != expected { - t.Fatalf("expected: %s\nactual: %s", expected, actual) - } - } -} diff --git a/vendor/github.com/pkg/errors/.travis.yml b/vendor/github.com/pkg/errors/.travis.yml index 588ceca1..d4b92663 100644 --- a/vendor/github.com/pkg/errors/.travis.yml +++ b/vendor/github.com/pkg/errors/.travis.yml @@ -1,10 +1,14 @@ language: go go_import_path: github.com/pkg/errors go: - - 1.4.3 - - 1.5.4 - - 1.6.2 - - 1.7.1 + - 1.4.x + - 1.5.x + - 1.6.x + - 1.7.x + - 1.8.x + - 1.9.x + - 1.10.x + - 1.11.x - tip script: diff --git a/vendor/github.com/pkg/errors/README.md b/vendor/github.com/pkg/errors/README.md index 273db3c9..6483ba2a 100644 --- a/vendor/github.com/pkg/errors/README.md +++ b/vendor/github.com/pkg/errors/README.md @@ -1,4 +1,4 @@ -# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors) +# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors) [![Sourcegraph](https://sourcegraph.com/github.com/pkg/errors/-/badge.svg)](https://sourcegraph.com/github.com/pkg/errors?badge) Package errors provides simple error handling primitives. @@ -47,6 +47,6 @@ We welcome pull requests, bug fixes and issue reports. With that said, the bar f Before proposing a change, please discuss your change by raising an issue. -## Licence +## License BSD-2-Clause diff --git a/vendor/github.com/pkg/errors/bench_test.go b/vendor/github.com/pkg/errors/bench_test.go deleted file mode 100644 index 0416a3cb..00000000 --- a/vendor/github.com/pkg/errors/bench_test.go +++ /dev/null @@ -1,59 +0,0 @@ -// +build go1.7 - -package errors - -import ( - "fmt" - "testing" - - stderrors "errors" -) - -func noErrors(at, depth int) error { - if at >= depth { - return stderrors.New("no error") - } - return noErrors(at+1, depth) -} -func yesErrors(at, depth int) error { - if at >= depth { - return New("ye error") - } - return yesErrors(at+1, depth) -} - -func BenchmarkErrors(b *testing.B) { - var toperr error - type run struct { - stack int - std bool - } - runs := []run{ - {10, false}, - {10, true}, - {100, false}, - {100, true}, - {1000, false}, - {1000, true}, - } - for _, r := range runs { - part := "pkg/errors" - if r.std { - part = "errors" - } - name := fmt.Sprintf("%s-stack-%d", part, r.stack) - b.Run(name, func(b *testing.B) { - var err error - f := yesErrors - if r.std { - f = noErrors - } - b.ReportAllocs() - for i := 0; i < b.N; i++ { - err = f(0, r.stack) - } - b.StopTimer() - toperr = err - }) - } -} diff --git a/vendor/github.com/pkg/errors/errors.go b/vendor/github.com/pkg/errors/errors.go index 842ee804..7421f326 100644 --- a/vendor/github.com/pkg/errors/errors.go +++ b/vendor/github.com/pkg/errors/errors.go @@ -6,7 +6,7 @@ // return err // } // -// which applied recursively up the call stack results in error reports +// which when applied recursively up the call stack results in error reports // without context or debugging information. The errors package allows // programmers to add context to the failure path in their code in a way // that does not destroy the original value of the error. @@ -15,16 +15,17 @@ // // The errors.Wrap function returns a new error that adds context to the // original error by recording a stack trace at the point Wrap is called, -// and the supplied message. For example +// together with the supplied message. For example // // _, err := ioutil.ReadAll(r) // if err != nil { // return errors.Wrap(err, "read failed") // } // -// If additional control is required the errors.WithStack and errors.WithMessage -// functions destructure errors.Wrap into its component operations of annotating -// an error with a stack trace and an a message, respectively. +// If additional control is required, the errors.WithStack and +// errors.WithMessage functions destructure errors.Wrap into its component +// operations: annotating an error with a stack trace and with a message, +// respectively. // // Retrieving the cause of an error // @@ -38,7 +39,7 @@ // } // // can be inspected by errors.Cause. errors.Cause will recursively retrieve -// the topmost error which does not implement causer, which is assumed to be +// the topmost error that does not implement causer, which is assumed to be // the original cause. For example: // // switch err := errors.Cause(err).(type) { @@ -48,16 +49,16 @@ // // unknown error // } // -// causer interface is not exported by this package, but is considered a part -// of stable public API. +// Although the causer interface is not exported by this package, it is +// considered a part of its stable public interface. // // Formatted printing of errors // // All error values returned from this package implement fmt.Formatter and can -// be formatted by the fmt package. The following verbs are supported +// be formatted by the fmt package. The following verbs are supported: // // %s print the error. If the error has a Cause it will be -// printed recursively +// printed recursively. // %v see %s // %+v extended format. Each Frame of the error's StackTrace will // be printed in detail. @@ -65,13 +66,13 @@ // Retrieving the stack trace of an error or wrapper // // New, Errorf, Wrap, and Wrapf record a stack trace at the point they are -// invoked. This information can be retrieved with the following interface. +// invoked. This information can be retrieved with the following interface: // // type stackTracer interface { // StackTrace() errors.StackTrace // } // -// Where errors.StackTrace is defined as +// The returned errors.StackTrace type is defined as // // type StackTrace []Frame // @@ -85,8 +86,8 @@ // } // } // -// stackTracer interface is not exported by this package, but is considered a part -// of stable public API. +// Although the stackTracer interface is not exported by this package, it is +// considered a part of its stable public interface. // // See the documentation for Frame.Format for more details. package errors @@ -192,7 +193,7 @@ func Wrap(err error, message string) error { } // Wrapf returns an error annotating err with a stack trace -// at the point Wrapf is call, and the format specifier. +// at the point Wrapf is called, and the format specifier. // If err is nil, Wrapf returns nil. func Wrapf(err error, format string, args ...interface{}) error { if err == nil { @@ -220,6 +221,18 @@ func WithMessage(err error, message string) error { } } +// WithMessagef annotates err with the format specifier. +// If err is nil, WithMessagef returns nil. +func WithMessagef(err error, format string, args ...interface{}) error { + if err == nil { + return nil + } + return &withMessage{ + cause: err, + msg: fmt.Sprintf(format, args...), + } +} + type withMessage struct { cause error msg string diff --git a/vendor/github.com/pkg/errors/errors_test.go b/vendor/github.com/pkg/errors/errors_test.go deleted file mode 100644 index 1d8c6355..00000000 --- a/vendor/github.com/pkg/errors/errors_test.go +++ /dev/null @@ -1,226 +0,0 @@ -package errors - -import ( - "errors" - "fmt" - "io" - "reflect" - "testing" -) - -func TestNew(t *testing.T) { - tests := []struct { - err string - want error - }{ - {"", fmt.Errorf("")}, - {"foo", fmt.Errorf("foo")}, - {"foo", New("foo")}, - {"string with format specifiers: %v", errors.New("string with format specifiers: %v")}, - } - - for _, tt := range tests { - got := New(tt.err) - if got.Error() != tt.want.Error() { - t.Errorf("New.Error(): got: %q, want %q", got, tt.want) - } - } -} - -func TestWrapNil(t *testing.T) { - got := Wrap(nil, "no error") - if got != nil { - t.Errorf("Wrap(nil, \"no error\"): got %#v, expected nil", got) - } -} - -func TestWrap(t *testing.T) { - tests := []struct { - err error - message string - want string - }{ - {io.EOF, "read error", "read error: EOF"}, - {Wrap(io.EOF, "read error"), "client error", "client error: read error: EOF"}, - } - - for _, tt := range tests { - got := Wrap(tt.err, tt.message).Error() - if got != tt.want { - t.Errorf("Wrap(%v, %q): got: %v, want %v", tt.err, tt.message, got, tt.want) - } - } -} - -type nilError struct{} - -func (nilError) Error() string { return "nil error" } - -func TestCause(t *testing.T) { - x := New("error") - tests := []struct { - err error - want error - }{{ - // nil error is nil - err: nil, - want: nil, - }, { - // explicit nil error is nil - err: (error)(nil), - want: nil, - }, { - // typed nil is nil - err: (*nilError)(nil), - want: (*nilError)(nil), - }, { - // uncaused error is unaffected - err: io.EOF, - want: io.EOF, - }, { - // caused error returns cause - err: Wrap(io.EOF, "ignored"), - want: io.EOF, - }, { - err: x, // return from errors.New - want: x, - }, { - WithMessage(nil, "whoops"), - nil, - }, { - WithMessage(io.EOF, "whoops"), - io.EOF, - }, { - WithStack(nil), - nil, - }, { - WithStack(io.EOF), - io.EOF, - }} - - for i, tt := range tests { - got := Cause(tt.err) - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("test %d: got %#v, want %#v", i+1, got, tt.want) - } - } -} - -func TestWrapfNil(t *testing.T) { - got := Wrapf(nil, "no error") - if got != nil { - t.Errorf("Wrapf(nil, \"no error\"): got %#v, expected nil", got) - } -} - -func TestWrapf(t *testing.T) { - tests := []struct { - err error - message string - want string - }{ - {io.EOF, "read error", "read error: EOF"}, - {Wrapf(io.EOF, "read error without format specifiers"), "client error", "client error: read error without format specifiers: EOF"}, - {Wrapf(io.EOF, "read error with %d format specifier", 1), "client error", "client error: read error with 1 format specifier: EOF"}, - } - - for _, tt := range tests { - got := Wrapf(tt.err, tt.message).Error() - if got != tt.want { - t.Errorf("Wrapf(%v, %q): got: %v, want %v", tt.err, tt.message, got, tt.want) - } - } -} - -func TestErrorf(t *testing.T) { - tests := []struct { - err error - want string - }{ - {Errorf("read error without format specifiers"), "read error without format specifiers"}, - {Errorf("read error with %d format specifier", 1), "read error with 1 format specifier"}, - } - - for _, tt := range tests { - got := tt.err.Error() - if got != tt.want { - t.Errorf("Errorf(%v): got: %q, want %q", tt.err, got, tt.want) - } - } -} - -func TestWithStackNil(t *testing.T) { - got := WithStack(nil) - if got != nil { - t.Errorf("WithStack(nil): got %#v, expected nil", got) - } -} - -func TestWithStack(t *testing.T) { - tests := []struct { - err error - want string - }{ - {io.EOF, "EOF"}, - {WithStack(io.EOF), "EOF"}, - } - - for _, tt := range tests { - got := WithStack(tt.err).Error() - if got != tt.want { - t.Errorf("WithStack(%v): got: %v, want %v", tt.err, got, tt.want) - } - } -} - -func TestWithMessageNil(t *testing.T) { - got := WithMessage(nil, "no error") - if got != nil { - t.Errorf("WithMessage(nil, \"no error\"): got %#v, expected nil", got) - } -} - -func TestWithMessage(t *testing.T) { - tests := []struct { - err error - message string - want string - }{ - {io.EOF, "read error", "read error: EOF"}, - {WithMessage(io.EOF, "read error"), "client error", "client error: read error: EOF"}, - } - - for _, tt := range tests { - got := WithMessage(tt.err, tt.message).Error() - if got != tt.want { - t.Errorf("WithMessage(%v, %q): got: %q, want %q", tt.err, tt.message, got, tt.want) - } - } - -} - -// errors.New, etc values are not expected to be compared by value -// but the change in errors#27 made them incomparable. Assert that -// various kinds of errors have a functional equality operator, even -// if the result of that equality is always false. -func TestErrorEquality(t *testing.T) { - vals := []error{ - nil, - io.EOF, - errors.New("EOF"), - New("EOF"), - Errorf("EOF"), - Wrap(io.EOF, "EOF"), - Wrapf(io.EOF, "EOF%d", 2), - WithMessage(nil, "whoops"), - WithMessage(io.EOF, "whoops"), - WithStack(io.EOF), - WithStack(nil), - } - - for i := range vals { - for j := range vals { - _ = vals[i] == vals[j] // mustn't panic - } - } -} diff --git a/vendor/github.com/pkg/errors/example_test.go b/vendor/github.com/pkg/errors/example_test.go deleted file mode 100644 index c1fc13e3..00000000 --- a/vendor/github.com/pkg/errors/example_test.go +++ /dev/null @@ -1,205 +0,0 @@ -package errors_test - -import ( - "fmt" - - "github.com/pkg/errors" -) - -func ExampleNew() { - err := errors.New("whoops") - fmt.Println(err) - - // Output: whoops -} - -func ExampleNew_printf() { - err := errors.New("whoops") - fmt.Printf("%+v", err) - - // Example output: - // whoops - // github.com/pkg/errors_test.ExampleNew_printf - // /home/dfc/src/github.com/pkg/errors/example_test.go:17 - // testing.runExample - // /home/dfc/go/src/testing/example.go:114 - // testing.RunExamples - // /home/dfc/go/src/testing/example.go:38 - // testing.(*M).Run - // /home/dfc/go/src/testing/testing.go:744 - // main.main - // /github.com/pkg/errors/_test/_testmain.go:106 - // runtime.main - // /home/dfc/go/src/runtime/proc.go:183 - // runtime.goexit - // /home/dfc/go/src/runtime/asm_amd64.s:2059 -} - -func ExampleWithMessage() { - cause := errors.New("whoops") - err := errors.WithMessage(cause, "oh noes") - fmt.Println(err) - - // Output: oh noes: whoops -} - -func ExampleWithStack() { - cause := errors.New("whoops") - err := errors.WithStack(cause) - fmt.Println(err) - - // Output: whoops -} - -func ExampleWithStack_printf() { - cause := errors.New("whoops") - err := errors.WithStack(cause) - fmt.Printf("%+v", err) - - // Example Output: - // whoops - // github.com/pkg/errors_test.ExampleWithStack_printf - // /home/fabstu/go/src/github.com/pkg/errors/example_test.go:55 - // testing.runExample - // /usr/lib/go/src/testing/example.go:114 - // testing.RunExamples - // /usr/lib/go/src/testing/example.go:38 - // testing.(*M).Run - // /usr/lib/go/src/testing/testing.go:744 - // main.main - // github.com/pkg/errors/_test/_testmain.go:106 - // runtime.main - // /usr/lib/go/src/runtime/proc.go:183 - // runtime.goexit - // /usr/lib/go/src/runtime/asm_amd64.s:2086 - // github.com/pkg/errors_test.ExampleWithStack_printf - // /home/fabstu/go/src/github.com/pkg/errors/example_test.go:56 - // testing.runExample - // /usr/lib/go/src/testing/example.go:114 - // testing.RunExamples - // /usr/lib/go/src/testing/example.go:38 - // testing.(*M).Run - // /usr/lib/go/src/testing/testing.go:744 - // main.main - // github.com/pkg/errors/_test/_testmain.go:106 - // runtime.main - // /usr/lib/go/src/runtime/proc.go:183 - // runtime.goexit - // /usr/lib/go/src/runtime/asm_amd64.s:2086 -} - -func ExampleWrap() { - cause := errors.New("whoops") - err := errors.Wrap(cause, "oh noes") - fmt.Println(err) - - // Output: oh noes: whoops -} - -func fn() error { - e1 := errors.New("error") - e2 := errors.Wrap(e1, "inner") - e3 := errors.Wrap(e2, "middle") - return errors.Wrap(e3, "outer") -} - -func ExampleCause() { - err := fn() - fmt.Println(err) - fmt.Println(errors.Cause(err)) - - // Output: outer: middle: inner: error - // error -} - -func ExampleWrap_extended() { - err := fn() - fmt.Printf("%+v\n", err) - - // Example output: - // error - // github.com/pkg/errors_test.fn - // /home/dfc/src/github.com/pkg/errors/example_test.go:47 - // github.com/pkg/errors_test.ExampleCause_printf - // /home/dfc/src/github.com/pkg/errors/example_test.go:63 - // testing.runExample - // /home/dfc/go/src/testing/example.go:114 - // testing.RunExamples - // /home/dfc/go/src/testing/example.go:38 - // testing.(*M).Run - // /home/dfc/go/src/testing/testing.go:744 - // main.main - // /github.com/pkg/errors/_test/_testmain.go:104 - // runtime.main - // /home/dfc/go/src/runtime/proc.go:183 - // runtime.goexit - // /home/dfc/go/src/runtime/asm_amd64.s:2059 - // github.com/pkg/errors_test.fn - // /home/dfc/src/github.com/pkg/errors/example_test.go:48: inner - // github.com/pkg/errors_test.fn - // /home/dfc/src/github.com/pkg/errors/example_test.go:49: middle - // github.com/pkg/errors_test.fn - // /home/dfc/src/github.com/pkg/errors/example_test.go:50: outer -} - -func ExampleWrapf() { - cause := errors.New("whoops") - err := errors.Wrapf(cause, "oh noes #%d", 2) - fmt.Println(err) - - // Output: oh noes #2: whoops -} - -func ExampleErrorf_extended() { - err := errors.Errorf("whoops: %s", "foo") - fmt.Printf("%+v", err) - - // Example output: - // whoops: foo - // github.com/pkg/errors_test.ExampleErrorf - // /home/dfc/src/github.com/pkg/errors/example_test.go:101 - // testing.runExample - // /home/dfc/go/src/testing/example.go:114 - // testing.RunExamples - // /home/dfc/go/src/testing/example.go:38 - // testing.(*M).Run - // /home/dfc/go/src/testing/testing.go:744 - // main.main - // /github.com/pkg/errors/_test/_testmain.go:102 - // runtime.main - // /home/dfc/go/src/runtime/proc.go:183 - // runtime.goexit - // /home/dfc/go/src/runtime/asm_amd64.s:2059 -} - -func Example_stackTrace() { - type stackTracer interface { - StackTrace() errors.StackTrace - } - - err, ok := errors.Cause(fn()).(stackTracer) - if !ok { - panic("oops, err does not implement stackTracer") - } - - st := err.StackTrace() - fmt.Printf("%+v", st[0:2]) // top two frames - - // Example output: - // github.com/pkg/errors_test.fn - // /home/dfc/src/github.com/pkg/errors/example_test.go:47 - // github.com/pkg/errors_test.Example_stackTrace - // /home/dfc/src/github.com/pkg/errors/example_test.go:127 -} - -func ExampleCause_printf() { - err := errors.Wrap(func() error { - return func() error { - return errors.Errorf("hello %s", fmt.Sprintf("world")) - }() - }(), "failed") - - fmt.Printf("%v", err) - - // Output: failed: hello world -} diff --git a/vendor/github.com/pkg/errors/format_test.go b/vendor/github.com/pkg/errors/format_test.go deleted file mode 100644 index 15fd7d89..00000000 --- a/vendor/github.com/pkg/errors/format_test.go +++ /dev/null @@ -1,535 +0,0 @@ -package errors - -import ( - "errors" - "fmt" - "io" - "regexp" - "strings" - "testing" -) - -func TestFormatNew(t *testing.T) { - tests := []struct { - error - format string - want string - }{{ - New("error"), - "%s", - "error", - }, { - New("error"), - "%v", - "error", - }, { - New("error"), - "%+v", - "error\n" + - "github.com/pkg/errors.TestFormatNew\n" + - "\t.+/github.com/pkg/errors/format_test.go:26", - }, { - New("error"), - "%q", - `"error"`, - }} - - for i, tt := range tests { - testFormatRegexp(t, i, tt.error, tt.format, tt.want) - } -} - -func TestFormatErrorf(t *testing.T) { - tests := []struct { - error - format string - want string - }{{ - Errorf("%s", "error"), - "%s", - "error", - }, { - Errorf("%s", "error"), - "%v", - "error", - }, { - Errorf("%s", "error"), - "%+v", - "error\n" + - "github.com/pkg/errors.TestFormatErrorf\n" + - "\t.+/github.com/pkg/errors/format_test.go:56", - }} - - for i, tt := range tests { - testFormatRegexp(t, i, tt.error, tt.format, tt.want) - } -} - -func TestFormatWrap(t *testing.T) { - tests := []struct { - error - format string - want string - }{{ - Wrap(New("error"), "error2"), - "%s", - "error2: error", - }, { - Wrap(New("error"), "error2"), - "%v", - "error2: error", - }, { - Wrap(New("error"), "error2"), - "%+v", - "error\n" + - "github.com/pkg/errors.TestFormatWrap\n" + - "\t.+/github.com/pkg/errors/format_test.go:82", - }, { - Wrap(io.EOF, "error"), - "%s", - "error: EOF", - }, { - Wrap(io.EOF, "error"), - "%v", - "error: EOF", - }, { - Wrap(io.EOF, "error"), - "%+v", - "EOF\n" + - "error\n" + - "github.com/pkg/errors.TestFormatWrap\n" + - "\t.+/github.com/pkg/errors/format_test.go:96", - }, { - Wrap(Wrap(io.EOF, "error1"), "error2"), - "%+v", - "EOF\n" + - "error1\n" + - "github.com/pkg/errors.TestFormatWrap\n" + - "\t.+/github.com/pkg/errors/format_test.go:103\n", - }, { - Wrap(New("error with space"), "context"), - "%q", - `"context: error with space"`, - }} - - for i, tt := range tests { - testFormatRegexp(t, i, tt.error, tt.format, tt.want) - } -} - -func TestFormatWrapf(t *testing.T) { - tests := []struct { - error - format string - want string - }{{ - Wrapf(io.EOF, "error%d", 2), - "%s", - "error2: EOF", - }, { - Wrapf(io.EOF, "error%d", 2), - "%v", - "error2: EOF", - }, { - Wrapf(io.EOF, "error%d", 2), - "%+v", - "EOF\n" + - "error2\n" + - "github.com/pkg/errors.TestFormatWrapf\n" + - "\t.+/github.com/pkg/errors/format_test.go:134", - }, { - Wrapf(New("error"), "error%d", 2), - "%s", - "error2: error", - }, { - Wrapf(New("error"), "error%d", 2), - "%v", - "error2: error", - }, { - Wrapf(New("error"), "error%d", 2), - "%+v", - "error\n" + - "github.com/pkg/errors.TestFormatWrapf\n" + - "\t.+/github.com/pkg/errors/format_test.go:149", - }} - - for i, tt := range tests { - testFormatRegexp(t, i, tt.error, tt.format, tt.want) - } -} - -func TestFormatWithStack(t *testing.T) { - tests := []struct { - error - format string - want []string - }{{ - WithStack(io.EOF), - "%s", - []string{"EOF"}, - }, { - WithStack(io.EOF), - "%v", - []string{"EOF"}, - }, { - WithStack(io.EOF), - "%+v", - []string{"EOF", - "github.com/pkg/errors.TestFormatWithStack\n" + - "\t.+/github.com/pkg/errors/format_test.go:175"}, - }, { - WithStack(New("error")), - "%s", - []string{"error"}, - }, { - WithStack(New("error")), - "%v", - []string{"error"}, - }, { - WithStack(New("error")), - "%+v", - []string{"error", - "github.com/pkg/errors.TestFormatWithStack\n" + - "\t.+/github.com/pkg/errors/format_test.go:189", - "github.com/pkg/errors.TestFormatWithStack\n" + - "\t.+/github.com/pkg/errors/format_test.go:189"}, - }, { - WithStack(WithStack(io.EOF)), - "%+v", - []string{"EOF", - "github.com/pkg/errors.TestFormatWithStack\n" + - "\t.+/github.com/pkg/errors/format_test.go:197", - "github.com/pkg/errors.TestFormatWithStack\n" + - "\t.+/github.com/pkg/errors/format_test.go:197"}, - }, { - WithStack(WithStack(Wrapf(io.EOF, "message"))), - "%+v", - []string{"EOF", - "message", - "github.com/pkg/errors.TestFormatWithStack\n" + - "\t.+/github.com/pkg/errors/format_test.go:205", - "github.com/pkg/errors.TestFormatWithStack\n" + - "\t.+/github.com/pkg/errors/format_test.go:205", - "github.com/pkg/errors.TestFormatWithStack\n" + - "\t.+/github.com/pkg/errors/format_test.go:205"}, - }, { - WithStack(Errorf("error%d", 1)), - "%+v", - []string{"error1", - "github.com/pkg/errors.TestFormatWithStack\n" + - "\t.+/github.com/pkg/errors/format_test.go:216", - "github.com/pkg/errors.TestFormatWithStack\n" + - "\t.+/github.com/pkg/errors/format_test.go:216"}, - }} - - for i, tt := range tests { - testFormatCompleteCompare(t, i, tt.error, tt.format, tt.want, true) - } -} - -func TestFormatWithMessage(t *testing.T) { - tests := []struct { - error - format string - want []string - }{{ - WithMessage(New("error"), "error2"), - "%s", - []string{"error2: error"}, - }, { - WithMessage(New("error"), "error2"), - "%v", - []string{"error2: error"}, - }, { - WithMessage(New("error"), "error2"), - "%+v", - []string{ - "error", - "github.com/pkg/errors.TestFormatWithMessage\n" + - "\t.+/github.com/pkg/errors/format_test.go:244", - "error2"}, - }, { - WithMessage(io.EOF, "addition1"), - "%s", - []string{"addition1: EOF"}, - }, { - WithMessage(io.EOF, "addition1"), - "%v", - []string{"addition1: EOF"}, - }, { - WithMessage(io.EOF, "addition1"), - "%+v", - []string{"EOF", "addition1"}, - }, { - WithMessage(WithMessage(io.EOF, "addition1"), "addition2"), - "%v", - []string{"addition2: addition1: EOF"}, - }, { - WithMessage(WithMessage(io.EOF, "addition1"), "addition2"), - "%+v", - []string{"EOF", "addition1", "addition2"}, - }, { - Wrap(WithMessage(io.EOF, "error1"), "error2"), - "%+v", - []string{"EOF", "error1", "error2", - "github.com/pkg/errors.TestFormatWithMessage\n" + - "\t.+/github.com/pkg/errors/format_test.go:272"}, - }, { - WithMessage(Errorf("error%d", 1), "error2"), - "%+v", - []string{"error1", - "github.com/pkg/errors.TestFormatWithMessage\n" + - "\t.+/github.com/pkg/errors/format_test.go:278", - "error2"}, - }, { - WithMessage(WithStack(io.EOF), "error"), - "%+v", - []string{ - "EOF", - "github.com/pkg/errors.TestFormatWithMessage\n" + - "\t.+/github.com/pkg/errors/format_test.go:285", - "error"}, - }, { - WithMessage(Wrap(WithStack(io.EOF), "inside-error"), "outside-error"), - "%+v", - []string{ - "EOF", - "github.com/pkg/errors.TestFormatWithMessage\n" + - "\t.+/github.com/pkg/errors/format_test.go:293", - "inside-error", - "github.com/pkg/errors.TestFormatWithMessage\n" + - "\t.+/github.com/pkg/errors/format_test.go:293", - "outside-error"}, - }} - - for i, tt := range tests { - testFormatCompleteCompare(t, i, tt.error, tt.format, tt.want, true) - } -} - -func TestFormatGeneric(t *testing.T) { - starts := []struct { - err error - want []string - }{ - {New("new-error"), []string{ - "new-error", - "github.com/pkg/errors.TestFormatGeneric\n" + - "\t.+/github.com/pkg/errors/format_test.go:315"}, - }, {Errorf("errorf-error"), []string{ - "errorf-error", - "github.com/pkg/errors.TestFormatGeneric\n" + - "\t.+/github.com/pkg/errors/format_test.go:319"}, - }, {errors.New("errors-new-error"), []string{ - "errors-new-error"}, - }, - } - - wrappers := []wrapper{ - { - func(err error) error { return WithMessage(err, "with-message") }, - []string{"with-message"}, - }, { - func(err error) error { return WithStack(err) }, - []string{ - "github.com/pkg/errors.(func·002|TestFormatGeneric.func2)\n\t" + - ".+/github.com/pkg/errors/format_test.go:333", - }, - }, { - func(err error) error { return Wrap(err, "wrap-error") }, - []string{ - "wrap-error", - "github.com/pkg/errors.(func·003|TestFormatGeneric.func3)\n\t" + - ".+/github.com/pkg/errors/format_test.go:339", - }, - }, { - func(err error) error { return Wrapf(err, "wrapf-error%d", 1) }, - []string{ - "wrapf-error1", - "github.com/pkg/errors.(func·004|TestFormatGeneric.func4)\n\t" + - ".+/github.com/pkg/errors/format_test.go:346", - }, - }, - } - - for s := range starts { - err := starts[s].err - want := starts[s].want - testFormatCompleteCompare(t, s, err, "%+v", want, false) - testGenericRecursive(t, err, want, wrappers, 3) - } -} - -func testFormatRegexp(t *testing.T, n int, arg interface{}, format, want string) { - got := fmt.Sprintf(format, arg) - gotLines := strings.SplitN(got, "\n", -1) - wantLines := strings.SplitN(want, "\n", -1) - - if len(wantLines) > len(gotLines) { - t.Errorf("test %d: wantLines(%d) > gotLines(%d):\n got: %q\nwant: %q", n+1, len(wantLines), len(gotLines), got, want) - return - } - - for i, w := range wantLines { - match, err := regexp.MatchString(w, gotLines[i]) - if err != nil { - t.Fatal(err) - } - if !match { - t.Errorf("test %d: line %d: fmt.Sprintf(%q, err):\n got: %q\nwant: %q", n+1, i+1, format, got, want) - } - } -} - -var stackLineR = regexp.MustCompile(`\.`) - -// parseBlocks parses input into a slice, where: -// - incase entry contains a newline, its a stacktrace -// - incase entry contains no newline, its a solo line. -// -// Detecting stack boundaries only works incase the WithStack-calls are -// to be found on the same line, thats why it is optionally here. -// -// Example use: -// -// for _, e := range blocks { -// if strings.ContainsAny(e, "\n") { -// // Match as stack -// } else { -// // Match as line -// } -// } -// -func parseBlocks(input string, detectStackboundaries bool) ([]string, error) { - var blocks []string - - stack := "" - wasStack := false - lines := map[string]bool{} // already found lines - - for _, l := range strings.Split(input, "\n") { - isStackLine := stackLineR.MatchString(l) - - switch { - case !isStackLine && wasStack: - blocks = append(blocks, stack, l) - stack = "" - lines = map[string]bool{} - case isStackLine: - if wasStack { - // Detecting two stacks after another, possible cause lines match in - // our tests due to WithStack(WithStack(io.EOF)) on same line. - if detectStackboundaries { - if lines[l] { - if len(stack) == 0 { - return nil, errors.New("len of block must not be zero here") - } - - blocks = append(blocks, stack) - stack = l - lines = map[string]bool{l: true} - continue - } - } - - stack = stack + "\n" + l - } else { - stack = l - } - lines[l] = true - case !isStackLine && !wasStack: - blocks = append(blocks, l) - default: - return nil, errors.New("must not happen") - } - - wasStack = isStackLine - } - - // Use up stack - if stack != "" { - blocks = append(blocks, stack) - } - return blocks, nil -} - -func testFormatCompleteCompare(t *testing.T, n int, arg interface{}, format string, want []string, detectStackBoundaries bool) { - gotStr := fmt.Sprintf(format, arg) - - got, err := parseBlocks(gotStr, detectStackBoundaries) - if err != nil { - t.Fatal(err) - } - - if len(got) != len(want) { - t.Fatalf("test %d: fmt.Sprintf(%s, err) -> wrong number of blocks: got(%d) want(%d)\n got: %s\nwant: %s\ngotStr: %q", - n+1, format, len(got), len(want), prettyBlocks(got), prettyBlocks(want), gotStr) - } - - for i := range got { - if strings.ContainsAny(want[i], "\n") { - // Match as stack - match, err := regexp.MatchString(want[i], got[i]) - if err != nil { - t.Fatal(err) - } - if !match { - t.Fatalf("test %d: block %d: fmt.Sprintf(%q, err):\ngot:\n%q\nwant:\n%q\nall-got:\n%s\nall-want:\n%s\n", - n+1, i+1, format, got[i], want[i], prettyBlocks(got), prettyBlocks(want)) - } - } else { - // Match as message - if got[i] != want[i] { - t.Fatalf("test %d: fmt.Sprintf(%s, err) at block %d got != want:\n got: %q\nwant: %q", n+1, format, i+1, got[i], want[i]) - } - } - } -} - -type wrapper struct { - wrap func(err error) error - want []string -} - -func prettyBlocks(blocks []string, prefix ...string) string { - var out []string - - for _, b := range blocks { - out = append(out, fmt.Sprintf("%v", b)) - } - - return " " + strings.Join(out, "\n ") -} - -func testGenericRecursive(t *testing.T, beforeErr error, beforeWant []string, list []wrapper, maxDepth int) { - if len(beforeWant) == 0 { - panic("beforeWant must not be empty") - } - for _, w := range list { - if len(w.want) == 0 { - panic("want must not be empty") - } - - err := w.wrap(beforeErr) - - // Copy required cause append(beforeWant, ..) modified beforeWant subtly. - beforeCopy := make([]string, len(beforeWant)) - copy(beforeCopy, beforeWant) - - beforeWant := beforeCopy - last := len(beforeWant) - 1 - var want []string - - // Merge two stacks behind each other. - if strings.ContainsAny(beforeWant[last], "\n") && strings.ContainsAny(w.want[0], "\n") { - want = append(beforeWant[:last], append([]string{beforeWant[last] + "((?s).*)" + w.want[0]}, w.want[1:]...)...) - } else { - want = append(beforeWant, w.want...) - } - - testFormatCompleteCompare(t, maxDepth, err, "%+v", want, false) - if maxDepth > 0 { - testGenericRecursive(t, err, want, list, maxDepth-1) - } - } -} diff --git a/vendor/github.com/pkg/errors/stack.go b/vendor/github.com/pkg/errors/stack.go index 6b1f2891..2874a048 100644 --- a/vendor/github.com/pkg/errors/stack.go +++ b/vendor/github.com/pkg/errors/stack.go @@ -46,7 +46,8 @@ func (f Frame) line() int { // // Format accepts flags that alter the printing of some verbs, as follows: // -// %+s path of source file relative to the compile time GOPATH +// %+s function name and path of source file relative to the compile time +// GOPATH separated by \n\t (\n\t) // %+v equivalent to %+s:%d func (f Frame) Format(s fmt.State, verb rune) { switch verb { @@ -79,6 +80,14 @@ func (f Frame) Format(s fmt.State, verb rune) { // StackTrace is stack of Frames from innermost (newest) to outermost (oldest). type StackTrace []Frame +// Format formats the stack of Frames according to the fmt.Formatter interface. +// +// %s lists source files for each Frame in the stack +// %v lists the source file and line number for each Frame in the stack +// +// Format accepts flags that alter the printing of some verbs, as follows: +// +// %+v Prints filename, function, and line number for each Frame in the stack. func (st StackTrace) Format(s fmt.State, verb rune) { switch verb { case 'v': @@ -136,43 +145,3 @@ func funcname(name string) string { i = strings.Index(name, ".") return name[i+1:] } - -func trimGOPATH(name, file string) string { - // Here we want to get the source file path relative to the compile time - // GOPATH. As of Go 1.6.x there is no direct way to know the compiled - // GOPATH at runtime, but we can infer the number of path segments in the - // GOPATH. We note that fn.Name() returns the function name qualified by - // the import path, which does not include the GOPATH. Thus we can trim - // segments from the beginning of the file path until the number of path - // separators remaining is one more than the number of path separators in - // the function name. For example, given: - // - // GOPATH /home/user - // file /home/user/src/pkg/sub/file.go - // fn.Name() pkg/sub.Type.Method - // - // We want to produce: - // - // pkg/sub/file.go - // - // From this we can easily see that fn.Name() has one less path separator - // than our desired output. We count separators from the end of the file - // path until it finds two more than in the function name and then move - // one character forward to preserve the initial path segment without a - // leading separator. - const sep = "/" - goal := strings.Count(name, sep) + 2 - i := len(file) - for n := 0; n < goal; n++ { - i = strings.LastIndex(file[:i], sep) - if i == -1 { - // not enough separators found, set i so that the slice expression - // below leaves file unmodified - i = -len(sep) - break - } - } - // get back to 0 or trim the leading separator - file = file[i+len(sep):] - return file -} diff --git a/vendor/github.com/pkg/errors/stack_test.go b/vendor/github.com/pkg/errors/stack_test.go deleted file mode 100644 index 510c27a9..00000000 --- a/vendor/github.com/pkg/errors/stack_test.go +++ /dev/null @@ -1,292 +0,0 @@ -package errors - -import ( - "fmt" - "runtime" - "testing" -) - -var initpc, _, _, _ = runtime.Caller(0) - -func TestFrameLine(t *testing.T) { - var tests = []struct { - Frame - want int - }{{ - Frame(initpc), - 9, - }, { - func() Frame { - var pc, _, _, _ = runtime.Caller(0) - return Frame(pc) - }(), - 20, - }, { - func() Frame { - var pc, _, _, _ = runtime.Caller(1) - return Frame(pc) - }(), - 28, - }, { - Frame(0), // invalid PC - 0, - }} - - for _, tt := range tests { - got := tt.Frame.line() - want := tt.want - if want != got { - t.Errorf("Frame(%v): want: %v, got: %v", uintptr(tt.Frame), want, got) - } - } -} - -type X struct{} - -func (x X) val() Frame { - var pc, _, _, _ = runtime.Caller(0) - return Frame(pc) -} - -func (x *X) ptr() Frame { - var pc, _, _, _ = runtime.Caller(0) - return Frame(pc) -} - -func TestFrameFormat(t *testing.T) { - var tests = []struct { - Frame - format string - want string - }{{ - Frame(initpc), - "%s", - "stack_test.go", - }, { - Frame(initpc), - "%+s", - "github.com/pkg/errors.init\n" + - "\t.+/github.com/pkg/errors/stack_test.go", - }, { - Frame(0), - "%s", - "unknown", - }, { - Frame(0), - "%+s", - "unknown", - }, { - Frame(initpc), - "%d", - "9", - }, { - Frame(0), - "%d", - "0", - }, { - Frame(initpc), - "%n", - "init", - }, { - func() Frame { - var x X - return x.ptr() - }(), - "%n", - `\(\*X\).ptr`, - }, { - func() Frame { - var x X - return x.val() - }(), - "%n", - "X.val", - }, { - Frame(0), - "%n", - "", - }, { - Frame(initpc), - "%v", - "stack_test.go:9", - }, { - Frame(initpc), - "%+v", - "github.com/pkg/errors.init\n" + - "\t.+/github.com/pkg/errors/stack_test.go:9", - }, { - Frame(0), - "%v", - "unknown:0", - }} - - for i, tt := range tests { - testFormatRegexp(t, i, tt.Frame, tt.format, tt.want) - } -} - -func TestFuncname(t *testing.T) { - tests := []struct { - name, want string - }{ - {"", ""}, - {"runtime.main", "main"}, - {"github.com/pkg/errors.funcname", "funcname"}, - {"funcname", "funcname"}, - {"io.copyBuffer", "copyBuffer"}, - {"main.(*R).Write", "(*R).Write"}, - } - - for _, tt := range tests { - got := funcname(tt.name) - want := tt.want - if got != want { - t.Errorf("funcname(%q): want: %q, got %q", tt.name, want, got) - } - } -} - -func TestTrimGOPATH(t *testing.T) { - var tests = []struct { - Frame - want string - }{{ - Frame(initpc), - "github.com/pkg/errors/stack_test.go", - }} - - for i, tt := range tests { - pc := tt.Frame.pc() - fn := runtime.FuncForPC(pc) - file, _ := fn.FileLine(pc) - got := trimGOPATH(fn.Name(), file) - testFormatRegexp(t, i, got, "%s", tt.want) - } -} - -func TestStackTrace(t *testing.T) { - tests := []struct { - err error - want []string - }{{ - New("ooh"), []string{ - "github.com/pkg/errors.TestStackTrace\n" + - "\t.+/github.com/pkg/errors/stack_test.go:172", - }, - }, { - Wrap(New("ooh"), "ahh"), []string{ - "github.com/pkg/errors.TestStackTrace\n" + - "\t.+/github.com/pkg/errors/stack_test.go:177", // this is the stack of Wrap, not New - }, - }, { - Cause(Wrap(New("ooh"), "ahh")), []string{ - "github.com/pkg/errors.TestStackTrace\n" + - "\t.+/github.com/pkg/errors/stack_test.go:182", // this is the stack of New - }, - }, { - func() error { return New("ooh") }(), []string{ - `github.com/pkg/errors.(func·009|TestStackTrace.func1)` + - "\n\t.+/github.com/pkg/errors/stack_test.go:187", // this is the stack of New - "github.com/pkg/errors.TestStackTrace\n" + - "\t.+/github.com/pkg/errors/stack_test.go:187", // this is the stack of New's caller - }, - }, { - Cause(func() error { - return func() error { - return Errorf("hello %s", fmt.Sprintf("world")) - }() - }()), []string{ - `github.com/pkg/errors.(func·010|TestStackTrace.func2.1)` + - "\n\t.+/github.com/pkg/errors/stack_test.go:196", // this is the stack of Errorf - `github.com/pkg/errors.(func·011|TestStackTrace.func2)` + - "\n\t.+/github.com/pkg/errors/stack_test.go:197", // this is the stack of Errorf's caller - "github.com/pkg/errors.TestStackTrace\n" + - "\t.+/github.com/pkg/errors/stack_test.go:198", // this is the stack of Errorf's caller's caller - }, - }} - for i, tt := range tests { - x, ok := tt.err.(interface { - StackTrace() StackTrace - }) - if !ok { - t.Errorf("expected %#v to implement StackTrace() StackTrace", tt.err) - continue - } - st := x.StackTrace() - for j, want := range tt.want { - testFormatRegexp(t, i, st[j], "%+v", want) - } - } -} - -func stackTrace() StackTrace { - const depth = 8 - var pcs [depth]uintptr - n := runtime.Callers(1, pcs[:]) - var st stack = pcs[0:n] - return st.StackTrace() -} - -func TestStackTraceFormat(t *testing.T) { - tests := []struct { - StackTrace - format string - want string - }{{ - nil, - "%s", - `\[\]`, - }, { - nil, - "%v", - `\[\]`, - }, { - nil, - "%+v", - "", - }, { - nil, - "%#v", - `\[\]errors.Frame\(nil\)`, - }, { - make(StackTrace, 0), - "%s", - `\[\]`, - }, { - make(StackTrace, 0), - "%v", - `\[\]`, - }, { - make(StackTrace, 0), - "%+v", - "", - }, { - make(StackTrace, 0), - "%#v", - `\[\]errors.Frame{}`, - }, { - stackTrace()[:2], - "%s", - `\[stack_test.go stack_test.go\]`, - }, { - stackTrace()[:2], - "%v", - `\[stack_test.go:225 stack_test.go:272\]`, - }, { - stackTrace()[:2], - "%+v", - "\n" + - "github.com/pkg/errors.stackTrace\n" + - "\t.+/github.com/pkg/errors/stack_test.go:225\n" + - "github.com/pkg/errors.TestStackTraceFormat\n" + - "\t.+/github.com/pkg/errors/stack_test.go:276", - }, { - stackTrace()[:2], - "%#v", - `\[\]errors.Frame{stack_test.go:225, stack_test.go:284}`, - }} - - for i, tt := range tests { - testFormatRegexp(t, i, tt.StackTrace, tt.format, tt.want) - } -} diff --git a/vendor/github.com/ryanuber/go-glob/.travis.yml b/vendor/github.com/ryanuber/go-glob/.travis.yml new file mode 100644 index 00000000..9d1ca3c3 --- /dev/null +++ b/vendor/github.com/ryanuber/go-glob/.travis.yml @@ -0,0 +1,5 @@ +language: go +go: + - tip +script: + - go test -v ./... diff --git a/vendor/github.com/ryanuber/go-glob/LICENSE b/vendor/github.com/ryanuber/go-glob/LICENSE new file mode 100644 index 00000000..bdfbd951 --- /dev/null +++ b/vendor/github.com/ryanuber/go-glob/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Ryan Uber + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/ryanuber/go-glob/README.md b/vendor/github.com/ryanuber/go-glob/README.md new file mode 100644 index 00000000..48f7fcb0 --- /dev/null +++ b/vendor/github.com/ryanuber/go-glob/README.md @@ -0,0 +1,29 @@ +# String globbing in golang [![Build Status](https://travis-ci.org/ryanuber/go-glob.svg)](https://travis-ci.org/ryanuber/go-glob) + +`go-glob` is a single-function library implementing basic string glob support. + +Globs are an extremely user-friendly way of supporting string matching without +requiring knowledge of regular expressions or Go's particular regex engine. Most +people understand that if you put a `*` character somewhere in a string, it is +treated as a wildcard. Surprisingly, this functionality isn't found in Go's +standard library, except for `path.Match`, which is intended to be used while +comparing paths (not arbitrary strings), and contains specialized logic for this +use case. A better solution might be a POSIX basic (non-ERE) regular expression +engine for Go, which doesn't exist currently. + +Example +======= + +``` +package main + +import "github.com/ryanuber/go-glob" + +func main() { + glob.Glob("*World!", "Hello, World!") // true + glob.Glob("Hello,*", "Hello, World!") // true + glob.Glob("*ello,*", "Hello, World!") // true + glob.Glob("World!", "Hello, World!") // false + glob.Glob("/home/*", "/home/ryanuber/.bashrc") // true +} +``` diff --git a/vendor/github.com/ryanuber/go-glob/glob.go b/vendor/github.com/ryanuber/go-glob/glob.go new file mode 100644 index 00000000..e67db3be --- /dev/null +++ b/vendor/github.com/ryanuber/go-glob/glob.go @@ -0,0 +1,56 @@ +package glob + +import "strings" + +// The character which is treated like a glob +const GLOB = "*" + +// Glob will test a string pattern, potentially containing globs, against a +// subject string. The result is a simple true/false, determining whether or +// not the glob pattern matched the subject text. +func Glob(pattern, subj string) bool { + // Empty pattern can only match empty subject + if pattern == "" { + return subj == pattern + } + + // If the pattern _is_ a glob, it matches everything + if pattern == GLOB { + return true + } + + parts := strings.Split(pattern, GLOB) + + if len(parts) == 1 { + // No globs in pattern, so test for equality + return subj == pattern + } + + leadingGlob := strings.HasPrefix(pattern, GLOB) + trailingGlob := strings.HasSuffix(pattern, GLOB) + end := len(parts) - 1 + + // Go over the leading parts and ensure they match. + for i := 0; i < end; i++ { + idx := strings.Index(subj, parts[i]) + + switch i { + case 0: + // Check the first section. Requires special handling. + if !leadingGlob && idx != 0 { + return false + } + default: + // Check that the middle parts match. + if idx < 0 { + return false + } + } + + // Trim evaluated text from subj as we loop over the pattern. + subj = subj[idx+len(parts[i]):] + } + + // Reached the last section. Requires special handling. + return trailingGlob || strings.HasSuffix(subj, parts[end]) +} diff --git a/vendor/github.com/ryanuber/go-glob/go.mod b/vendor/github.com/ryanuber/go-glob/go.mod new file mode 100644 index 00000000..f3820359 --- /dev/null +++ b/vendor/github.com/ryanuber/go-glob/go.mod @@ -0,0 +1 @@ +module github.com/ryanuber/go-glob diff --git a/vendor/howett.net/plist/.travis.yml b/vendor/howett.net/plist/.travis.yml deleted file mode 100644 index b1f27e39..00000000 --- a/vendor/howett.net/plist/.travis.yml +++ /dev/null @@ -1,8 +0,0 @@ -language: go -go_import_path: "howett.net/plist" -go: - - 1.2 - - master -script: - - go test -v - - go test -tags appengine diff --git a/vendor/howett.net/plist/README.md b/vendor/howett.net/plist/README.md index ffc456f3..a13e29a3 100644 --- a/vendor/howett.net/plist/README.md +++ b/vendor/howett.net/plist/README.md @@ -1,4 +1,4 @@ -# plist - A pure Go property list transcoder [![coverage report](https://gitlab.howett.net/DHowett/plist/badges/master/coverage.svg)](https://gitlab.howett.net/DHowett/plist/commits/master) +# plist - A pure Go property list transcoder [![coverage report](https://gitlab.howett.net/go/plist/badges/master/coverage.svg)](https://gitlab.howett.net/go/plist/commits/master) ## INSTALL ``` $ go get howett.net/plist diff --git a/vendor/howett.net/plist/bplist_generator.go b/vendor/howett.net/plist/bplist_generator.go index 5b6513d1..09ab71b1 100644 --- a/vendor/howett.net/plist/bplist_generator.go +++ b/vendor/howett.net/plist/bplist_generator.go @@ -109,7 +109,7 @@ func (p *bplistGenerator) writePlistValue(pval cfValue) { case cfString: p.writeStringTag(string(pval)) case *cfNumber: - p.writeIntTag(pval.value) + p.writeIntTag(pval.signed, pval.value) case *cfReal: if pval.wide { p.writeRealTag(pval.value, 64) @@ -154,7 +154,7 @@ func (p *bplistGenerator) writeBoolTag(v bool) { binary.Write(p.writer, binary.BigEndian, tag) } -func (p *bplistGenerator) writeIntTag(n uint64) { +func (p *bplistGenerator) writeIntTag(signed bool, n uint64) { var tag uint8 var val interface{} switch { @@ -167,12 +167,25 @@ func (p *bplistGenerator) writeIntTag(n uint64) { case n <= uint64(0xffffffff): val = uint32(n) tag = bpTagInteger | 0x2 + case n > uint64(0x7fffffffffffffff) && !signed: + // 64-bit values are always *signed* in format 00. + // Any unsigned value that doesn't intersect with the signed + // range must be sign-extended and stored as a SInt128 + val = n + tag = bpTagInteger | 0x4 default: val = n tag = bpTagInteger | 0x3 } binary.Write(p.writer, binary.BigEndian, tag) + if tag&0xF == 0x4 { + // SInt128; in the absence of true 128-bit integers in Go, + // we'll just fake the top half. We only got here because + // we had an unsigned 64-bit int that didn't fit, + // so sign extend it with zeroes. + binary.Write(p.writer, binary.BigEndian, uint64(0)) + } binary.Write(p.writer, binary.BigEndian, val) } @@ -216,7 +229,7 @@ func (p *bplistGenerator) writeCountedTag(tag uint8, count uint64) { binary.Write(p.writer, binary.BigEndian, marker) if count >= 0xF { - p.writeIntTag(count) + p.writeIntTag(false, count) } } diff --git a/vendor/howett.net/plist/bplist_parser.go b/vendor/howett.net/plist/bplist_parser.go index 224354bb..1825b570 100644 --- a/vendor/howett.net/plist/bplist_parser.go +++ b/vendor/howett.net/plist/bplist_parser.go @@ -13,6 +13,10 @@ import ( "unicode/utf16" ) +const ( + signedHighBits = 0xFFFFFFFFFFFFFFFF +) + type offset uint64 type bplistParser struct { @@ -112,20 +116,31 @@ func (p *bplistParser) parseDocument() (pval cfValue, parseError error) { } // parseSizedInteger returns a 128-bit integer as low64, high64 -func (p *bplistParser) parseSizedInteger(off offset, nbytes int) (uint64, uint64, offset) { +func (p *bplistParser) parseSizedInteger(off offset, nbytes int) (lo uint64, hi uint64, newOffset offset) { + // Per comments in CoreFoundation, format version 00 requires that all + // 1, 2 or 4-byte integers be interpreted as unsigned. 8-byte integers are + // signed (always?) and therefore must be sign extended here. + // negative 1, 2, or 4-byte integers are always emitted as 64-bit. switch nbytes { case 1: - return uint64(p.buffer[off]), 0, off + offset(nbytes) + lo, hi = uint64(p.buffer[off]), 0 case 2: - return uint64(binary.BigEndian.Uint16(p.buffer[off:])), 0, off + offset(nbytes) + lo, hi = uint64(binary.BigEndian.Uint16(p.buffer[off:])), 0 case 4: - return uint64(binary.BigEndian.Uint32(p.buffer[off:])), 0, off + offset(nbytes) + lo, hi = uint64(binary.BigEndian.Uint32(p.buffer[off:])), 0 case 8: - return binary.BigEndian.Uint64(p.buffer[off:]), 0, off + offset(nbytes) + lo = binary.BigEndian.Uint64(p.buffer[off:]) + if p.buffer[off]&0x80 != 0 { + // sign extend if lo is signed + hi = signedHighBits + } case 16: - return binary.BigEndian.Uint64(p.buffer[off+8:]), binary.BigEndian.Uint64(p.buffer[off:]), off + offset(nbytes) + lo, hi = binary.BigEndian.Uint64(p.buffer[off+8:]), binary.BigEndian.Uint64(p.buffer[off:]) + default: + panic(errors.New("illegal integer size")) } - panic(errors.New("illegal integer size")) + newOffset = off + offset(nbytes) + return } func (p *bplistParser) parseObjectRefAtOffset(off offset) (uint64, offset) { @@ -193,7 +208,7 @@ func (p *bplistParser) parseTagAtOffset(off offset) cfValue { case bpTagInteger: lo, hi, _ := p.parseIntegerAtOffset(off) return &cfNumber{ - signed: hi == 0xFFFFFFFFFFFFFFFF, // a signed integer is stored as a 128-bit integer with the top 64 bits set + signed: hi == signedHighBits, // a signed integer is stored as a 128-bit integer with the top 64 bits set value: lo, } case bpTagReal: diff --git a/vendor/howett.net/plist/bplist_test.go b/vendor/howett.net/plist/bplist_test.go deleted file mode 100644 index 280158cf..00000000 --- a/vendor/howett.net/plist/bplist_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package plist - -import ( - "bytes" - "encoding/binary" - "io/ioutil" - "testing" -) - -func BenchmarkBplistGenerate(b *testing.B) { - for i := 0; i < b.N; i++ { - d := newBplistGenerator(ioutil.Discard) - d.generateDocument(plistValueTree) - } -} - -func BenchmarkBplistParse(b *testing.B) { - buf := bytes.NewReader(plistValueTreeAsBplist) - b.ResetTimer() - for i := 0; i < b.N; i++ { - b.StartTimer() - d := newBplistParser(buf) - d.parseDocument() - b.StopTimer() - buf.Seek(0, 0) - } -} - -func TestBplistInt128(t *testing.T) { - bplist := []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0x14, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19} - expected := uint64(0x090a0b0c0d0e0f10) - buf := bytes.NewReader(bplist) - d := newBplistParser(buf) - pval, _ := d.parseDocument() - if pinteger, ok := pval.(*cfNumber); !ok || pinteger.value != expected { - t.Error("Expected", expected, "received", pval) - } -} - -func TestBplistLatin1ToUTF16(t *testing.T) { - expectedPrefix := []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd1, 0x01, 0x02, 0x51, 0x5f, 0x6f, 0x10, 0x80} - expectedPostfix := []byte{0x00, 0x08, 0x00, 0x0b, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10} - expectedBuf := bytes.NewBuffer(expectedPrefix) - - sBuf := &bytes.Buffer{} - for i := uint16(0xc280); i <= 0xc2bf; i++ { - binary.Write(sBuf, binary.BigEndian, i) - binary.Write(expectedBuf, binary.BigEndian, i-0xc200) - } - - for i := uint16(0xc380); i <= 0xc3bf; i++ { - binary.Write(sBuf, binary.BigEndian, i) - binary.Write(expectedBuf, binary.BigEndian, i-0xc300+0x0040) - } - - expectedBuf.Write(expectedPostfix) - - var buf bytes.Buffer - encoder := NewBinaryEncoder(&buf) - - data := map[string]string{ - "_": string(sBuf.Bytes()), - } - if err := encoder.Encode(data); err != nil { - t.Error(err.Error()) - } - - if !bytes.Equal(buf.Bytes(), expectedBuf.Bytes()) { - t.Error("Expected", expectedBuf.Bytes(), "received", buf.Bytes()) - return - } -} diff --git a/vendor/howett.net/plist/cmd/ply/README.md b/vendor/howett.net/plist/cmd/ply/README.md deleted file mode 100644 index cdd579f3..00000000 --- a/vendor/howett.net/plist/cmd/ply/README.md +++ /dev/null @@ -1,180 +0,0 @@ -# Ply -Property list pretty-printer powered by `howett.net/plist`. - -_verb. work with (a tool, especially one requiring steady, rhythmic movements)._ - -## Installation - -`go get howett.net/plist/cmd/ply` - -## Usage - -``` - ply [OPTIONS] - -Application Options: - -c, --convert= convert the property list to a new format (c=list for list) (pretty) - -k, --key= A keypath! (/) - -o, --out= output filename - -I, --indent indent indentable output formats (xml, openstep, gnustep, json) - -Help Options: - -h, --help Show this help message -``` - -## Features - -### Keypath evaluation - -``` -$ ply file.plist -{ - x: { - y: { - z: 1024 - } - } -} -$ ply -k x/y/z file.plist -1024 -``` - -Keypaths are composed of a number of path expressions: - -* `/name` - dictionary key access -* `[i]` - index array, string, or data -* `[i:j]` - silce array, string, or data in the range `[i, j)` -* `!` - parse the data value as a property list and use it as the base of evaluation for further path components -* `$(subexpression)` - evaluate `subexpression` and paste its value - -#### Examples - -Given the following property list: - -``` -{ - a = { - b = { - c = (1, 2, 3); - d = hello; - }; - data = <414243>; - }; - sub = <7b0a0974 6869733d 22612064 69637469 6f6e6172 7920696e 73696465 20616e6f 74686572 20706c69 73742122 3b7d>; - hello = subexpression; -} -``` - -##### pretty print -``` -$ ply file.plist -{ - a: { - b: { - c: ( - [0]: 1 - [1]: 2 - [2]: 3 - ) - d: hello - } - data: 00000000 41 42 43 |ABC.............| - } - hello: subexpression - sub: 00000000 7b 0a 09 74 68 69 73 3d 22 61 20 64 69 63 74 69 |{..this="a dicti| - 00000010 6f 6e 61 72 79 20 69 6e 73 69 64 65 20 61 6e 6f |onary inside ano| - 00000020 74 68 65 72 20 70 6c 69 73 74 21 22 3b 7d |ther plist!";}..| -} -``` - -##### consecutive dictionary keys -``` -$ ply file.plist -k 'a/b/d' -hello -``` - -##### array indexing -``` -$ ply file.plist -k 'a/b/c[1]' -2 -``` - -##### data hexdump -``` -$ ply file.plist -k 'a/data' -00000000 41 42 43 |ABC.............| -``` - -##### data and array slicing -``` -$ ply file.plist -k 'a/data[2:3]' -00000000 43 |C...............| -``` - -``` -$ ply -k 'sub[0:10]' file.plist -00000000 7b 0a 09 74 68 69 73 3d 22 61 |{..this="a......| -``` - -##### subplist parsing -``` -$ ply -k 'sub!' file.plist -{ - this: a dictionary inside another plist! -} -``` - -##### subplist keypath evaluation -``` -$ ply -k 'sub!/this' file.plist -a dictionary inside another plist! -``` - -##### subexpression evaluation -``` -$ ply -k '/$(/a/b/d)' file.plist -subexpression -``` - -### Property list conversion - -`-c `, or `-c list` to list them all. - -* Binary property list [`bplist`] -* XML [`xml`] -* GNUstep [`gnustep`, `gs`] -* OpenStep [`openstep`, `os`] -* JSON (for a subset of data types) [`json`] -* YAML [`yaml`] - -#### Notes -By default, ply will emit the most compact representation it can for a given format. The `-I` flag influences the inclusion of whitespace. - -Ply will overwrite the input file unless an output filename is specified with `-o `. - -### Property list subsetting - -(and subset conversion) - -``` -$ ply -k '/a/b' -o file-a-b.plist -c openstep -I file.plist -$ cat file-a-b.plist -{ - c = ( - 1, - 2, - 3, - ); - d = hello; -} -``` - -#### Subplist extraction - -``` -$ ply -k '/sub!' -o file-sub.plist -c openstep -I file.plist -$ cat file-sub.plist -{ - this = "a dictionary inside another plist!"; -} -``` diff --git a/vendor/howett.net/plist/cmd/ply/ply.go b/vendor/howett.net/plist/cmd/ply/ply.go deleted file mode 100644 index 057dd684..00000000 --- a/vendor/howett.net/plist/cmd/ply/ply.go +++ /dev/null @@ -1,395 +0,0 @@ -package main - -import ( - "bufio" - "bytes" - "encoding/binary" - "encoding/json" - "errors" - "fmt" - "io" - "os" - "path/filepath" - "reflect" - "strconv" - "strings" - - "github.com/jessevdk/go-flags" - "gopkg.in/yaml.v1" - "howett.net/plist" -) - -//import "github.com/mgutz/ansi" - -const ( - PrettyFormat = 100 + iota - JSONFormat - YAMLFormat - RawFormat -) - -var nameFormatMap = map[string]int{ - "x": plist.XMLFormat, - "xml": plist.XMLFormat, - "xml1": plist.XMLFormat, - "b": plist.BinaryFormat, - "bin": plist.BinaryFormat, - "binary": plist.BinaryFormat, - "binary1": plist.BinaryFormat, - "o": plist.OpenStepFormat, - "os": plist.OpenStepFormat, - "openstep": plist.OpenStepFormat, - "step": plist.OpenStepFormat, - "g": plist.GNUStepFormat, - "gs": plist.GNUStepFormat, - "gnustep": plist.GNUStepFormat, - "pretty": PrettyFormat, - "json": JSONFormat, - "yaml": YAMLFormat, - "r": RawFormat, - "raw": RawFormat, -} - -var opts struct { - Convert string `short:"c" long:"convert" description:"convert the property list to a new format (c=list for list)" default:"pretty" value-name:""` - Keypath string `short:"k" long:"key" description:"A keypath!" default:"/" value-name:""` - Output string `short:"o" long:"out" description:"output filename" default:"" value-name:""` - Indent bool `short:"I" long:"indent" description:"indent indentable output formats (xml, openstep, gnustep, json)"` -} - -func main() { - parser := flags.NewParser(&opts, flags.Default) - args, err := parser.Parse() - if err != nil { - // flags.Default implies flags.PrintError; there's no reason to print it here - return - } - - if opts.Convert == "list" { - formats := make([]string, len(nameFormatMap)) - i := 0 - for k, _ := range nameFormatMap { - formats[i] = k - i++ - } - - fmt.Fprintln(os.Stderr, "Supported output formats:") - fmt.Fprintln(os.Stderr, strings.Join(formats, ", ")) - return - } - - if len(args) < 1 { - parser.WriteHelp(os.Stderr) - return - } - - filename := args[0] - - keypath := opts.Keypath - if len(keypath) == 0 { - c := strings.Index(filename, ":") - if c > -1 { - keypath = filename[c+1:] - filename = filename[:c] - } - } - - file, err := os.Open(filename) - if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - return - } - - var val interface{} - switch strings.ToLower(filepath.Ext(filename)) { - case ".json", ".yaml", ".yml": - buf := &bytes.Buffer{} - io.Copy(buf, file) - err = yaml.Unmarshal(buf.Bytes(), &val) - default: - dec := plist.NewDecoder(file) - err = dec.Decode(&val) - } - - if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - return - } - file.Close() - - convert := strings.ToLower(opts.Convert) - format, ok := nameFormatMap[convert] - if !ok { - fmt.Fprintf(os.Stderr, "unknown output format %s\n", convert) - return - } - - output := opts.Output - newline := false - var outputStream io.WriteCloser - if format < PrettyFormat && output == "" { - // Writing a plist, but no output filename. Save to original. - output = filename - } else if format >= PrettyFormat && output == "" { - // Writing a non-plist, but no output filename: Stdout - outputStream = os.Stdout - newline = true - } else if output == "-" { - // - means stdout. - outputStream = os.Stdout - newline = true - } - - if outputStream == nil { - outfile, err := os.Create(output) - if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - return - } - outputStream = outfile - } - - keypathContext := &KeypathWalker{} - rval, err := keypathContext.WalkKeypath(reflect.ValueOf(val), keypath) - if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - return - } - val = rval.Interface() - - switch { - case format >= 0 && format < PrettyFormat: - enc := plist.NewEncoderForFormat(outputStream, format) - if opts.Indent { - enc.Indent("\t") - } - err := enc.Encode(val) - if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - return - } - case format == PrettyFormat: - PrettyPrint(outputStream, rval.Interface()) - case format == JSONFormat: - var out []byte - var err error - if opts.Indent { - out, err = json.MarshalIndent(val, "", "\t") - } else { - out, err = json.Marshal(val) - } - if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - return - } - outputStream.Write(out) - case format == YAMLFormat: - out, err := yaml.Marshal(val) - if err != nil { - fmt.Fprintln(os.Stderr, err.Error()) - return - } - outputStream.Write(out) - case format == RawFormat: - newline = false - switch rval.Kind() { - case reflect.String: - outputStream.Write([]byte(val.(string))) - case reflect.Slice: - if rval.Elem().Kind() == reflect.Uint8 { - outputStream.Write(val.([]byte)) - } - default: - binary.Write(outputStream, binary.LittleEndian, val) - } - } - if newline { - fmt.Fprintf(outputStream, "\n") - } - outputStream.Close() -} - -type KeypathWalker struct { - rootVal *reflect.Value - curVal reflect.Value -} - -func (ctx *KeypathWalker) Split(data []byte, atEOF bool) (advance int, token []byte, err error) { - mode, oldmode := 0, 0 - depth := 0 - tok, subexpr := "", "" - // modes: - // 0: normal string, separated by / - // 1: array index (reading between []) - // 2: found $, looking for ( or nothing - // 3: found $(, reading subkey, looking for ) - // 4: "escape"? unused as yet. - if len(data) == 0 && atEOF { - return 0, nil, io.EOF - } -each: - for _, v := range data { - advance++ - switch { - case mode == 4: - // Completing an escape sequence. - tok += string(v) - mode = 0 - continue each - case mode == 0 && v == '/': - if tok != "" { - break each - } else { - continue each - } - case mode == 0 && v == '[': - if tok != "" { - // We have encountered a [ after text, we want only the text - advance-- // We don't want to consume this character. - break each - } else { - tok += string(v) - mode = 1 - } - case mode == 1 && v == ']': - mode = 0 - tok += string(v) - break each - case mode == 0 && v == '!': - if tok == "" { - tok = "!" - break each - } else { - // We have encountered a ! after text, we want the text - advance-- // We don't want to consume this character. - break each - } - case (mode == 0 || mode == 1) && v == '$': - oldmode = mode - mode = 2 - case mode == 2: - if v == '(' { - mode = 3 - depth++ - subexpr = "" - } else { - // We didn't emit the $ to begin with, so we have to do it here. - tok += "$" + string(v) - mode = 0 - } - case mode == 3 && v == '(': - subexpr += string(v) - depth++ - case mode == 3 && v == ')': - depth-- - if depth == 0 { - newCtx := &KeypathWalker{rootVal: ctx.rootVal} - subexprVal, e := newCtx.WalkKeypath(*ctx.rootVal, subexpr) - if e != nil { - return 0, nil, errors.New("Dynamic subexpression " + subexpr + " failed: " + e.Error()) - } - if subexprVal.Kind() == reflect.Interface { - subexprVal = subexprVal.Elem() - } - s := "" - if subexprVal.Kind() == reflect.String { - s = subexprVal.String() - } else if subexprVal.Kind() == reflect.Uint64 { - s = strconv.Itoa(int(subexprVal.Uint())) - } else { - return 0, nil, errors.New("Dynamic subexpression " + subexpr + " evaluated to non-string/non-int.") - } - tok += s - mode = oldmode - } else { - subexpr += string(v) - } - case mode == 3: - subexpr += string(v) - default: - tok += string(v) - } - - } - return advance, []byte(tok), nil -} - -func (ctx *KeypathWalker) WalkKeypath(val reflect.Value, keypath string) (reflect.Value, error) { - if keypath == "" { - return val, nil - } - - if ctx.rootVal == nil { - ctx.rootVal = &val - } - - ctx.curVal = val - - scanner := bufio.NewScanner(strings.NewReader(keypath)) - scanner.Split(ctx.Split) - for scanner.Scan() { - token := scanner.Text() - if ctx.curVal.Kind() == reflect.Interface { - ctx.curVal = ctx.curVal.Elem() - } - - switch { - case len(token) == 0: - continue - case token[0] == '[': // array - s := token[1 : len(token)-1] - if ctx.curVal.Kind() != reflect.Slice && ctx.curVal.Kind() != reflect.String { - return reflect.ValueOf(nil), errors.New("keypath attempted to index non-indexable with " + s) - } - - colon := strings.Index(s, ":") - if colon > -1 { - var err error - var si, sj int - is := s[:colon] - js := s[colon+1:] - if is != "" { - si, err = strconv.Atoi(is) - if err != nil { - return reflect.ValueOf(nil), err - } - } - if js != "" { - sj, err = strconv.Atoi(js) - if err != nil { - return reflect.ValueOf(nil), err - } - } - if si < 0 || sj > ctx.curVal.Len() { - return reflect.ValueOf(nil), errors.New("keypath attempted to index outside of indexable with " + s) - } - ctx.curVal = ctx.curVal.Slice(si, sj) - } else { - idx, _ := strconv.Atoi(s) - ctx.curVal = ctx.curVal.Index(idx) - } - case token[0] == '!': // subplist! - if ctx.curVal.Kind() != reflect.Slice || ctx.curVal.Type().Elem().Kind() != reflect.Uint8 { - return reflect.Value{}, errors.New("Attempted to subplist non-data.") - } - byt := ctx.curVal.Interface().([]uint8) - buf := bytes.NewReader(byt) - dec := plist.NewDecoder(buf) - var subval interface{} - dec.Decode(&subval) - ctx.curVal = reflect.ValueOf(subval) - default: // just a string - if ctx.curVal.Kind() != reflect.Map { - return reflect.ValueOf(nil), errors.New("keypath attempted to descend into non-map using key " + token) - } - if token != "" { - ctx.curVal = ctx.curVal.MapIndex(reflect.ValueOf(token)) - } - } - } - err := scanner.Err() - if err != nil { - return reflect.ValueOf(nil), err - } - return ctx.curVal, nil -} diff --git a/vendor/howett.net/plist/cmd/ply/prettyprint.go b/vendor/howett.net/plist/cmd/ply/prettyprint.go deleted file mode 100644 index be75e6bd..00000000 --- a/vendor/howett.net/plist/cmd/ply/prettyprint.go +++ /dev/null @@ -1,121 +0,0 @@ -package main - -import ( - "encoding/hex" - "fmt" - "io" - "reflect" - "sort" - "time" - - "howett.net/plist" -) - -func PrettyPrint(w io.Writer, val interface{}) { - printValue(w, val, "") -} - -func printMap(w io.Writer, tv reflect.Value, depth string) { - fmt.Fprintf(w, "{\n") - ss := make(sort.StringSlice, tv.Len()) - i := 0 - for _, kval := range tv.MapKeys() { - if kval.Kind() == reflect.Interface { - kval = kval.Elem() - } - - if kval.Kind() != reflect.String { - continue - } - - ss[i] = kval.String() - i++ - } - sort.Sort(ss) - for _, k := range ss { - val := tv.MapIndex(reflect.ValueOf(k)) - v := val.Interface() - nd := depth + " " - for i := 0; i < len(k)+2; i++ { - nd += " " - } - fmt.Fprintf(w, " %s%s: ", depth, k) - printValue(w, v, nd) - } - fmt.Fprintf(w, "%s}\n", depth) -} - -func printValue(w io.Writer, val interface{}, depth string) { - switch tv := val.(type) { - case map[interface{}]interface{}: - printMap(w, reflect.ValueOf(tv), depth) - case map[string]interface{}: - printMap(w, reflect.ValueOf(tv), depth) - case []interface{}: - fmt.Fprintf(w, "(\n") - for i, v := range tv { - id := fmt.Sprintf("[%d]", i) - nd := depth + " " - for i := 0; i < len(id)+2; i++ { - nd += " " - } - fmt.Fprintf(w, " %s%s: ", depth, id) - printValue(w, v, nd) - } - fmt.Fprintf(w, "%s)\n", depth) - case plist.UID: - fmt.Fprintf(w, "#%d\n", uint64(tv)) - case int64, uint64, string, float32, float64, bool, time.Time: - fmt.Fprintf(w, "%+v\n", tv) - case uint8: - fmt.Fprintf(w, "0x%2.02x\n", tv) - case []byte: - l := len(tv) - sxl := l / 16 - if l%16 > 0 { - sxl++ - } - sxl *= 16 - var buf [4]byte - var off [8]byte - var asc [16]byte - var ol int - for i := 0; i < sxl; i++ { - if i%16 == 0 { - if i > 0 { - io.WriteString(w, depth) - } - buf[0] = byte(i >> 24) - buf[1] = byte(i >> 16) - buf[2] = byte(i >> 8) - buf[3] = byte(i) - hex.Encode(off[:], buf[:]) - io.WriteString(w, string(off[:])+" ") - } - if i < l { - hex.Encode(off[:], tv[i:i+1]) - if tv[i] < 32 || tv[i] > 126 { - asc[i%16] = '.' - } else { - asc[i%16] = tv[i] - } - } else { - off[0] = ' ' - off[1] = ' ' - asc[i%16] = '.' - } - off[2] = ' ' - ol = 3 - if i%16 == 7 || i%16 == 15 { - off[3] = ' ' - ol = 4 - } - io.WriteString(w, string(off[:ol])) - if i%16 == 15 { - io.WriteString(w, "|"+string(asc[:])+"|\n") - } - } - default: - fmt.Fprintf(w, "%#v\n", val) - } -} diff --git a/vendor/howett.net/plist/common_data_for_test.go b/vendor/howett.net/plist/common_data_for_test.go deleted file mode 100644 index 694c0f13..00000000 --- a/vendor/howett.net/plist/common_data_for_test.go +++ /dev/null @@ -1,958 +0,0 @@ -package plist - -import ( - "errors" - "math" - "reflect" - "time" -) - -type TestData struct { - Name string - Value interface{} - DecodeValue interface{} // used when the document cannot encode parts of Value - Documents map[int][]byte - SkipDecode map[int]bool - SkipEncode map[int]bool -} - -type SparseBundleHeader struct { - InfoDictionaryVersion string `plist:"CFBundleInfoDictionaryVersion"` - BandSize uint64 `plist:"band-size"` - BackingStoreVersion int `plist:"bundle-backingstore-version"` - DiskImageBundleType string `plist:"diskimage-bundle-type"` - Size uint64 `plist:"size"` -} - -type EmbedA struct { - EmbedC - EmbedB EmbedB - FieldA string -} - -type EmbedB struct { - FieldB string - *EmbedC -} - -type EmbedC struct { - FieldA1 string `plist:"FieldA"` - FieldA2 string - FieldB string - FieldC string -} - -type TextMarshalingBool struct { - b bool -} - -func (b TextMarshalingBool) MarshalText() ([]byte, error) { - if b.b { - return []byte("truthful"), nil - } - return []byte("non-factual"), nil -} - -func (b *TextMarshalingBool) UnmarshalText(text []byte) error { - if string(text) == "truthful" { - b.b = true - } - return nil -} - -type TextMarshalingBoolViaPointer struct { - b bool -} - -func (b *TextMarshalingBoolViaPointer) MarshalText() ([]byte, error) { - if b.b { - return []byte("plausible"), nil - } - return []byte("unimaginable"), nil -} - -func (b *TextMarshalingBoolViaPointer) UnmarshalText(text []byte) error { - if string(text) == "plausible" { - b.b = true - } - return nil -} - -type ArrayThatSerializesAsOneObject struct { - values []uint64 -} - -func (f ArrayThatSerializesAsOneObject) MarshalPlist() (interface{}, error) { - if len(f.values) == 1 { - return f.values[0], nil - } - return f.values, nil -} - -func (f *ArrayThatSerializesAsOneObject) UnmarshalPlist(unmarshal func(interface{}) error) error { - var ui uint64 - if err := unmarshal(&ui); err == nil { - f.values = []uint64{ui} - return nil - } - - return unmarshal(&f.values) -} - -type PlistMarshalingBoolByPointer struct { - b bool -} - -func (b *PlistMarshalingBoolByPointer) MarshalPlist() (interface{}, error) { - if b.b { - return int64(-1), nil - } - return int64(-2), nil -} - -func (b *PlistMarshalingBoolByPointer) UnmarshalPlist(unmarshal func(interface{}) error) error { - var val int64 - err := unmarshal(&val) - if err != nil { - return err - } - - b.b = val == -1 - return nil -} - -type BothMarshaler struct{} - -func (b *BothMarshaler) MarshalPlist() (interface{}, error) { - return map[string]string{"a": "b"}, nil -} - -func (b *BothMarshaler) MarshalText() ([]byte, error) { - return []byte("shouldn't see this"), nil -} - -type BothUnmarshaler struct { - Blah int64 `plist:"blah,omitempty"` -} - -func (b *BothUnmarshaler) UnmarshalPlist(unmarshal func(interface{}) error) error { - // no error - return nil -} - -func (b *BothUnmarshaler) UnmarshalText(text []byte) error { - return errors.New("shouldn't hit this") -} - -var xmlPreamble = ` - -` - -var tests = []TestData{ - { - Name: "String", - Value: "Hello", - Documents: map[int][]byte{ - OpenStepFormat: []byte(`Hello`), - GNUStepFormat: []byte(`Hello`), - XMLFormat: []byte(xmlPreamble + `Hello`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 85, 72, 101, 108, 108, 111, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14}, - }, - }, - { - Name: "Basic Structure", - Value: struct { - Name string - }{ - Name: "Dustin", - }, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`{Name=Dustin;}`), - GNUStepFormat: []byte(`{Name=Dustin;}`), - XMLFormat: []byte(xmlPreamble + `NameDustin`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 209, 1, 2, 84, 78, 97, 109, 101, 86, 68, 117, 115, 116, 105, 110, 8, 11, 16, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23}, - }, - }, - { - Name: "Basic Structure with non-exported fields", - Value: struct { - Name string - age int - }{ - Name: "Dustin", - age: 24, - }, - DecodeValue: struct { - Name string - age int - }{ - Name: "Dustin", - }, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`{Name=Dustin;}`), - GNUStepFormat: []byte(`{Name=Dustin;}`), - XMLFormat: []byte(xmlPreamble + `NameDustin`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 209, 1, 2, 84, 78, 97, 109, 101, 86, 68, 117, 115, 116, 105, 110, 8, 11, 16, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23}, - }, - }, - { - Name: "Basic Structure with omitted fields", - Value: struct { - Name string - Age int `plist:"-"` - }{ - Name: "Dustin", - Age: 24, - }, - DecodeValue: struct { - Name string - Age int `plist:"-"` - }{ - Name: "Dustin", - }, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`{Name=Dustin;}`), - GNUStepFormat: []byte(`{Name=Dustin;}`), - XMLFormat: []byte(xmlPreamble + `NameDustin`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 209, 1, 2, 84, 78, 97, 109, 101, 86, 68, 117, 115, 116, 105, 110, 8, 11, 16, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23}, - }, - }, - { - Name: "Basic Structure with empty omitempty fields", - Value: struct { - Name string - Age int `plist:"age,omitempty"` - Slice []int `plist:",omitempty"` - Bool bool `plist:",omitempty"` - Uint uint `plist:",omitempty"` - Float32 float32 `plist:",omitempty"` - Float64 float64 `plist:",omitempty"` - Stringptr *string `plist:",omitempty"` - Notempty uint `plist:",omitempty"` - }{ - Name: "Dustin", - Notempty: 10, - }, - DecodeValue: struct { - Name string - Age int `plist:"age,omitempty"` - Slice []int `plist:",omitempty"` - Bool bool `plist:",omitempty"` - Uint uint `plist:",omitempty"` - Float32 float32 `plist:",omitempty"` - Float64 float64 `plist:",omitempty"` - Stringptr *string `plist:",omitempty"` - Notempty uint `plist:",omitempty"` - }{ - Name: "Dustin", - Notempty: 10, - }, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`{Name=Dustin;Notempty=10;}`), - GNUStepFormat: []byte(`{Name=Dustin;Notempty=<*I10>;}`), - XMLFormat: []byte(xmlPreamble + `NameDustinNotempty10`), - BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd2, 0x1, 0x2, 0x3, 0x4, 0x54, 0x4e, 0x61, 0x6d, 0x65, 0x58, 0x4e, 0x6f, 0x74, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x56, 0x44, 0x75, 0x73, 0x74, 0x69, 0x6e, 0x10, 0xa, 0x8, 0xd, 0x12, 0x1b, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24}, - }, - }, - { - Name: "Structure with Anonymous Embeds", - Value: EmbedA{ - EmbedC: EmbedC{ - FieldA1: "", - FieldA2: "", - FieldB: "A.C.B", - FieldC: "A.C.C", - }, - EmbedB: EmbedB{ - FieldB: "A.B.B", - EmbedC: &EmbedC{ - FieldA1: "A.B.C.A1", - FieldA2: "A.B.C.A2", - FieldB: "", // Shadowed by A.B.B - FieldC: "A.B.C.C", - }, - }, - FieldA: "A.A", - }, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`{EmbedB={FieldA="A.B.C.A1";FieldA2="A.B.C.A2";FieldB="A.B.B";FieldC="A.B.C.C";};FieldA="A.A";FieldA2="";FieldB="A.C.B";FieldC="A.C.C";}`), - GNUStepFormat: []byte(`{EmbedB={FieldA=A.B.C.A1;FieldA2=A.B.C.A2;FieldB=A.B.B;FieldC=A.B.C.C;};FieldA=A.A;FieldA2="";FieldB=A.C.B;FieldC=A.C.C;}`), - XMLFormat: []byte(xmlPreamble + `EmbedBFieldAA.B.C.A1FieldA2A.B.C.A2FieldBA.B.BFieldCA.B.C.CFieldAA.AFieldA2FieldBA.C.BFieldCA.C.C`), - BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd5, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0xb, 0xc, 0xd, 0xe, 0x56, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x42, 0x56, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x41, 0x57, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x41, 0x32, 0x56, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x42, 0x56, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x43, 0xd4, 0x2, 0x3, 0x4, 0x5, 0x7, 0x8, 0x9, 0xa, 0x58, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x2e, 0x41, 0x31, 0x58, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x2e, 0x41, 0x32, 0x55, 0x41, 0x2e, 0x42, 0x2e, 0x42, 0x57, 0x41, 0x2e, 0x42, 0x2e, 0x43, 0x2e, 0x43, 0x53, 0x41, 0x2e, 0x41, 0x50, 0x55, 0x41, 0x2e, 0x43, 0x2e, 0x42, 0x55, 0x41, 0x2e, 0x43, 0x2e, 0x43, 0x8, 0x13, 0x1a, 0x21, 0x29, 0x30, 0x37, 0x40, 0x49, 0x52, 0x58, 0x60, 0x64, 0x65, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71}, - }, - }, - { - Name: "Arbitrary Byte Data", - Value: []byte{'h', 'e', 'l', 'l', 'o'}, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`<68656c6c 6f>`), - GNUStepFormat: []byte(`<68656c6c 6f>`), - XMLFormat: []byte(xmlPreamble + `aGVsbG8=`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 69, 104, 101, 108, 108, 111, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14}, - }, - }, - { - Name: "Arbitrary Integer Slice", - Value: []int{'h', 'e', 'l', 'l', 'o'}, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`(104,101,108,108,111,)`), - GNUStepFormat: []byte(`(<*I104>,<*I101>,<*I108>,<*I108>,<*I111>,)`), - XMLFormat: []byte(xmlPreamble + `104101108108111`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 165, 1, 2, 3, 3, 4, 16, 104, 16, 101, 16, 108, 16, 111, 8, 14, 16, 18, 20, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22}, - }, - }, - { - Name: "Arbitrary Integer Array", - Value: [3]int{'h', 'i', '!'}, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`(104,105,33,)`), - GNUStepFormat: []byte(`(<*I104>,<*I105>,<*I33>,)`), - XMLFormat: []byte(xmlPreamble + `10410533`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 163, 1, 2, 3, 16, 104, 16, 105, 16, 33, 8, 12, 14, 16, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18}, - }, - }, - { - Name: "Unsigned Integers of Increasing Size", - Value: []uint64{0xff, 0xfff, 0xffff, 0xfffff, 0xffffff, 0xfffffff, 0xffffffff, 0xffffffffffffffff}, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`(255,4095,65535,1048575,16777215,268435455,4294967295,18446744073709551615,)`), - GNUStepFormat: []byte(`(<*I255>,<*I4095>,<*I65535>,<*I1048575>,<*I16777215>,<*I268435455>,<*I4294967295>,<*I18446744073709551615>,)`), - XMLFormat: []byte(xmlPreamble + `255409565535104857516777215268435455429496729518446744073709551615`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 168, 1, 2, 3, 4, 5, 6, 7, 8, 16, 255, 17, 15, 255, 17, 255, 255, 18, 0, 15, 255, 255, 18, 0, 255, 255, 255, 18, 15, 255, 255, 255, 18, 255, 255, 255, 255, 19, 255, 255, 255, 255, 255, 255, 255, 255, 8, 17, 19, 22, 25, 30, 35, 40, 45, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54}, - }, - }, - { - Name: "Hexadecimal Integers", - Value: []int{'h', 'e', 'x', 'i', 'n', 't', -42}, - Documents: map[int][]byte{ - XMLFormat: []byte(xmlPreamble + `0x680X650x780X690x6e0X74-0x2a`), - }, - SkipEncode: map[int]bool{XMLFormat: true}, - }, - { - Name: "Octal Integers (treated as Decimal)", - Value: []int{'o', 'c', 't', 'i', 'n', 't', -42}, - Documents: map[int][]byte{ - XMLFormat: []byte(xmlPreamble + `01110990116010501100116-042`), - }, - SkipEncode: map[int]bool{XMLFormat: true}, - }, - { - Name: "Floats of Increasing Bitness", - Value: []interface{}{float32(math.MaxFloat32), float64(math.MaxFloat64)}, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`(3.4028234663852886e+38,1.7976931348623157e+308,)`), - GNUStepFormat: []byte(`(<*R3.4028234663852886e+38>,<*R1.7976931348623157e+308>,)`), - XMLFormat: []byte(xmlPreamble + `3.4028234663852886e+381.7976931348623157e+308`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 162, 1, 2, 34, 127, 127, 255, 255, 35, 127, 239, 255, 255, 255, 255, 255, 255, 8, 11, 16, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25}, - }, - // We can't store varying bitness in text formats. - SkipDecode: map[int]bool{XMLFormat: true, OpenStepFormat: true, GNUStepFormat: true}, - }, - { - Name: "Boolean True", - Value: true, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`1`), - GNUStepFormat: []byte(`<*BY>`), - XMLFormat: []byte(xmlPreamble + ``), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 9, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9}, - }, - }, - { - Name: "Floating-Point Value", - Value: 3.14159265358979323846264338327950288, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`3.141592653589793`), - GNUStepFormat: []byte(`<*R3.141592653589793>`), - XMLFormat: []byte(xmlPreamble + `3.141592653589793`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 35, 64, 9, 33, 251, 84, 68, 45, 24, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17}, - }, - }, - { - Name: "Map (containing arbitrary types)", - Value: map[string]interface{}{ - "float": 1.0, - "uint64": uint64(1), - }, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`{float=1;uint64=1;}`), - GNUStepFormat: []byte(`{float=<*R1>;uint64=<*I1>;}`), - XMLFormat: []byte(xmlPreamble + `float1uint641`), - BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd2, 0x1, 0x2, 0x3, 0x4, 0x55, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x23, 0x3f, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x1, 0x8, 0xd, 0x13, 0x1a, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25}, - }, - // Can't lax decode strings into numerics in a map (we don't know they want numbers) - SkipDecode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "Map (containing all variations of all types)", - Value: interface{}(map[string]interface{}{ - "intarray": []interface{}{ - int(1), - int8(8), - int16(16), - int32(32), - int64(64), - uint(2), - uint8(9), - uint16(17), - uint32(33), - uint64(65), - }, - "floats": []interface{}{ - float32(32.0), - float64(64.0), - }, - "booleans": []bool{ - true, - false, - }, - "strings": []string{ - "Hello, ASCII", - "Hello, 世界", - }, - "data": []byte{1, 2, 3, 4}, - "date": time.Date(2013, 11, 27, 0, 34, 0, 0, time.UTC), - }), - Documents: map[int][]byte{ - OpenStepFormat: []byte(`{booleans=(1,0,);data=<01020304>;date="2013-11-27 00:34:00 +0000";floats=(32,64,);intarray=(1,8,16,32,64,2,9,17,33,65,);strings=("Hello, ASCII","Hello, \U4e16\U754c",);}`), - GNUStepFormat: []byte(`{booleans=(<*BY>,<*BN>,);data=<01020304>;date=<*D2013-11-27 00:34:00 +0000>;floats=(<*R32>,<*R64>,);intarray=(<*I1>,<*I8>,<*I16>,<*I32>,<*I64>,<*I2>,<*I9>,<*I17>,<*I33>,<*I65>,);strings=("Hello, ASCII","Hello, \U4e16\U754c",);}`), - XMLFormat: []byte(xmlPreamble + `booleansdataAQIDBA==date2013-11-27T00:34:00Zfloats3264intarray1816326429173365stringsHello, ASCIIHello, 世界`), - BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd6, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xa, 0xb, 0xc, 0xf, 0x1a, 0x58, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x73, 0x54, 0x64, 0x61, 0x74, 0x61, 0x54, 0x64, 0x61, 0x74, 0x65, 0x56, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x73, 0x58, 0x69, 0x6e, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x57, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0xa2, 0x8, 0x9, 0x9, 0x8, 0x44, 0x1, 0x2, 0x3, 0x4, 0x33, 0x41, 0xb8, 0x45, 0x75, 0x78, 0x0, 0x0, 0x0, 0xa2, 0xd, 0xe, 0x22, 0x42, 0x0, 0x0, 0x0, 0x23, 0x40, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaa, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x10, 0x1, 0x10, 0x8, 0x10, 0x10, 0x10, 0x20, 0x10, 0x40, 0x10, 0x2, 0x10, 0x9, 0x10, 0x11, 0x10, 0x21, 0x10, 0x41, 0xa2, 0x1b, 0x1c, 0x5c, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x41, 0x53, 0x43, 0x49, 0x49, 0x69, 0x0, 0x48, 0x0, 0x65, 0x0, 0x6c, 0x0, 0x6c, 0x0, 0x6f, 0x0, 0x2c, 0x0, 0x20, 0x4e, 0x16, 0x75, 0x4c, 0x8, 0x15, 0x1e, 0x23, 0x28, 0x2f, 0x38, 0x40, 0x43, 0x44, 0x45, 0x4a, 0x53, 0x56, 0x5b, 0x64, 0x6f, 0x71, 0x73, 0x75, 0x77, 0x79, 0x7b, 0x7d, 0x7f, 0x81, 0x83, 0x86, 0x93, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa6}, - }, - SkipDecode: map[int]bool{OpenStepFormat: true, GNUStepFormat: true, XMLFormat: true, BinaryFormat: true}, - }, - { - Name: "Map (containing nil)", - Value: map[string]interface{}{ - "float": 1.5, - "uint64": uint64(1), - "nil": nil, - }, - DecodeValue: map[string]interface{}{ - "float": 1.5, - "uint64": uint64(1), - }, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`{float=1.5;uint64=1;}`), - GNUStepFormat: []byte(`{float=<*R1.5>;uint64=<*I1>;}`), - XMLFormat: []byte(xmlPreamble + `float1.5uint641`), - BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd2, 0x1, 0x2, 0x3, 0x4, 0x55, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x56, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x23, 0x3f, 0xf8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x1, 0x8, 0xd, 0x13, 0x1a, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25}, - }, - // Can't lax decode strings into numerics in a map (we don't know they want numbers) - SkipDecode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "Pointer to structure with plist tags", - Value: &SparseBundleHeader{ - InfoDictionaryVersion: "6.0", - BandSize: 8388608, - Size: 4 * 1048576 * 1024 * 1024, - DiskImageBundleType: "com.apple.diskimage.sparsebundle", - BackingStoreVersion: 1, - }, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`{CFBundleInfoDictionaryVersion="6.0";"band-size"=8388608;"bundle-backingstore-version"=1;"diskimage-bundle-type"="com.apple.diskimage.sparsebundle";size=4398046511104;}`), - GNUStepFormat: []byte(`{CFBundleInfoDictionaryVersion=6.0;band-size=<*I8388608>;bundle-backingstore-version=<*I1>;diskimage-bundle-type=com.apple.diskimage.sparsebundle;size=<*I4398046511104>;}`), - XMLFormat: []byte(xmlPreamble + `CFBundleInfoDictionaryVersion6.0band-size8388608bundle-backingstore-version1diskimage-bundle-typecom.apple.diskimage.sparsebundlesize4398046511104`), - BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd5, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0x5f, 0x10, 0x1d, 0x43, 0x46, 0x42, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x44, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x72, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x59, 0x62, 0x61, 0x6e, 0x64, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x5f, 0x10, 0x1b, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2d, 0x62, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x10, 0x15, 0x64, 0x69, 0x73, 0x6b, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2d, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x54, 0x73, 0x69, 0x7a, 0x65, 0x53, 0x36, 0x2e, 0x30, 0x12, 0x0, 0x80, 0x0, 0x0, 0x10, 0x1, 0x5f, 0x10, 0x20, 0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x2e, 0x64, 0x69, 0x73, 0x6b, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2e, 0x73, 0x70, 0x61, 0x72, 0x73, 0x65, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x13, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x13, 0x33, 0x3d, 0x5b, 0x73, 0x78, 0x7c, 0x81, 0x83, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xaf}, - }, - SkipDecode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "Array of byte arrays", - Value: [][]byte{ - []byte("Hello"), - []byte("World"), - }, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`(<48656c6c 6f>,<576f726c 64>,)`), - GNUStepFormat: []byte(`(<48656c6c 6f>,<576f726c 64>,)`), - XMLFormat: []byte(xmlPreamble + `SGVsbG8=V29ybGQ=`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 162, 1, 2, 69, 72, 101, 108, 108, 111, 69, 87, 111, 114, 108, 100, 8, 11, 17, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23}, - }, - }, - { - Name: "Date", - Value: time.Date(2013, 11, 27, 0, 34, 0, 0, time.UTC), - Documents: map[int][]byte{ - OpenStepFormat: []byte(`"2013-11-27 00:34:00 +0000"`), - GNUStepFormat: []byte(`<*D2013-11-27 00:34:00 +0000>`), - XMLFormat: []byte(xmlPreamble + `2013-11-27T00:34:00Z`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 51, 65, 184, 69, 117, 120, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17}, - }, - }, - { - Name: "Floating-Point NaN", - Value: math.NaN(), - Documents: map[int][]byte{ - OpenStepFormat: []byte(`NaN`), - GNUStepFormat: []byte(`<*RNaN>`), - XMLFormat: []byte(xmlPreamble + `nan`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 35, 127, 248, 0, 0, 0, 0, 0, 1, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17}, - }, - SkipDecode: map[int]bool{OpenStepFormat: true, GNUStepFormat: true, XMLFormat: true, BinaryFormat: true}, - }, - { - Name: "Floating-Point Infinity", - Value: math.Inf(1), - Documents: map[int][]byte{ - OpenStepFormat: []byte(`+Inf`), - GNUStepFormat: []byte(`<*R+Inf>`), - XMLFormat: []byte(xmlPreamble + `inf`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 35, 127, 240, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17}, - }, - }, - { - Name: "Floating-Point Negative Infinity", - Value: math.Inf(-1), - Documents: map[int][]byte{ - OpenStepFormat: []byte(`-Inf`), - GNUStepFormat: []byte(`<*R-Inf>`), - XMLFormat: []byte(xmlPreamble + `-inf`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 35, 255, 240, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17}, - }, - }, - { - Name: "UTF-8 string", - Value: []string{"Hello, ASCII", "Hello, 世界"}, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`("Hello, ASCII","Hello, \U4e16\U754c",)`), - GNUStepFormat: []byte(`("Hello, ASCII","Hello, \U4e16\U754c",)`), - XMLFormat: []byte(xmlPreamble + `Hello, ASCIIHello, 世界`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 162, 1, 2, 92, 72, 101, 108, 108, 111, 44, 32, 65, 83, 67, 73, 73, 105, 0, 72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 44, 0, 32, 78, 22, 117, 76, 8, 11, 24, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43}, - }, - }, - { - Name: "An array containing more than fifteen items", - Value: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,)`), - GNUStepFormat: []byte(`(<*I1>,<*I2>,<*I3>,<*I4>,<*I5>,<*I6>,<*I7>,<*I8>,<*I9>,<*I10>,<*I11>,<*I12>,<*I13>,<*I14>,<*I15>,<*I16>,)`), - XMLFormat: []byte(xmlPreamble + `12345678910111213141516`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 175, 16, 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 1, 16, 2, 16, 3, 16, 4, 16, 5, 16, 6, 16, 7, 16, 8, 16, 9, 16, 10, 16, 11, 16, 12, 16, 13, 16, 14, 16, 15, 16, 16, 8, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59}, - }, - }, - { - Name: "TextMarshaler/TextUnmarshaler", - Value: TextMarshalingBool{true}, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`truthful`), - GNUStepFormat: []byte(`truthful`), - XMLFormat: []byte(xmlPreamble + `truthful`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 88, 116, 114, 117, 116, 104, 102, 117, 108, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17}, - }, - // We expect false here because the non-pointer version cannot mutate itself. - }, - { - Name: "TextMarshaler/TextUnmarshaler via Pointer", - Value: &TextMarshalingBoolViaPointer{false}, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`unimaginable`), - GNUStepFormat: []byte(`unimaginable`), - XMLFormat: []byte(xmlPreamble + `unimaginable`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 92, 117, 110, 105, 109, 97, 103, 105, 110, 97, 98, 108, 101, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21}, - }, - DecodeValue: TextMarshalingBoolViaPointer{false}, - }, - { - Name: "Duplicated Values", - Value: []interface{}{ - "Hello", - float32(32.0), - float64(32.0), - []byte("data"), - float32(64.0), - float64(64.0), - uint64(100), - float32(32.0), - time.Date(2013, 11, 27, 0, 34, 0, 0, time.UTC), - float64(32.0), - float32(64.0), - float64(64.0), - "Hello", - []byte("data"), - uint64(100), - time.Date(2013, 11, 27, 0, 34, 0, 0, time.UTC), - }, - Documents: map[int][]byte{ - BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xaf, 0x10, 0x10, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x2, 0x8, 0x3, 0x5, 0x6, 0x1, 0x4, 0x7, 0x8, 0x55, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x22, 0x42, 0x0, 0x0, 0x0, 0x23, 0x40, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x64, 0x61, 0x74, 0x61, 0x22, 0x42, 0x80, 0x0, 0x0, 0x23, 0x40, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x64, 0x33, 0x41, 0xb8, 0x45, 0x75, 0x78, 0x0, 0x0, 0x0, 0x8, 0x1b, 0x21, 0x26, 0x2f, 0x34, 0x39, 0x42, 0x44, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4d}, - }, - }, - { - Name: "Funny Characters", - Value: map[string]string{ - "\a": "\b", - "\v": "\f", - "\\": "\"", - "\t\r": "\n", - "\u00C8": "wat", - "\u0100": "hundred", - }, - Documents: map[int][]byte{ - // Hard to encode these in a raw string ;P - OpenStepFormat: []byte{0x7b, 0x22, 0x5c, 0x61, 0x22, 0x3d, 0x22, 0x5c, 0x62, 0x22, 0x3b, 0x22, 0x9, 0xd, 0x22, 0x3d, 0x22, 0xa, 0x22, 0x3b, 0x22, 0x5c, 0x76, 0x22, 0x3d, 0x22, 0x5c, 0x66, 0x22, 0x3b, 0x22, 0x5c, 0x5c, 0x22, 0x3d, 0x22, 0x5c, 0x22, 0x22, 0x3b, 0x22, 0x5c, 0x33, 0x31, 0x30, 0x22, 0x3d, 0x77, 0x61, 0x74, 0x3b, 0x22, 0x5c, 0x55, 0x30, 0x31, 0x30, 0x30, 0x22, 0x3d, 0x68, 0x75, 0x6e, 0x64, 0x72, 0x65, 0x64, 0x3b, 0x7d}, - GNUStepFormat: []byte{0x7b, 0x22, 0x5c, 0x61, 0x22, 0x3d, 0x22, 0x5c, 0x62, 0x22, 0x3b, 0x22, 0x9, 0xd, 0x22, 0x3d, 0x22, 0xa, 0x22, 0x3b, 0x22, 0x5c, 0x76, 0x22, 0x3d, 0x22, 0x5c, 0x66, 0x22, 0x3b, 0x22, 0x5c, 0x5c, 0x22, 0x3d, 0x22, 0x5c, 0x22, 0x22, 0x3b, 0x22, 0x5c, 0x33, 0x31, 0x30, 0x22, 0x3d, 0x77, 0x61, 0x74, 0x3b, 0x22, 0x5c, 0x55, 0x30, 0x31, 0x30, 0x30, 0x22, 0x3d, 0x68, 0x75, 0x6e, 0x64, 0x72, 0x65, 0x64, 0x3b, 0x7d}, - }, - }, - { - Name: "Signed Integers", - Value: []int64{-1, -127, -255, -32767, -65535}, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`(-1,-127,-255,-32767,-65535,)`), - GNUStepFormat: []byte(`(<*I-1>,<*I-127>,<*I-255>,<*I-32767>,<*I-65535>,)`), - XMLFormat: []byte(xmlPreamble + `-1-127-255-32767-65535`), - BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xa5, 0x1, 0x2, 0x3, 0x4, 0x5, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x1, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x1, 0x8, 0xe, 0x17, 0x20, 0x29, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b}, - }, - }, - { - Name: "A map with a blank key", - Value: map[string]string{ - "": "Hello", - }, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`{""=Hello;}`), - GNUStepFormat: []byte(`{""=Hello;}`), - XMLFormat: []byte(xmlPreamble + `Hello`), - BinaryFormat: []byte{98, 112, 108, 105, 115, 116, 48, 48, 209, 1, 2, 80, 85, 72, 101, 108, 108, 111, 8, 11, 12, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18}, - }, - }, - { - Name: "CF Keyed Archiver UIDs (interface{})", - Value: []UID{ - 0xff, - 0xffff, - 0xffffff, - 0xffffffff, - 0xffffffffff, - }, - Documents: map[int][]byte{ - XMLFormat: []byte(xmlPreamble + `CF$UID255CF$UID65535CF$UID16777215CF$UID4294967295CF$UID1099511627775`), - BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xa5, 0x01, 0x02, 0x03, 0x04, 0x05, 0x80, 0xff, 0x81, 0xff, 0xff, 0x83, 0x00, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, 0xff, 0x87, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x0e, 0x10, 0x13, 0x18, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26}, - }, - }, - { - Name: "CF Keyed Archiver UID (struct)", - Value: struct { - U UID `plist:"identifier"` - }{ - U: 1024, - }, - Documents: map[int][]byte{ - XMLFormat: []byte(xmlPreamble + `identifierCF$UID1024`), - BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd1, 0x01, 0x02, 0x5a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x81, 0x04, 0x00, 0x08, 0x0b, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19}, - }, - }, - { - Name: "CF Keyed Archiver UID as Legacy Int", - Value: struct { - U UID `plist:"identifier"` - }{ - U: 1024, - }, - Documents: map[int][]byte{ - XMLFormat: []byte(xmlPreamble + `identifierCF$UID1024`), - BinaryFormat: []byte{0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd1, 0x01, 0x02, 0x5a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x81, 0x04, 0x00, 0x08, 0x0b, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19}, - }, - DecodeValue: struct { - U uint64 `plist:"identifier"` - }{ - U: 1024, - }, - }, - { - Name: "Custom Marshaller/Unmarshaller by Value", - Value: []ArrayThatSerializesAsOneObject{ - ArrayThatSerializesAsOneObject{[]uint64{100}}, - ArrayThatSerializesAsOneObject{[]uint64{2, 4, 6, 8}}, - }, - Documents: map[int][]byte{ - GNUStepFormat: []byte(`(<*I100>,(<*I2>,<*I4>,<*I6>,<*I8>,),)`), - }, - }, - { - Name: "Custom Marshaller/Unmarshaller by Pointer", - Value: &PlistMarshalingBoolByPointer{true}, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`-1`), - GNUStepFormat: []byte(`<*I-1>`), - }, - }, - { - Name: "Type implementing both Text and Plist Marshaler", - Value: &BothMarshaler{}, - Documents: map[int][]byte{ - GNUStepFormat: []byte(`{a=b;}`), - }, - }, - { - Name: "Type implementing both Text and Plist Unmarshaler", - Value: &BothUnmarshaler{int64(1024)}, - Documents: map[int][]byte{ - GNUStepFormat: []byte(`{blah=<*I1024>;}`), - }, - DecodeValue: &BothUnmarshaler{int64(0)}, - }, - { - Name: "Comments", - Value: struct { - A, B, C int - S, S2 string - }{ - 1, 2, 3, - "/not/a/comment/", "/not*a/*comm*en/t", - }, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`{ - A=1 /* A is 1 because it is the first letter */; - B=2; // B is 2 because comment-to-end-of-line. - C=3; - S = /not/a/comment/; - S2 = /not*a/*comm*en/t; - }`), - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "Escapes", - Value: struct { - W, A, B, V, F, T, R, N, Hex1, Unicode1, Unicode2, Octal1 string - }{ - "w", "\a", "\b", "\v", "\f", "\t", "\r", "\n", "\u00ab", "\u00ac", "\u00ad", "\033", - }, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`{ - W="\w"; - A="\a"; - B="\b"; - V="\v"; - F="\f"; - T="\t"; - R="\r"; - N="\n"; - Hex1="\xAB"; - Unicode1="\u00AC"; - Unicode2="\U00AD"; - Octal1="\033"; - }`), - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "Empty Strings in Arrays", - Value: []string{"A"}, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`(A,,,"",)`), - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "Empty Data", - Value: []byte{}, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`<>`), - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "UTF-8 with BOM", - Value: "Hello", - Documents: map[int][]byte{ - OpenStepFormat: []byte("\uFEFFHello"), - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "UTF-16LE with BOM", - Value: "Hello", - Documents: map[int][]byte{ - OpenStepFormat: []byte{0xFF, 0xFE, 'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o', 0}, - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "UTF-16BE with BOM", - Value: "Hello", - Documents: map[int][]byte{ - OpenStepFormat: []byte{0xFE, 0xFF, 0, 'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o'}, - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "UTF-16LE without BOM", - Value: "Hello", - Documents: map[int][]byte{ - OpenStepFormat: []byte{'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o', 0}, - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "UTF-16BE without BOM", - Value: "Hello", - Documents: map[int][]byte{ - OpenStepFormat: []byte{0, 'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o'}, - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "UTF-16BE with High Characters", - Value: "Hello, 世界", - Documents: map[int][]byte{ - OpenStepFormat: []byte{0, '"', 0, 'H', 0, 'e', 0, 'l', 0, 'l', 0, 'o', 0, ',', 0, ' ', 0x4E, 0x16, 0x75, 0x4C, 0, '"'}, - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "Legacy Strings File Format (No Dictionary)", - Value: map[string]string{ - "Key": "Value", - "Key2": "Value2", - }, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`"Key" = "Value"; - "Key2" = "Value2";`), - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "Strings File Shortcut Format (No Values)", - Value: map[string]string{ - "Key": "Key", - "Key2": "Key2", - }, - Documents: map[int][]byte{ - OpenStepFormat: []byte(`"Key"; - "Key2";`), - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "Various Truncated Escapes", - Value: "\x01\x02\x03\x04\x057", - Documents: map[int][]byte{ - OpenStepFormat: []byte(`"\x1\u02\U003\4\0057"`), - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "Various Case-Insensitive Escapes", - Value: "\u00AB\uCDEF", - Documents: map[int][]byte{ - OpenStepFormat: []byte(`"\xaB\uCdEf"`), - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "Text data long enough to trigger implementation-specific reallocation", // this is for coverage :( - Value: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - Documents: map[int][]byte{ - OpenStepFormat: []byte("<0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001>"), - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "Empty Text Document", - Value: map[string]interface{}{}, // Defined to be an empty dictionary - Documents: map[int][]byte{ - OpenStepFormat: []byte{}, - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, - { - Name: "Text document consisting of only whitespace", - Value: map[string]interface{}{}, // Defined to be an empty dictionary - Documents: map[int][]byte{ - OpenStepFormat: []byte(" \n\t"), - }, - SkipEncode: map[int]bool{OpenStepFormat: true}, - }, -} - -type EverythingTestData struct { - Intarray []uint64 `plist:"intarray"` - Floats []float64 `plist:"floats"` - Booleans []bool `plist:"booleans"` - Strings []string `plist:"strings"` - Dat []byte `plist:"data"` - Date time.Time `plist:"date"` -} - -var plistValueTreeRawData = &EverythingTestData{ - Intarray: []uint64{1, 8, 16, 32, 64, 2, 9, 17, 33, 65}, - Floats: []float64{32.0, 64.0}, - Booleans: []bool{true, false}, - Strings: []string{"Hello, ASCII", "Hello, 世界"}, - Dat: []byte{1, 2, 3, 4}, - Date: time.Date(2013, 11, 27, 0, 34, 0, 0, time.UTC), -} -var plistValueTree cfValue -var plistValueTreeAsBplist = []byte{98, 112, 108, 105, 115, 116, 48, 48, 214, 1, 13, 17, 21, 25, 27, 2, 14, 18, 22, 26, 28, 88, 105, 110, 116, 97, 114, 114, 97, 121, 170, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 16, 1, 16, 8, 16, 16, 16, 32, 16, 64, 16, 2, 16, 9, 16, 17, 16, 33, 16, 65, 86, 102, 108, 111, 97, 116, 115, 162, 15, 16, 34, 66, 0, 0, 0, 35, 64, 80, 0, 0, 0, 0, 0, 0, 88, 98, 111, 111, 108, 101, 97, 110, 115, 162, 19, 20, 9, 8, 87, 115, 116, 114, 105, 110, 103, 115, 162, 23, 24, 92, 72, 101, 108, 108, 111, 44, 32, 65, 83, 67, 73, 73, 105, 0, 72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 44, 0, 32, 78, 22, 117, 76, 84, 100, 97, 116, 97, 68, 1, 2, 3, 4, 84, 100, 97, 116, 101, 51, 65, 184, 69, 117, 120, 0, 0, 0, 8, 21, 30, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 68, 71, 76, 85, 94, 97, 98, 99, 107, 110, 123, 142, 147, 152, 157, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166} -var plistValueTreeAsXML = xmlPreamble + `intarray1816326429173365floats3264booleansstringsHello, ASCIIHello, 世界dataAQIDBA==date2013-11-27T00:34:00Z` -var plistValueTreeAsOpenStep = `{booleans=(1,0,);data=<01020304>;date="2013-11-27 00:34:00 +0000";floats=(32,64,);intarray=(1,8,16,32,64,2,9,17,33,65,);strings=("Hello, ASCII","Hello, \U4e16\U754c",);}` -var plistValueTreeAsGNUStep = `{booleans=(<*BY>,<*BN>,);data=<01020304>;date=<*D2013-11-27 00:34:00 +0000>;floats=(<*R32>,<*R64>,);intarray=(<*I1>,<*I8>,<*I16>,<*I32>,<*I64>,<*I2>,<*I9>,<*I17>,<*I33>,<*I65>,);strings=("Hello, ASCII","Hello, \U4e16\U754c",);}` - -type LaxTestData struct { - I64 int64 - U64 uint64 - F64 float64 - B bool - D time.Time -} - -var laxTestData = LaxTestData{1, 2, 3.0, true, time.Date(2013, 11, 27, 0, 34, 0, 0, time.UTC)} - -func setupPlistValues() { - plistValueTree = &cfDictionary{ - keys: []string{ - "intarray", - "floats", - "booleans", - "strings", - "data", - "date", - }, - values: []cfValue{ - &cfArray{ - values: []cfValue{ - &cfNumber{value: 1}, - &cfNumber{value: 8}, - &cfNumber{value: 16}, - &cfNumber{value: 32}, - &cfNumber{value: 64}, - &cfNumber{value: 2}, - &cfNumber{value: 8}, - &cfNumber{value: 17}, - &cfNumber{value: 33}, - &cfNumber{value: 65}, - }, - }, - &cfArray{ - values: []cfValue{ - &cfReal{wide: false, value: 32.0}, - &cfReal{wide: true, value: 64.0}, - }, - }, - &cfArray{ - values: []cfValue{ - cfBoolean(true), - cfBoolean(false), - }, - }, - &cfArray{ - values: []cfValue{ - cfString("Hello, ASCII"), - cfString("Hello, 世界"), - }, - }, - cfData{1, 2, 3, 4}, - cfDate(time.Date(2013, 11, 27, 0, 32, 0, 0, time.UTC)), - }, - } -} - -func init() { - setupPlistValues() - - // Pre-warm the type info struct to remove it from benchmarking - getTypeInfo(reflect.ValueOf(plistValueTreeRawData).Type()) -} diff --git a/vendor/howett.net/plist/decode_test.go b/vendor/howett.net/plist/decode_test.go deleted file mode 100644 index aabc509e..00000000 --- a/vendor/howett.net/plist/decode_test.go +++ /dev/null @@ -1,239 +0,0 @@ -package plist - -import ( - "bytes" - "fmt" - "reflect" - "testing" -) - -func BenchmarkXMLDecode(b *testing.B) { - for i := 0; i < b.N; i++ { - b.StopTimer() - var bval interface{} - buf := bytes.NewReader([]byte(plistValueTreeAsXML)) - b.StartTimer() - decoder := NewDecoder(buf) - decoder.Decode(bval) - b.StopTimer() - } -} - -func BenchmarkBplistDecode(b *testing.B) { - for i := 0; i < b.N; i++ { - b.StopTimer() - var bval interface{} - buf := bytes.NewReader(plistValueTreeAsBplist) - b.StartTimer() - decoder := NewDecoder(buf) - decoder.Decode(bval) - b.StopTimer() - } -} - -func TestLaxDecode(t *testing.T) { - var laxTestDataStringsOnlyAsXML = `{B=1;D="2013-11-27 00:34:00 +0000";I64=1;F64="3.0";U64=2;}` - d := LaxTestData{} - buf := bytes.NewReader([]byte(laxTestDataStringsOnlyAsXML)) - decoder := NewDecoder(buf) - decoder.lax = true - err := decoder.Decode(&d) - if err != nil { - t.Error(err.Error()) - } - - if d != laxTestData { - t.Logf("Expected: %#v", laxTestData) - t.Logf("Received: %#v", d) - t.Fail() - } -} - -func TestIllegalLaxDecode(t *testing.T) { - i := int64(0) - u := uint64(0) - f := float64(0) - b := false - plists := []struct { - pl string - d interface{} - }{ - {"abc", &i}, - {"abc", &u}, - {"def", &f}, - {"ghi", &b}, - {"jkl", []byte{0x00}}, - } - - for _, plist := range plists { - buf := bytes.NewReader([]byte(plist.pl)) - decoder := NewDecoder(buf) - decoder.lax = true - err := decoder.Decode(plist.d) - t.Logf("Error: %v", err) - if err == nil { - t.Error("Expected error, received nothing.") - } - } -} - -func TestIllegalDecode(t *testing.T) { - i := int64(0) - b := false - plists := []struct { - pl string - d interface{} - }{ - {"abc", &i}, - {"ABC=", &i}, - {"34.1", &i}, - {"def", &i}, - {"2010-01-01T00:00:00Z", &i}, - {"0", &b}, - {"0", &b}, - {"a0", &b}, - {"", &[1]int{1}}, - } - - for _, plist := range plists { - buf := bytes.NewReader([]byte(plist.pl)) - decoder := NewDecoder(buf) - err := decoder.Decode(plist.d) - t.Logf("Error: %v", err) - if err == nil { - t.Error("Expected error, received nothing.") - } - } -} - -func TestDecode(t *testing.T) { - for _, test := range tests { - subtest(t, test.Name, func(t *testing.T) { - expVal := test.DecodeValue - if expVal == nil { - expVal = test.Value - } - - expReflect := reflect.ValueOf(expVal) - if !expReflect.IsValid() || isEmptyInterface(expReflect) { - return - } - if expReflect.Kind() == reflect.Ptr || expReflect.Kind() == reflect.Interface { - // Unbox pointer for comparison's sake - expReflect = expReflect.Elem() - } - expVal = expReflect.Interface() - - results := make(map[int]interface{}) - for fmt, doc := range test.Documents { - if test.SkipDecode[fmt] { - return - } - subtest(t, FormatNames[fmt], func(t *testing.T) { - val := reflect.New(expReflect.Type()).Interface() - _, err := Unmarshal(doc, val) - if err != nil { - t.Error(err) - } - - valReflect := reflect.ValueOf(val) - if valReflect.Kind() == reflect.Ptr || valReflect.Kind() == reflect.Interface { - // Unbox pointer for comparison's sake - valReflect = valReflect.Elem() - val = valReflect.Interface() - } - - results[fmt] = val - if !reflect.DeepEqual(expVal, val) { - t.Logf("Expected: %#v\n", expVal) - t.Logf("Received: %#v\n", val) - t.Fail() - } - }) - } - - if results[BinaryFormat] != nil && results[XMLFormat] != nil { - if !reflect.DeepEqual(results[BinaryFormat], results[XMLFormat]) { - t.Log("Binary and XML decoding yielded different values.") - t.Log("Binary:", results[BinaryFormat]) - t.Log("XML :", results[XMLFormat]) - t.Fail() - } - } - }) - } -} - -func TestInterfaceDecode(t *testing.T) { - var xval interface{} - buf := bytes.NewReader([]byte{98, 112, 108, 105, 115, 116, 48, 48, 214, 1, 13, 17, 21, 25, 27, 2, 14, 18, 22, 26, 28, 88, 105, 110, 116, 97, 114, 114, 97, 121, 170, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 16, 1, 16, 8, 16, 16, 16, 32, 16, 64, 16, 2, 16, 9, 16, 17, 16, 33, 16, 65, 86, 102, 108, 111, 97, 116, 115, 162, 15, 16, 34, 66, 0, 0, 0, 35, 64, 80, 0, 0, 0, 0, 0, 0, 88, 98, 111, 111, 108, 101, 97, 110, 115, 162, 19, 20, 9, 8, 87, 115, 116, 114, 105, 110, 103, 115, 162, 23, 24, 92, 72, 101, 108, 108, 111, 44, 32, 65, 83, 67, 73, 73, 105, 0, 72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 44, 0, 32, 78, 22, 117, 76, 84, 100, 97, 116, 97, 68, 1, 2, 3, 4, 84, 100, 97, 116, 101, 51, 65, 184, 69, 117, 120, 0, 0, 0, 8, 21, 30, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 68, 71, 76, 85, 94, 97, 98, 99, 107, 110, 123, 142, 147, 152, 157, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 166}) - decoder := NewDecoder(buf) - err := decoder.Decode(&xval) - if err != nil { - t.Log("Error:", err) - t.Fail() - } -} - -func TestFormatDetection(t *testing.T) { - type formatTest struct { - expectedFormat int - data []byte - } - plists := []formatTest{ - {BinaryFormat, []byte{98, 112, 108, 105, 115, 116, 48, 48, 85, 72, 101, 108, 108, 111, 8, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14}}, - {XMLFormat, []byte(`<*I3>`)}, - {InvalidFormat, []byte(`bplist00`)}, // Looks like a binary property list, and bplist does not have fallbacks(!) - {OpenStepFormat, []byte(`(1,2,3,4,5)`)}, - {OpenStepFormat, []byte(``)}, - {GNUStepFormat, []byte(`(1,2,<*I3>)`)}, - {InvalidFormat, []byte{0x00}}, // This isn't a valid property list of any sort. - } - - for i, fmttest := range plists { - fmt, err := Unmarshal(fmttest.data, nil) - if fmt != fmttest.expectedFormat { - t.Errorf("plist %d: Wanted %s, received %s.", i, FormatNames[fmttest.expectedFormat], FormatNames[fmt]) - } - if err != nil { - t.Logf("plist %d: Error: %v", i, err) - } - } -} - -func ExampleDecoder_Decode() { - type sparseBundleHeader struct { - InfoDictionaryVersion string `plist:"CFBundleInfoDictionaryVersion"` - BandSize uint64 `plist:"band-size"` - BackingStoreVersion int `plist:"bundle-backingstore-version"` - DiskImageBundleType string `plist:"diskimage-bundle-type"` - Size uint64 `plist:"size"` - } - - buf := bytes.NewReader([]byte(` - - - - CFBundleInfoDictionaryVersion - 6.0 - band-size - 8388608 - bundle-backingstore-version - 1 - diskimage-bundle-type - com.apple.diskimage.sparsebundle - size - 4398046511104 - -`)) - - var data sparseBundleHeader - decoder := NewDecoder(buf) - err := decoder.Decode(&data) - if err != nil { - fmt.Println(err) - } - fmt.Println(data) - - // Output: {6.0 8388608 1 com.apple.diskimage.sparsebundle 4398046511104} -} diff --git a/vendor/howett.net/plist/encode_test.go b/vendor/howett.net/plist/encode_test.go deleted file mode 100644 index 32c613f8..00000000 --- a/vendor/howett.net/plist/encode_test.go +++ /dev/null @@ -1,155 +0,0 @@ -package plist - -import ( - "bytes" - "fmt" - "testing" -) - -func BenchmarkXMLEncode(b *testing.B) { - for i := 0; i < b.N; i++ { - NewEncoder(&bytes.Buffer{}).Encode(plistValueTreeRawData) - } -} - -func BenchmarkBplistEncode(b *testing.B) { - for i := 0; i < b.N; i++ { - NewBinaryEncoder(&bytes.Buffer{}).Encode(plistValueTreeRawData) - } -} - -func BenchmarkOpenStepEncode(b *testing.B) { - for i := 0; i < b.N; i++ { - NewEncoderForFormat(&bytes.Buffer{}, OpenStepFormat).Encode(plistValueTreeRawData) - } -} - -func TestEncode(t *testing.T) { - for _, test := range tests { - subtest(t, test.Name, func(t *testing.T) { - for fmt, doc := range test.Documents { - if test.SkipEncode[fmt] { - continue - } - subtest(t, FormatNames[fmt], func(t *testing.T) { - encoded, err := Marshal(test.Value, fmt) - - if err != nil { - t.Error(err) - } - - if !bytes.Equal(doc, encoded) { - printype := "%s" - if fmt == BinaryFormat { - printype = "%2x" - } - t.Logf("Value: %#v", test.Value) - t.Logf("Expected: "+printype+"\n", doc) - t.Logf("Received: "+printype+"\n", doc) - t.Fail() - } - }) - } - }) - } -} - -func ExampleEncoder_Encode() { - type sparseBundleHeader struct { - InfoDictionaryVersion string `plist:"CFBundleInfoDictionaryVersion"` - BandSize uint64 `plist:"band-size"` - BackingStoreVersion int `plist:"bundle-backingstore-version"` - DiskImageBundleType string `plist:"diskimage-bundle-type"` - Size uint64 `plist:"size"` - } - data := &sparseBundleHeader{ - InfoDictionaryVersion: "6.0", - BandSize: 8388608, - Size: 4 * 1048576 * 1024 * 1024, - DiskImageBundleType: "com.apple.diskimage.sparsebundle", - BackingStoreVersion: 1, - } - - buf := &bytes.Buffer{} - encoder := NewEncoder(buf) - err := encoder.Encode(data) - if err != nil { - fmt.Println(err) - } - fmt.Println(buf.String()) - - // Output: - // - // CFBundleInfoDictionaryVersion6.0band-size8388608bundle-backingstore-version1diskimage-bundle-typecom.apple.diskimage.sparsebundlesize4398046511104 -} - -func ExampleMarshal_xml() { - type sparseBundleHeader struct { - InfoDictionaryVersion string `plist:"CFBundleInfoDictionaryVersion"` - BandSize uint64 `plist:"band-size"` - BackingStoreVersion int `plist:"bundle-backingstore-version"` - DiskImageBundleType string `plist:"diskimage-bundle-type"` - Size uint64 `plist:"size"` - } - data := &sparseBundleHeader{ - InfoDictionaryVersion: "6.0", - BandSize: 8388608, - Size: 4 * 1048576 * 1024 * 1024, - DiskImageBundleType: "com.apple.diskimage.sparsebundle", - BackingStoreVersion: 1, - } - - plist, err := MarshalIndent(data, XMLFormat, "\t") - if err != nil { - fmt.Println(err) - } - fmt.Println(string(plist)) - - // Output: - // - // - // - // CFBundleInfoDictionaryVersion - // 6.0 - // band-size - // 8388608 - // bundle-backingstore-version - // 1 - // diskimage-bundle-type - // com.apple.diskimage.sparsebundle - // size - // 4398046511104 - // - // -} - -func ExampleMarshal_gnustep() { - type sparseBundleHeader struct { - InfoDictionaryVersion string `plist:"CFBundleInfoDictionaryVersion"` - BandSize uint64 `plist:"band-size"` - BackingStoreVersion int `plist:"bundle-backingstore-version"` - DiskImageBundleType string `plist:"diskimage-bundle-type"` - Size uint64 `plist:"size"` - } - data := &sparseBundleHeader{ - InfoDictionaryVersion: "6.0", - BandSize: 8388608, - Size: 4 * 1048576 * 1024 * 1024, - DiskImageBundleType: "com.apple.diskimage.sparsebundle", - BackingStoreVersion: 1, - } - - plist, err := MarshalIndent(data, GNUStepFormat, "\t") - if err != nil { - fmt.Println(err) - } - fmt.Println(string(plist)) - - // Output: { - // CFBundleInfoDictionaryVersion = 6.0; - // band-size = <*I8388608>; - // bundle-backingstore-version = <*I1>; - // diskimage-bundle-type = com.apple.diskimage.sparsebundle; - // size = <*I4398046511104>; - // } -} diff --git a/vendor/howett.net/plist/example_custom_marshaler_test.go b/vendor/howett.net/plist/example_custom_marshaler_test.go deleted file mode 100644 index d8e8f69d..00000000 --- a/vendor/howett.net/plist/example_custom_marshaler_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package plist_test - -import ( - "encoding/base64" - "fmt" - - "howett.net/plist" -) - -type Base64String string - -func (e Base64String) MarshalPlist() (interface{}, error) { - return base64.StdEncoding.EncodeToString([]byte(e)), nil -} - -func (e *Base64String) UnmarshalPlist(unmarshal func(interface{}) error) error { - var b64 string - if err := unmarshal(&b64); err != nil { - return err - } - - bytes, err := base64.StdEncoding.DecodeString(b64) - if err != nil { - return err - } - - *e = Base64String(bytes) - return nil -} - -func Example() { - s := Base64String("Dustin") - - data, err := plist.Marshal(&s, plist.OpenStepFormat) - if err != nil { - panic(err) - } - - fmt.Println("Property List:", string(data)) - - var decoded Base64String - _, err = plist.Unmarshal(data, &decoded) - if err != nil { - panic(err) - } - - fmt.Println("Raw Data:", string(decoded)) - - // Output: - // Property List: RHVzdGlu - // Raw Data: Dustin -} diff --git a/vendor/howett.net/plist/go.mod b/vendor/howett.net/plist/go.mod new file mode 100644 index 00000000..ec83441b --- /dev/null +++ b/vendor/howett.net/plist/go.mod @@ -0,0 +1,9 @@ +module howett.net/plist + +require ( + // for cmd/ply + github.com/jessevdk/go-flags v1.4.0 + github.com/kr/pretty v0.1.0 // indirect + gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect + gopkg.in/yaml.v2 v2.2.1 +) diff --git a/vendor/howett.net/plist/go16_test.go b/vendor/howett.net/plist/go16_test.go deleted file mode 100644 index 3de460ab..00000000 --- a/vendor/howett.net/plist/go16_test.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !go1.7 - -package plist - -import "testing" - -func subtest(t *testing.T, name string, f func(t *testing.T)) { - // Subtests don't exist for Go <1.7, and we can't create our own testing.T to substitute in - // for f's argument. - f(t) -} diff --git a/vendor/howett.net/plist/go17_test.go b/vendor/howett.net/plist/go17_test.go deleted file mode 100644 index fa9eb71b..00000000 --- a/vendor/howett.net/plist/go17_test.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build go1.7 - -package plist - -import "testing" - -func subtest(t *testing.T, name string, f func(t *testing.T)) { - t.Run(name, f) -} diff --git a/vendor/howett.net/plist/invalid_bplist_test.go b/vendor/howett.net/plist/invalid_bplist_test.go deleted file mode 100644 index 7d607d12..00000000 --- a/vendor/howett.net/plist/invalid_bplist_test.go +++ /dev/null @@ -1,496 +0,0 @@ -package plist - -import ( - "bytes" - "testing" -) - -/* - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', // Magic - - // Object Table - // Offset Table - - // Trailer - 0x00, 0x00, 0x00, 0x00, 0x00, // - U8[5] Unused - 0x01, // - U8 Sort Version - 0x01, // - U8 Offset Table Entry Size (#bytes) - 0x01, // - U8 Object Reference Size (#bytes) - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // - U64 # Objects - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // - U64 Top Object - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // - U64 Offset Table Offset - }, -*/ - -var InvalidBplists = [][]byte{ - // Too short - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - 0x00, - }, - // Bad magic - []byte{ - 'x', 'p', 'l', 'i', 's', 't', '0', '0', - - 0x00, - 0x08, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - }, - // Bad version - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '3', '0', - - 0x00, - 0x08, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - }, - // Bad version II - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '@', 'A', - - 0x00, - 0x08, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - }, - // Offset table inside trailer - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - }, - // Offset table inside header - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }, - // Offset table off end of file - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, - }, - // Garbage between offset table and trailer - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0x00, - 0x09, - - 0xAB, 0xCD, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - }, - // Top Object out of range - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0x00, - 0x08, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - }, - // Object out of range - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0x00, - 0xFF, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - }, - // Object references too small (1 byte, but 257 objects) - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0x00, - - // 257 bytes worth of object table - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - }, - // Offset references too small (1 byte, but 257 bytes worth of objects) - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - // 257 bytes worth of "objects" - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, - - 0x00, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09, - }, - // Too many objects - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0x00, - 0x08, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - }, - // String way too long - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0x5F, 0x10, 0xFF, - 0x08, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, - }, - // UTF-16 String way too long - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0x6F, 0x10, 0xFF, - 0x08, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, - }, - // Data way too long - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0x4F, 0x10, 0xFF, - 0x08, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, - }, - // Array way too long - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0xAF, 0x10, 0xFF, - 0x08, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, - }, - // Dictionary way too long - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0xDF, 0x10, 0xFF, - 0x08, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, - }, - // Array self-referential - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0xA1, 0x00, - - 0x08, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - }, - // Dictionary self-referential key - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0xD1, 0x00, 0x01, - 0x50, // 0-byte string - - 0x08, 0x0B, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, - }, - // Dictionary self-referential value - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0xD1, 0x01, 0x00, - 0x50, // 0-byte string - - 0x08, 0x0B, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, - }, - // Dictionary non-string key - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0xD1, 0x01, 0x02, - 0x08, - 0x09, - - 0x08, 0x0B, 0x0C, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, - }, - // Array contains invalid reference - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0xA1, 0x0F, - - 0x08, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, - }, - // Dictionary contains invalid reference - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0xD1, 0x01, 0x0F, - 0x50, // 0-byte string - - 0x08, 0x0B, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, - }, - // Invalid float ("7-byte") - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0x27, - - 0x08, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - }, - // Invalid integer (8^5) - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0x15, - - 0x08, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - }, - // Invalid atom - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0xFF, - - 0x08, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - }, - - // array refers to self through a second level - []byte{ - 'b', 'p', 'l', 'i', 's', 't', '0', '0', - - 0xA1, 0x01, - 0xA1, 0x00, - - 0x08, 0x0A, - - 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, - 0x01, - 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, - }, -} - -func TestInvalidBinaryPlists(t *testing.T) { - for _, data := range InvalidBplists { - buf := bytes.NewReader(data) - d := newBplistParser(buf) - _, err := d.parseDocument() - if err == nil { - t.Fatal("invalid plist failed to throw error") - } else { - t.Log(err) - } - } -} diff --git a/vendor/howett.net/plist/invalid_text_test.go b/vendor/howett.net/plist/invalid_text_test.go deleted file mode 100644 index 8a3da2f9..00000000 --- a/vendor/howett.net/plist/invalid_text_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package plist - -import ( - "strings" - "testing" -) - -var InvalidTextPlists = []struct { - Name string - Data string -}{ - {"Truncated array", "("}, - {"Truncated dictionary", "{a=b;"}, - {"Truncated dictionary 2", "{"}, - {"Unclosed nested array", "{0=(/"}, - {"Unclosed dictionary", "{0=/"}, - {"Broken GNUStep data", "(<*I5>,<*I5>,<*I5>,<*I5>,*I16777215>,<*I268435455>,<*I4294967295>,<*I18446744073709551615>,)"}, - {"Truncated nested array", "{0=(((/"}, - {"Truncated dictionary with comment-like", "{/"}, - {"Truncated array with comment-like", "(/"}, - {"Truncated array with empty data", "(<>"}, - {"Bad Extended Character", "{¬=A;}"}, - {"Missing Equals in Dictionary", `{"A"A;}`}, - {"Missing Semicolon in Dictionary", `{"A"=A}`}, - {"Invalid GNUStep type", "<*F33>"}, - {"Invalid GNUStep int", "(<*I>"}, - {"Invalid GNUStep date", "<*D5>"}, - {"Truncated GNUStep value", "<*I3"}, - {"Invalid data", ""}, - {"Truncated unicode escape", `"\u231`}, - {"Truncated hex escape", `"\x2`}, - {"Truncated octal escape", `"\02`}, - {"Truncated data", `<33`}, - {"Uneven data", `<3>`}, - {"Truncated block comment", `/* hello`}, - {"Truncated quoted string", `"hi`}, - {"Garbage after end of non-string", " cde"}, - {"Broken UTF-16", "\xFE\xFF\x01"}, -} - -func TestInvalidTextPlists(t *testing.T) { - for _, test := range InvalidTextPlists { - subtest(t, test.Name, func(t *testing.T) { - var obj interface{} - buf := strings.NewReader(test.Data) - err := NewDecoder(buf).Decode(&obj) - if err == nil { - t.Fatal("invalid plist failed to throw error") - } else { - t.Log(err) - } - }) - } -} diff --git a/vendor/howett.net/plist/marshal_test.go b/vendor/howett.net/plist/marshal_test.go deleted file mode 100644 index d2b95841..00000000 --- a/vendor/howett.net/plist/marshal_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package plist - -import ( - "reflect" - "testing" - "time" -) - -func BenchmarkStructMarshal(b *testing.B) { - for i := 0; i < b.N; i++ { - e := &Encoder{} - e.marshal(reflect.ValueOf(plistValueTreeRawData)) - } -} - -func BenchmarkMapMarshal(b *testing.B) { - data := map[string]interface{}{ - "intarray": []interface{}{ - int(1), - int8(8), - int16(16), - int32(32), - int64(64), - uint(2), - uint8(9), - uint16(17), - uint32(33), - uint64(65), - }, - "floats": []interface{}{ - float32(32.0), - float64(64.0), - }, - "booleans": []bool{ - true, - false, - }, - "strings": []string{ - "Hello, ASCII", - "Hello, 世界", - }, - "data": []byte{1, 2, 3, 4}, - "date": time.Date(2013, 11, 27, 0, 34, 0, 0, time.UTC), - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - e := &Encoder{} - e.marshal(reflect.ValueOf(data)) - } -} - -func TestInvalidMarshal(t *testing.T) { - tests := []struct { - Name string - Thing interface{} - }{ - {"Function", func() {}}, - {"Nil", nil}, - {"Map with integer keys", map[int]string{1: "hi"}}, - {"Channel", make(chan int)}, - } - - for _, v := range tests { - subtest(t, v.Name, func(t *testing.T) { - data, err := Marshal(v.Thing, OpenStepFormat) - if err == nil { - t.Fatalf("expected error; got plist data: %x", data) - } else { - t.Log(err) - } - }) - } -} diff --git a/vendor/howett.net/plist/text_test.go b/vendor/howett.net/plist/text_test.go deleted file mode 100644 index 86c1acf9..00000000 --- a/vendor/howett.net/plist/text_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package plist - -import ( - "bytes" - "io/ioutil" - "testing" -) - -func BenchmarkOpenStepGenerate(b *testing.B) { - for i := 0; i < b.N; i++ { - d := newTextPlistGenerator(ioutil.Discard, OpenStepFormat) - d.generateDocument(plistValueTree) - } -} - -func BenchmarkOpenStepParse(b *testing.B) { - buf := bytes.NewReader([]byte(plistValueTreeAsOpenStep)) - b.ResetTimer() - for i := 0; i < b.N; i++ { - b.StartTimer() - d := newTextPlistParser(buf) - d.parseDocument() - b.StopTimer() - buf.Seek(0, 0) - } -} - -func BenchmarkGNUStepParse(b *testing.B) { - buf := bytes.NewReader([]byte(plistValueTreeAsGNUStep)) - b.ResetTimer() - for i := 0; i < b.N; i++ { - b.StartTimer() - d := newTextPlistParser(buf) - d.parseDocument() - b.StopTimer() - buf.Seek(0, 0) - } -} - -// The valid text test cases have been merged into the common/global test cases. diff --git a/vendor/howett.net/plist/unmarshal.go b/vendor/howett.net/plist/unmarshal.go index e38cbe53..06f5d6fc 100644 --- a/vendor/howett.net/plist/unmarshal.go +++ b/vendor/howett.net/plist/unmarshal.go @@ -257,10 +257,7 @@ func (p *Decoder) unmarshalDictionary(dict *cfDictionary, val reflect.Value) { sval := dict.values[i] keyv := reflect.ValueOf(k).Convert(typ.Key()) - mapElem := val.MapIndex(keyv) - if !mapElem.IsValid() { - mapElem = reflect.New(typ.Elem()).Elem() - } + mapElem := reflect.New(typ.Elem()).Elem() p.unmarshal(sval, mapElem) val.SetMapIndex(keyv, mapElem) diff --git a/vendor/howett.net/plist/unmarshal_test.go b/vendor/howett.net/plist/unmarshal_test.go deleted file mode 100644 index eaf3cdb3..00000000 --- a/vendor/howett.net/plist/unmarshal_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package plist - -import ( - "reflect" - "testing" - "time" -) - -func BenchmarkStructUnmarshal(b *testing.B) { - type Data struct { - Intarray []uint64 `plist:"intarray"` - Floats []float64 `plist:"floats"` - Booleans []bool `plist:"booleans"` - Strings []string `plist:"strings"` - Dat []byte `plist:"data"` - Date time.Time `plist:"date"` - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - var xval Data - d := &Decoder{} - d.unmarshal(plistValueTree, reflect.ValueOf(&xval)) - } -} - -func BenchmarkInterfaceUnmarshal(b *testing.B) { - for i := 0; i < b.N; i++ { - var xval interface{} - d := &Decoder{} - d.unmarshal(plistValueTree, reflect.ValueOf(&xval)) - } -} diff --git a/vendor/howett.net/plist/xml_generator.go b/vendor/howett.net/plist/xml_generator.go index 9302ef07..0b59ed7f 100644 --- a/vendor/howett.net/plist/xml_generator.go +++ b/vendor/howett.net/plist/xml_generator.go @@ -1,64 +1,117 @@ package plist import ( + "bufio" "encoding/base64" "encoding/xml" "io" "math" + "strconv" "time" ) -const xmlDOCTYPE = ` -` +const ( + xmlHEADER string = `` + "\n" + xmlDOCTYPE = `` + "\n" + xmlArrayTag = "array" + xmlDataTag = "data" + xmlDateTag = "date" + xmlDictTag = "dict" + xmlFalseTag = "false" + xmlIntegerTag = "integer" + xmlKeyTag = "key" + xmlPlistTag = "plist" + xmlRealTag = "real" + xmlStringTag = "string" + xmlTrueTag = "true" + + // magic value used in the XML encoding of UIDs + // (stored as a dictionary mapping CF$UID->integer) + xmlCFUIDMagic = "CF$UID" +) + +func formatXMLFloat(f float64) string { + switch { + case math.IsInf(f, 1): + return "inf" + case math.IsInf(f, -1): + return "-inf" + case math.IsNaN(f): + return "nan" + } + return strconv.FormatFloat(f, 'g', -1, 64) +} type xmlPlistGenerator struct { - writer io.Writer - xmlEncoder *xml.Encoder + *bufio.Writer + + indent string + depth int + putNewline bool } func (p *xmlPlistGenerator) generateDocument(root cfValue) { - io.WriteString(p.writer, xml.Header) - io.WriteString(p.writer, xmlDOCTYPE) - - plistStartElement := xml.StartElement{ - Name: xml.Name{ - Space: "", - Local: "plist", - }, - Attr: []xml.Attr{{ - Name: xml.Name{ - Space: "", - Local: "version"}, - Value: "1.0"}, - }, - } - - p.xmlEncoder.EncodeToken(plistStartElement) + p.WriteString(xmlHEADER) + p.WriteString(xmlDOCTYPE) + p.openTag(`plist version="1.0"`) p.writePlistValue(root) + p.closeTag(xmlPlistTag) + p.Flush() +} + +func (p *xmlPlistGenerator) openTag(n string) { + p.writeIndent(1) + p.WriteByte('<') + p.WriteString(n) + p.WriteByte('>') +} - p.xmlEncoder.EncodeToken(plistStartElement.End()) - p.xmlEncoder.Flush() +func (p *xmlPlistGenerator) closeTag(n string) { + p.writeIndent(-1) + p.WriteString("') +} + +func (p *xmlPlistGenerator) element(n string, v string) { + p.writeIndent(0) + if len(v) == 0 { + p.WriteByte('<') + p.WriteString(n) + p.WriteString("/>") + } else { + p.WriteByte('<') + p.WriteString(n) + p.WriteByte('>') + + err := xml.EscapeText(p.Writer, []byte(v)) + if err != nil { + panic(err) + } + + p.WriteString("') + } } func (p *xmlPlistGenerator) writeDictionary(dict *cfDictionary) { dict.sort() - startElement := xml.StartElement{Name: xml.Name{Local: "dict"}} - p.xmlEncoder.EncodeToken(startElement) + p.openTag(xmlDictTag) for i, k := range dict.keys { - p.xmlEncoder.EncodeElement(k, xml.StartElement{Name: xml.Name{Local: "key"}}) + p.element(xmlKeyTag, k) p.writePlistValue(dict.values[i]) } - p.xmlEncoder.EncodeToken(startElement.End()) + p.closeTag(xmlDictTag) } func (p *xmlPlistGenerator) writeArray(a *cfArray) { - startElement := xml.StartElement{Name: xml.Name{Local: "array"}} - p.xmlEncoder.EncodeToken(startElement) + p.openTag(xmlArrayTag) for _, v := range a.values { p.writePlistValue(v) } - p.xmlEncoder.EncodeToken(startElement.End()) + p.closeTag(xmlArrayTag) } func (p *xmlPlistGenerator) writePlistValue(pval cfValue) { @@ -66,80 +119,67 @@ func (p *xmlPlistGenerator) writePlistValue(pval cfValue) { return } - defer p.xmlEncoder.Flush() - - if dict, ok := pval.(*cfDictionary); ok { - p.writeDictionary(dict) - return - } else if a, ok := pval.(*cfArray); ok { - p.writeArray(a) - return - } else if uid, ok := pval.(cfUID); ok { - p.writeDictionary(&cfDictionary{ - keys: []string{"CF$UID"}, - values: []cfValue{ - &cfNumber{ - signed: false, - value: uint64(uid), - }, - }, - }) - return - } - - // Everything here and beyond is encoded the same way: value - key := "" - var encodedValue interface{} = pval - switch pval := pval.(type) { case cfString: - key = "string" + p.element(xmlStringTag, string(pval)) case *cfNumber: - key = "integer" if pval.signed { - encodedValue = int64(pval.value) + p.element(xmlIntegerTag, strconv.FormatInt(int64(pval.value), 10)) } else { - encodedValue = pval.value + p.element(xmlIntegerTag, strconv.FormatUint(pval.value, 10)) } case *cfReal: - key = "real" - encodedValue = pval.value - switch { - case math.IsInf(pval.value, 1): - encodedValue = "inf" - case math.IsInf(pval.value, -1): - encodedValue = "-inf" - case math.IsNaN(pval.value): - encodedValue = "nan" - } + p.element(xmlRealTag, formatXMLFloat(pval.value)) case cfBoolean: - key = "false" - b := bool(pval) - if b { - key = "true" + if bool(pval) { + p.element(xmlTrueTag, "") + } else { + p.element(xmlFalseTag, "") } - encodedValue = "" case cfData: - key = "data" - encodedValue = xml.CharData(base64.StdEncoding.EncodeToString([]byte(pval))) + p.element(xmlDataTag, base64.StdEncoding.EncodeToString([]byte(pval))) case cfDate: - key = "date" - encodedValue = time.Time(pval).In(time.UTC).Format(time.RFC3339) + p.element(xmlDateTag, time.Time(pval).In(time.UTC).Format(time.RFC3339)) + case *cfDictionary: + p.writeDictionary(pval) + case *cfArray: + p.writeArray(pval) + case cfUID: + p.openTag(xmlDictTag) + p.element(xmlKeyTag, xmlCFUIDMagic) + p.element(xmlIntegerTag, strconv.FormatUint(uint64(pval), 10)) + p.closeTag(xmlDictTag) } +} - if key != "" { - err := p.xmlEncoder.EncodeElement(encodedValue, xml.StartElement{Name: xml.Name{Local: key}}) - if err != nil { - panic(err) - } +func (p *xmlPlistGenerator) writeIndent(delta int) { + if len(p.indent) == 0 { + return + } + + if delta < 0 { + p.depth-- + } + + if p.putNewline { + // from encoding/xml/marshal.go; it seems to be intended + // to suppress the first newline. + p.WriteByte('\n') + } else { + p.putNewline = true + } + for i := 0; i < p.depth; i++ { + p.WriteString(p.indent) + } + if delta > 0 { + p.depth++ } } func (p *xmlPlistGenerator) Indent(i string) { - p.xmlEncoder.Indent("", i) + p.indent = i } func newXMLPlistGenerator(w io.Writer) *xmlPlistGenerator { - mw := mustWriter{w} - return &xmlPlistGenerator{mw, xml.NewEncoder(mw)} + return &xmlPlistGenerator{Writer: bufio.NewWriter(w)} } diff --git a/vendor/howett.net/plist/xml_test.go b/vendor/howett.net/plist/xml_test.go deleted file mode 100644 index 1b823ac0..00000000 --- a/vendor/howett.net/plist/xml_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package plist - -import ( - "bytes" - "io/ioutil" - "testing" -) - -func BenchmarkXMLGenerate(b *testing.B) { - for i := 0; i < b.N; i++ { - d := newXMLPlistGenerator(ioutil.Discard) - d.generateDocument(plistValueTree) - } -} - -func BenchmarkXMLParse(b *testing.B) { - buf := bytes.NewReader([]byte(plistValueTreeAsXML)) - b.ResetTimer() - for i := 0; i < b.N; i++ { - b.StartTimer() - d := newXMLPlistParser(buf) - d.parseDocument() - b.StopTimer() - buf.Seek(0, 0) - } -} - -func TestVariousIllegalXMLPlists(t *testing.T) { - plists := []string{ - `0x`, - "helo", - "helo", - "helo", - "helo", - "", - "helo", - "*@&%#helo", - "*@&%#helo", - "*@&%#helo", - "10", - "10", - "10", - "10", - "10", - "", - "", - "", - "", - "", - "