func()

in cmd/list.go [217:335]


func (cooked cookedListCmdArgs) handleListContainerCommand() (err error) {
	ctx := context.WithValue(context.TODO(), ste.ServiceAPIVersionOverride, ste.DefaultServiceApiVersion)

	var credentialInfo common.CredentialInfo

	source, err := SplitResourceString(cooked.sourcePath, cooked.location)
	if err != nil {
		return err
	}

	if err := common.VerifyIsURLResolvable(raw.src); cooked.location.IsRemote() && err != nil {
		return fmt.Errorf("failed to resolve target: %w", err)
	}

	level, err := DetermineLocationLevel(source.Value, cooked.location, true)
	if err != nil {
		return err
	}

	// isSource is rather misnomer for canBePublic. We can list public containers, and hence isSource=true
	if credentialInfo, _, err = GetCredentialInfoForLocation(ctx, cooked.location, source, true, common.CpkOptions{}); err != nil {
		return fmt.Errorf("failed to obtain credential info: %s", err.Error())
	} else if credentialInfo.CredentialType.IsAzureOAuth() {
		uotm := GetUserOAuthTokenManagerInstance()
		if tokenInfo, err := uotm.GetTokenInfo(ctx); err != nil {
			return err
		} else {
			credentialInfo.OAuthTokenInfo = *tokenInfo
		}
	}

	// check if user wants to get version id
	getVersionId := containsProperty(cooked.properties, VersionId)

	traverser, err := InitResourceTraverser(source, cooked.location, &ctx, &credentialInfo, common.ESymlinkHandlingType.Skip(), nil, true, true, false, common.EPermanentDeleteOption.None(), func(common.EntityType) {}, nil, false, common.ESyncHashType.None(), common.EPreservePermissionsOption.None(), common.LogNone, common.CpkOptions{}, nil, false, cooked.trailingDot, nil, nil, getVersionId)
	if err != nil {
		return fmt.Errorf("failed to initialize traverser: %s", err.Error())
	}

	var fileCount int64 = 0
	var sizeCount int64 = 0

	type versionIdObject struct {
		versionId string
		fileSize  int64
	}
	objectVer := make(map[string]versionIdObject)

	processor := func(object StoredObject) error {
		lo := cooked.newListObject(object, level)
		glcm.Output(func(format common.OutputFormat) string {
			if format == common.EOutputFormat.Json() {
				jsonOutput, err := json.Marshal(lo)
				common.PanicIfErr(err)
				return string(jsonOutput)
			} else {
				return lo.String()
			}
		}, common.EOutputMessageType.ListObject())

		// ensure that versioned objects don't get counted multiple times in the tally
		// 1. only include the size of the latest version of the object in the sizeCount
		// 2. only include the object once in the fileCount
		if cooked.RunningTally {
			if getVersionId {
				// get new version id object
				updatedVersionId := versionIdObject{
					versionId: object.blobVersionID,
					fileSize:  object.size,
				}

				// there exists a current version id of the object
				if currentVersionId, ok := objectVer[object.relativePath]; ok {
					// get current version id time
					currentVid, _ := time.Parse(versionIdTimeFormat, currentVersionId.versionId)

					// get new version id time
					newVid, _ := time.Parse(versionIdTimeFormat, object.blobVersionID)

					// if new vid came after the current vid, then it is the latest version
					// update the objectVer with the latest version
					// we will also remove sizeCount and fileCount of current object, allowing
					// the updated sizeCount and fileCount to be added at line 320
					if newVid.After(currentVid) {
						sizeCount -= currentVersionId.fileSize // remove size of current object
						fileCount--                            // remove current object file count
						objectVer[object.relativePath] = updatedVersionId
					}
				} else {
					objectVer[object.relativePath] = updatedVersionId
				}
			}
			fileCount++
			sizeCount += object.size
		}
		return nil
	}

	err = traverser.Traverse(nil, processor, nil)

	if err != nil {
		return fmt.Errorf("failed to traverse container: %s", err.Error())
	}

	if cooked.RunningTally {
		ls := cooked.newListSummary(fileCount, sizeCount)
		glcm.Output(func(format common.OutputFormat) string {
			if format == common.EOutputFormat.Json() {
				jsonOutput, err := json.Marshal(ls)
				common.PanicIfErr(err)
				return string(jsonOutput)
			} else {
				return ls.String()
			}
		}, common.EOutputMessageType.ListSummary())
	}

	return nil
}