Skip to content

Conversation

@BirmacherAkos
Copy link
Contributor

Only the prov. profiles.
The certificates will come on the next round.

 - uploaders/common.go: error handling for io.Copy()
 - uploaders/requestResponse: Doc fix
@@ -0,0 +1,322 @@
package uploaders
Copy link
Contributor

@godrei godrei Mar 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the main file's name of a package .go should be the package name: uploaders.go


// AskAccessToken ...
func AskAccessToken() (token string, err error) {
messageToAsk := "Please copy your personal access token to Bitrise.\n" +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use '`' syntax to define multi line string:

func createRequestURLForMyApps() string {
requestURL, err := urlutil.Join(baseURL, myAppsEndPoint)
if err != nil {
failWithMessage("failed to create request URL, error: %s", err)
Copy link
Contributor

@godrei godrei Mar 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • do not call os exit int this kind of small units (its i ok in main())
  • do not separate this to a new function: it is only used by one other function and has only one fn call

return req
}

func createRequest(url string, fields map[string]interface{}, requestMethod httpMethod, headers map[string]string) (*http.Request, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • recommended input order: method, url, headers, body
  • no need to define httpMethod struct (we use only two method: "GET" and "POST" + they are short and well known)

}

func createRequest(url string, fields map[string]interface{}, requestMethod httpMethod, headers map[string]string) (*http.Request, error) {
b := new(bytes.Buffer)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to explicit initialize b: var b bytes.Buffer works great and shows, that we do not care about its initial value.

if err != nil {
return nil, err
}
if _, err := io.Copy(os.Stdout, req.Body); err != nil {
Copy link
Contributor

@godrei godrei Mar 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we copy the body to stdout?

return requestURL
}

func createRequestURLForProvProfSlug(appSlug string) string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not separate this logic into a new function

return requestURL
}

func failWithMessage(format string, v ...interface{}) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoid os exiting in package!

@@ -0,0 +1,25 @@
package uploaders
Copy link
Contributor

@godrei godrei Mar 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use snake_case go file names: http_method.go

based on my previous comment: remove this file!

}

// Appliocation ...
type Appliocation struct {
Copy link
Contributor

@godrei godrei Mar 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

type Appliocation

@@ -0,0 +1,45 @@
package uploaders
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may call this file: models.go

return nil
}

func createUploadRequest(url string, files map[string]string, requestMethod httpMethod, headers map[string]string) *http.Request {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if there are several 'commonly' used functions you can move them into: common.go file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure about this?
I think it would be better if every "network type" function will be under the uploaders package and not the cmd package.

cmd/common.go Outdated
// ----------------------------------------------------------------
// --- Upload methods

// TODO
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoid leaving TODO comment in your code!

cmd/common.go Outdated

// TODO
func uploadProvisioningProfiles(profilesToUpload []profileutil.ProvisioningProfileInfoModel, outputDirPath string) error {
// Get accesToken from stdin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for this comment AskAccessToken is a descriptive name

cmd/common.go Outdated
// TODO
func uploadProvisioningProfiles(profilesToUpload []profileutil.ProvisioningProfileInfoModel, outputDirPath string) error {
// Get accesToken from stdin
accessToken, err := uploaders.AskAccessToken()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AskAccessToken does not belong to uploaders, do it here in common.go

cmd/common.go Outdated
// Get accesToken from stdin
accessToken, err := uploaders.AskAccessToken()

appList, err := uploaders.FetchMyApps(accessToken)
Copy link
Contributor

@godrei godrei Mar 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uploaders.FetchMyApps() is a strange function name.

may the uploaders package should be: bitriseclient, this way:

client := bitriseclient.New(AccessToken)
client.FetchMyApps()
client.UploadProfiles() 
entc...

creating a Client model may worth, since you need to use AccessToken at every request.


// Upload provisioning profiles
for _, profile := range profilesToUpload {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoid unnecessary empty lines!


exportFileName := provProfileExportFileName(profile, outputDirPath)

provProfile, err := os.Open(outputDirPath + "/" + exportFileName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do this size calculation in RegisterProvisioningProfile

cmd/common.go Outdated
}

err = uploaders.UploadProvisioningProfile(provProfSlugResponseData, outputDirPath, exportFileName)
if err != nil {
Copy link
Contributor

@godrei godrei Mar 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if function returns only a single error, define and check the error in if statement:

if err := uploaders.UploadProvisioningProfile(provProfSlugResponseData, outputDirPath, exportFileName); err != nil {
}

avoid using err = xyz() this can easily lead to a shadowed error! always try to define the error like: err := xyz()

cmd/common.go Outdated
bytes := info.Size()
log.Debugf("\n%s size: %d", exportFileName, bytes)

provProfSlugResponseData, err := uploaders.RegisterProvisioningProfile(accessToken, selectedApp.Slug, bytes, profile)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems we only use RegisterProvisioningProfileResponseData's UploadURL and UploadFileName, return this values in RegisterProvisioningProfile instead of a new model with unused fields

cmd/common.go Outdated
return nil
}

func selectApp(appList []uploaders.Appliocation) (seledtedApp uploaders.Appliocation, err error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please check which fields of the app is used if there is no more then 2 fields may we do not need a struct.

cmd/common.go Outdated
}

func selectApp(appList []uploaders.Appliocation) (seledtedApp uploaders.Appliocation, err error) {
selectionList := []string{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we do not care about initial value, use: var selectionList []string

cmd/common.go Outdated

log.Debugf("selected app: %v", userSelection)

selectedApp, err := getAppFromUserSelection(userSelection, appList)
Copy link
Contributor

@godrei godrei Mar 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for this function:

  • sort the selectionList
  • then find the selected index by: sort.Search...
  • then appList[i] is the app

also you can return this function: return getAppFromUserSelection

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have changed to the sort.Search() method as you advised, but I have not removed the getAppFromUserSelection() because it has tests.

Copy link
Contributor

@godrei godrei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please have a look on my comments

Squashed commits:
[6a9bc13] PR fix (+3 squashed commits)
Squashed commits:
[a22d42c] uploaders/requestResponse.go renamed to uploaders/model.go
[be88ad1] Application type fix;
uploaders.go: failWithMessage removed, Instead every func return with an error if needed;
[1da5d56] httpMethod removed;

// Response struct
var appListResponse FetchMyAppsResponse
responseStatusCode := -1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we use it?


// Response struct
requestResponse := FetchUploadedIdentityListResponse{}
responseStatusCode := -1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we use it?

log.Debugf("\nRequest URL: %s", requestURL)

// Response struct
requestResponse := FetchUploadedIdentityListResponse{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var

}

// Response struct
responseStatusCode := -1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we use it?

return "", err
}

data, err := profileutil.NewProvisioningProfileInfo(*plistData, profileutil.ProfileTypeIos)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return profileutil.NewProvisioningProfileInfo(*plistData, profileutil.ProfileTypeIos)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only need the UUID

// Perform request
if err := retry.Times(1).Wait(5 * time.Second).Try(func(attempt uint) error {
body, statusCode, err := performRequest(request)
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the thing is: if the request returns non success status code, the erro will be nil.
later you do not check the status code, probably the json marshal would fail, since in case of error the response is something else then the success model, but fail fast!

please check the status code and retry if non success received

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, but the performRequest do this already. If the status code != statusOK it will return an error.

cmd/common.go Outdated
return nil
}

func uploadExportedFiles(profilesToExport []profileutil.ProvisioningProfileInfoModel, certificatesToExport []certificateutil.CertificateInfoModel,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not use named returns values in this long func

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need it here because this func returns 2 bool attr. and it can cause a misconception.
And if the provisioning profiles are uploaded successfully but the certs. are not, only the first bool (provProfilesUploaded) will be true.

cmd/common.go Outdated
fmt.Println()
log.Infof("Looking for certificate duplicates on Bitrise...")

uploadedCertificatesSerialList := []string{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var

cmd/common.go Outdated

// Get uploaded certificates' serials
for _, uploadedIdentity := range uploadedItentityList {
serialListAsString := []string{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var

cmd/common.go Outdated
return err
}

bytes := info.Size()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for this new var

cmd/common.go Outdated
return err
}

if err := bitriseClient.ConfirmIdentityUpload(certificateResponseData.Slug, certificateResponseData.UploadFileName); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return bitriseClient.ConfirmIdentityUpload(certificateResponseData.Slug, certificateResponseData.UploadFileName)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can do that but I think it will break the code's continuity. (The previous func call looks the same).
That's why I would not change the return statement.

}

userSelection, err := goinp.SelectFromStringsWithDefault("Select the app which you want to upload the privisioning profiles", 1, selectionList)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this empty line

cmd/common.go Outdated
return err
}

bytes := info.Size()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for new var

cmd/common.go Outdated
func askUploadGeneratedFiles() (bool, error) {
messageToAsk := "Do you want to upload the provisioning profiles and certificates to Bitrise?"

answer, err := goinp.AskForBoolFromReader(messageToAsk, os.Stdin)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return goinp.AskForBoolFromReader(messageToAsk, os.Stdin)

cmd/common.go Outdated
func askUploadIdentities() (bool, error) {
messageToAsk := "Do you want to upload the certificates to Bitrise?"

answer, err := goinp.AskForBoolFromReader(messageToAsk, os.Stdin)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return goinp.AskForBoolFromReader(messageToAsk, os.Stdin)

cmd/common.go Outdated
fmt.Println()
log.Infof("Looking for provisioning profile duplicates on Bitrise...")

uploadedProfileUUIDList := []string{}
Copy link
Contributor

@godrei godrei Mar 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

map would be much better for this purpose, no need for IsStringInSlice:
uploadedProfileUUIDList := map[string]bool{}

client := &BitriseClient{accessToken, "", map[string]string{"Authorization": "token " + accessToken}}
var apps []Application

log.Infof("Asking your application list from Bitrise...")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Asking -> fetching


for key, value := range headers {
req.Header.Add(key, value)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove unused newlines


//
// Perform request
if err := retry.Times(1).Wait(5 * time.Second).Try(func(attempt uint) error {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please shorten these long logics.

}

// FetchIdentityResponseData ...
type FetchIdentityResponseData struct {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please shorten model names and also remove un-relevant part of the names

}

// NewBitriseClient ...
func NewBitriseClient(accessToken string) (*BitriseClient, []Application, error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please try to create an authenticated httpClient so you won't need to create it all the time and set the auth header for that.

Squashed commits:
[e108a55] BitriseClient: RunRequest method (+2 squashed commits)
Squashed commits:
[53c1dba] Renames
[181bf12] FetchIdentityListResponse rename
cmd/common.go Outdated
}

func uploadExportedFiles(profilesToExport []profileutil.ProvisioningProfileInfoModel, certificatesToExport []certificateutil.CertificateInfoModel,
outputDirPath string) (provProfilesUploaded bool, certsUploaded bool, err error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please separate the functionality into two functions rather than merging the return values together.

@trapacska trapacska merged commit 7045fd3 into bitrise-io:master Apr 6, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants