// MapFetchableUrl checks a type to see if it is either a short git hub url or a fully specified URL
// and returns the URL that should be used to fetch it. If the url is not fetchable (primitive type for
// example) will return empty string.
func (tr *typeResolver) MapFetchableURL(t string) (string, error) {
	if util.IsGithubShortType(t) {
		return tr.ShortTypeToDownloadURL(t)
	} else if util.IsHttpUrl(t) {
		return t, nil
	}
	return "", nil
}
// MapFetchableUrls checks a type to see if it is either a short git hub url or a fully specified URL
// and returns the URL that should be used to fetch it. If the url is not fetchable (primitive type for
// example) will return empty string.
func (tr *typeResolver) MapFetchableURLs(t string) ([]string, error) {
	if util.IsGithubShortType(t) {
		return tr.ShortTypeToDownloadURLs(t)
	} else if util.IsGithubShortPackageType(t) {
		return tr.ShortTypeToPackageDownloadURLs(t)
	} else if util.IsHttpUrl(t) {
		return []string{t}, nil
	}
	return []string{}, nil
}
Exemple #3
0
func getTypeUrl(tName string) string {
	if util.IsHttpUrl(tName) {
		// User can pass raw URL to template.
		return tName
	}

	// User can pass registry type.
	t := getRegistryType(tName)
	if t == nil {
		log.Fatalf("Invalid type name, must be in the form \"<type-name>:<version>\": %s", tName)
	}

	return getDownloadUrl(*t)
}
// getTypeURLs returns URLs or empty list if a primitive type.
func getTypeURLs(tName string) []string {
	if util.IsHttpUrl(tName) {
		// User can pass raw URL to template.
		return []string{tName}
	}

	// User can pass registry type.
	t := getRegistryType(tName)
	if t == nil {
		// Primitive types have no associated URL.
		return []string{}
	}

	return getDownloadURLs(*t)
}
// GetDownloadURLs checks a type to see if it is either a short git hub url or a fully specified URL
// and returns the URLs that should be used to fetch it. If the url is not fetchable (primitive type
// for example), it returns an empty slice.
func GetDownloadURLs(rp RegistryProvider, t string) ([]string, error) {
	if IsGithubShortType(t) {
		return ShortTypeToDownloadURLs(rp, t)
	} else if IsGithubShortPackageType(t) {
		return ShortTypeToPackageDownloadURLs(rp, t)
	} else if util.IsHttpUrl(t) {
		result, err := url.Parse(t)
		if err != nil {
			return nil, fmt.Errorf("cannot parse download URL %s: %s", t, err)
		}

		return []string{result.String()}, nil
	}

	return []string{}, nil
}
// ResolveTypes resolves the types in the supplied configuration and returns
// resolved type definitions in t.ImportFiles. Types can be either
// primitive (i.e., built in), resolved (i.e., already t.ImportFiles), or remote
// (i.e., described by a URL that must be fetched to resolve the type).
func (tr *typeResolver) ResolveTypes(config *Configuration, imports []*ImportFile) ([]*ImportFile, error) {
	existing := map[string]bool{}
	for _, v := range imports {
		existing[v.Name] = true
	}

	fetched := map[string][]*ImportFile{}
	toFetch := make([]string, 0, tr.maxUrls)
	for _, r := range config.Resources {
		// Only fetch HTTP URLs that we haven't already imported.
		if util.IsHttpUrl(r.Type) && !existing[r.Type] {
			toFetch = append(toFetch, r.Type)
			fetched[r.Type] = append(fetched[r.Type], &ImportFile{Name: r.Type})
		}
	}

	count := 0
	for len(toFetch) > 0 {
		//1. Fetch import URL. Exit if no URLs left
		//2. Check/handle HTTP status
		//3. Store results in all ImportFiles from that URL
		//4. Check for the optional schema file at import URL + .schema
		//5. Repeat 2,3 for schema file
		//6. Add each schema import to fetch if not already done
		//7. Mark URL done. Return to 1.
		if count >= tr.maxUrls {
			return nil, resolverError(config,
				fmt.Errorf("Number of imports exceeds maximum of %d", tr.maxUrls))
		}

		url := toFetch[0]
		template, err := performHTTPGet(tr.getter, url, false)
		if err != nil {
			return nil, resolverError(config, err)
		}

		for _, i := range fetched[url] {
			i.Content = template
		}

		schemaURL := url + schemaSuffix
		sch, err := performHTTPGet(tr.getter, schemaURL, true)
		if err != nil {
			return nil, resolverError(config, err)
		}

		if sch != "" {
			var s Schema
			if err := yaml.Unmarshal([]byte(sch), &s); err != nil {
				return nil, resolverError(config, err)
			}
			// Here we handle any nested imports in the schema we've just fetched.
			for _, v := range s.Imports {
				i := &ImportFile{Name: v.Name}
				var existingSchema string
				if len(fetched[v.Path]) == 0 {
					// If this import URL is new to us, add it to the URLs to fetch.
					toFetch = append(toFetch, v.Path)
				} else {
					// If this is not a new import URL and we've already fetched its contents,
					// reuse them. Also, check if we also found a schema for that import URL and
					// record those contents for re-use as well.
					if fetched[v.Path][0].Content != "" {
						i.Content = fetched[v.Path][0].Content
						if len(fetched[v.Path+schemaSuffix]) > 0 {
							existingSchema = fetched[v.Path+schemaSuffix][0].Content
						}
					}
				}
				fetched[v.Path] = append(fetched[v.Path], i)
				if existingSchema != "" {
					fetched[v.Path+schemaSuffix] = append(fetched[v.Path+schemaSuffix],
						&ImportFile{Name: v.Name + schemaSuffix, Content: existingSchema})
				}
			}

			// Add the schema we've fetched as the schema for any templates which used this URL.
			for _, i := range fetched[url] {
				schemaImportName := i.Name + schemaSuffix
				fetched[schemaURL] = append(fetched[schemaURL],
					&ImportFile{Name: schemaImportName, Content: sch})
			}
		}

		count = count + 1
		toFetch = toFetch[1:]
	}

	ret := []*ImportFile{}
	for _, v := range fetched {
		ret = append(ret, v...)
	}

	return ret, nil
}