func()

in utils/zip.go [103:221]


func (zw *ZipWriter) buildIncludeMetadata() ([]Include, error) {
	var includeInfo []Include
	var listOfSourceFiles []string
	var err error
	var verboseMsg string

	// iterate over set of included files specified in manifest YAML e.g.
	// include:
	// - ["source"]
	// - ["source", "destination"]
	for _, includeData := range zw.include {
		var i Include
		// if "destination" is not specified, its considered same as "source"
		// "source" is relative to where manifest.yaml file is located
		// relative source path is converted to absolute path by appending manifest path
		// since the relative source path might not be accessible from where wskdeploy is invoked
		// "destination" is relative to the action directory, the one specified in function
		// relative path is converted to absolute path by appending function directory
		if len(includeData) == 1 {
			i.source = filepath.Join(zw.manifestFilePath, includeData[0])
			i.destination = filepath.Join(zw.src, includeData[0])
			verboseMsg = wski18n.T(wski18n.ID_VERBOSE_ZIP_INCLUDE_SOURCE_PATH_X_path_X,
				map[string]interface{}{
					wski18n.KEY_PATH: includeData[0],
				})
			wskprint.PrintlnOpenWhiskVerbose(Flags.Verbose, verboseMsg)
		} else if len(includeData) == 2 {
			i.source = filepath.Join(zw.manifestFilePath, includeData[0])
			i.destination = zw.src + "/" + includeData[1]
			verboseMsg = wski18n.T(wski18n.ID_VERBOSE_ZIP_INCLUDE_SOURCE_PATH_X_path_X_DESTINATION_PATH_X_dest_X,
				map[string]interface{}{
					wski18n.KEY_PATH:        includeData[0],
					wski18n.KEY_DESTINATION: includeData[1],
				})
		} else {
			if len(includeData) == 0 {
				verboseMsg = wski18n.T(wski18n.ID_VERBOSE_INVALID_INCLUDE_ENTRY,
					map[string]interface{}{
						wski18n.KEY_INCLUDE: "",
					})
				wskprint.PrintlnOpenWhiskVerbose(Flags.Verbose, verboseMsg)
			} else {
				for index, d := range includeData {
					includeData[index] = "\"" + d + "\""
				}
				includeEntry := strings.Join(includeData, ", ")
				verboseMsg = wski18n.T(wski18n.ID_VERBOSE_INVALID_INCLUDE_ENTRY,
					map[string]interface{}{
						wski18n.KEY_INCLUDE: includeEntry,
					})
				wskprint.PrintlnOpenWhiskVerbose(Flags.Verbose, verboseMsg)
			}
			continue
		}

		// set destDir to the destination location
		// check if its a file than change it to the Dir of destination file
		destDir := i.destination
		if isFilePath(destDir) {
			destDir = filepath.Dir(destDir)
		}
		// trim path wildcard "*" from the destination path as if it has any
		destDirs := strings.Split(destDir, PATH_WILDCARD)
		destDir = destDirs[0]

		// retrieve the name of all files matching pattern or nil if there is no matching file
		// listOfSourceFiles will hold a list of files matching patterns such as
		// actions/* or actions/libs/* or actions/libs/*/utils.js or actions/*/*/utils.js
		if listOfSourceFiles, err = filepath.Glob(i.source); err != nil {
			return includeInfo, err
		}

		// handle the scenarios where included path is something similar to actions/common/*.js
		// or actions/libs/* or actions/libs/*/utils.js
		// and destination is set to libs/ or libs/* or ./libs/* or libs/*/utils.js or libs/ or ./libs/
		if strings.ContainsAny(i.source, PATH_WILDCARD) {
			wskprint.PrintlnOpenWhiskVerbose(Flags.Verbose, wski18n.T(wski18n.ID_VERBOSE_LIST_OF_FILES_MATCHING_PATTERN))
			for _, file := range listOfSourceFiles {
				var relPath string
				if relPath, err = filepath.Rel(i.source, file); err != nil {
					return includeInfo, err
				}
				relPath = strings.TrimLeft(relPath, ONE_DIR_UP)
				j := Include{
					source:      file,
					destination: filepath.Join(destDir, relPath),
				}
				includeInfo = append(includeInfo, j)
				zw.excludedFiles[j.source] = false
				verboseMsg = wski18n.T(wski18n.ID_VERBOSE_ZIP_INCLUDE_SOURCE_PATH_X_path_X_DESTINATION_PATH_X_dest_X,
					map[string]interface{}{
						wski18n.KEY_PATH:        j.source,
						wski18n.KEY_DESTINATION: j.destination,
					})
				wskprint.PrintlnOpenWhiskVerbose(Flags.Verbose, verboseMsg)
			}
			// handle scenarios where included path is something similar to actions/common/utils.js
			// and destination is set to ./common/ i.e. no file name specified in the destination
		} else {
			if f, err := isFile(i.source); err == nil && f {
				if _, file := filepath.Split(i.destination); len(file) == 0 {
					_, sFile := filepath.Split(i.source)
					i.destination = i.destination + sFile
				}
			}
			// append just parsed include info to the list for further processing
			wskprint.PrintlnOpenWhiskVerbose(Flags.Verbose, wski18n.T(wski18n.ID_VERBOSE_LIST_OF_FILES_MATCHING_PATTERN))
			verboseMsg = wski18n.T(wski18n.ID_VERBOSE_ZIP_INCLUDE_SOURCE_PATH_X_path_X_DESTINATION_PATH_X_dest_X,
				map[string]interface{}{
					wski18n.KEY_PATH:        i.source,
					wski18n.KEY_DESTINATION: i.destination,
				})
			wskprint.PrintlnOpenWhiskVerbose(Flags.Verbose, verboseMsg)
			includeInfo = append(includeInfo, i)
			zw.excludedFiles[i.source] = false
		}
	}
	return includeInfo, nil
}