Пример #1
0
// exportCodelab fetches codelab src from either local disk or remote,
// parses and stores the results on disk, in a dir ancestored by *output.
//
// Stored results include codelab content formatted in *tmplout, its assets
// and metadata in JSON format.
//
// There's a special case where basedir has a value of "-", in which
// nothing is stored on disk and the only output, codelab formatted content,
// is printed to stdout.
func exportCodelab(src string) (*types.Meta, error) {
	clab, err := slurpCodelab(src)
	if err != nil {
		return nil, err
	}
	var client *http.Client // need for downloadImages
	if clab.typ == srcGoogleDoc {
		client, err = driveClient()
		if err != nil {
			return nil, err
		}
	}

	// codelab export context
	lastmod := types.ContextTime(clab.mod)
	meta := &clab.Meta
	ctx := &types.Context{
		Source:  src,
		Env:     *expenv,
		Format:  *tmplout,
		Prefix:  *prefix,
		MainGA:  *globalGA,
		Updated: &lastmod,
	}

	// rewritten image urls
	var imap map[string]string

	dir := *output // output dir or stdout
	if !isStdout(dir) {
		dir = codelabDir(dir, meta)
		imap = rewriteImages(clab.Steps)
	}
	// write codelab and its metadata to disk
	if err := writeCodelab(dir, clab.Codelab, ctx); err != nil {
		return nil, err
	}
	// slurp codelab assets to disk, if any
	mdir := filepath.Join(dir, imgDirname)
	return meta, downloadImages(client, mdir, imap)
}
Пример #2
0
// updateCodelab reads metadata from a dir/codelab.json file,
// re-exports the codelab just like it normally would in exportCodelab,
// and removes assets (images) which are not longer in use.
func updateCodelab(dir string) (*types.Meta, error) {
	// get stored codelab metadata and fail early if we can't
	meta, err := readMeta(filepath.Join(dir, metaFilename))
	if err != nil {
		return nil, err
	}
	// override allowed options from cli
	if *prefix != "" {
		meta.Prefix = *prefix
	}
	if *globalGA != "" {
		meta.MainGA = *globalGA
	}

	// fetch and parse codelab source
	clab, err := slurpCodelab(meta.Source)
	if err != nil {
		return nil, err
	}
	updated := types.ContextTime(clab.mod)
	meta.Context.Updated = &updated

	// update image references before writing codelab
	imgmap := rewriteImages(clab.Steps)
	basedir := filepath.Join(dir, "..")
	newdir := codelabDir(basedir, &clab.Meta)
	if err := writeCodelab(newdir, clab.Codelab, &meta.Context); err != nil {
		return nil, err
	}

	// slurp codelab assets to disk
	var client *http.Client
	if clab.typ == srcGoogleDoc {
		client, err = driveClient()
		if err != nil {
			return nil, err
		}
	}
	imgdir := filepath.Join(newdir, imgDirname)
	if err := downloadImages(client, imgdir, imgmap); err != nil {
		return nil, err
	}

	// cleanup:
	// - remove original dir if codelab ID has changed and so has the output dir
	// - otherwise, remove images which are not in imgs
	old := codelabDir(basedir, &meta.Meta)
	if old != newdir {
		return &meta.Meta, os.RemoveAll(old)
	}
	visit := func(p string, fi os.FileInfo, err error) error {
		if err != nil || p == imgdir {
			return err
		}
		if fi.IsDir() {
			return filepath.SkipDir
		}
		if _, ok := imgmap[filepath.Base(p)]; !ok {
			return os.Remove(p)
		}
		return nil
	}
	return &meta.Meta, filepath.Walk(imgdir, visit)
}