// 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) }
// 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) }