|
4 | 4 | "bytes" |
5 | 5 | "context" |
6 | 6 | "fmt" |
| 7 | + "net/http" |
7 | 8 | "os" |
8 | 9 | "os/exec" |
9 | 10 | "path/filepath" |
@@ -156,6 +157,37 @@ var catalogCmdDef = &cli.Command{ |
156 | 157 | util.CmdMiddlewareTracingSpan, |
157 | 158 | ), |
158 | 159 | }, |
| 160 | + { |
| 161 | + Name: "serve", |
| 162 | + Usage: "Generates html and serves", |
| 163 | + Action: util.ChainCmdMiddleware(cmdServe, |
| 164 | + util.CmdMiddlewareLogging, |
| 165 | + util.CmdMiddlewareTracingConfig, |
| 166 | + util.CmdMiddlewareTracingSpan, |
| 167 | + ), |
| 168 | + Flags: []cli.Flag{ |
| 169 | + &cli.StringFlag{ |
| 170 | + Name: "output", |
| 171 | + Aliases: []string{"o"}, |
| 172 | + Usage: "Output path for HTML generation", |
| 173 | + }, |
| 174 | + &cli.StringFlag{ |
| 175 | + Name: "url-prefix", |
| 176 | + Usage: "URL prefix for links within generated HTML", |
| 177 | + Value: "/", |
| 178 | + }, |
| 179 | + &cli.StringFlag{ |
| 180 | + Name: "download-url", |
| 181 | + Usage: "URL for warehouse to use for download links", |
| 182 | + }, |
| 183 | + &cli.UintFlag{ |
| 184 | + Name: "port", |
| 185 | + Aliases: []string{"p"}, |
| 186 | + Usage: "Port number for the server address", |
| 187 | + Value: 8080, |
| 188 | + }, |
| 189 | + }, |
| 190 | + }, |
159 | 191 | }, |
160 | 192 | } |
161 | 193 |
|
@@ -715,69 +747,116 @@ func cmdCatalogShow(c *cli.Context) error { |
715 | 747 | return nil |
716 | 748 | } |
717 | 749 |
|
718 | | -func cmdGenerateHtml(c *cli.Context) error { |
719 | | - catalogName := c.String("name") |
| 750 | +type protoSiteConfig struct { |
| 751 | + catalogName string |
| 752 | + outputPathOverride string |
| 753 | + urlPrefix string |
| 754 | + downloadUrl string |
| 755 | +} |
720 | 756 |
|
| 757 | +func (cfg protoSiteConfig) SiteConfig(ctx context.Context) (cataloghtml.SiteConfig, error) { |
721 | 758 | // open the workspace set |
722 | 759 | wsSet, err := util.OpenWorkspaceSet() |
723 | 760 | if err != nil { |
724 | | - return err |
| 761 | + return cataloghtml.SiteConfig{}, err |
725 | 762 | } |
726 | 763 |
|
727 | | - // create the catalog if it does not exist |
728 | | - exists, err := wsSet.Root().HasCatalog(catalogName) |
| 764 | + exists, err := wsSet.Root().HasCatalog(cfg.catalogName) |
729 | 765 | if err != nil { |
730 | | - return err |
| 766 | + return cataloghtml.SiteConfig{}, err |
731 | 767 | } |
732 | 768 | if !exists { |
733 | | - return fmt.Errorf("catalog %q not found", catalogName) |
| 769 | + return cataloghtml.SiteConfig{}, fmt.Errorf("catalog %q not found", cfg.catalogName) |
734 | 770 | } |
735 | 771 |
|
736 | | - cat, err := wsSet.Root().OpenCatalog(catalogName) |
| 772 | + cat, err := wsSet.Root().OpenCatalog(cfg.catalogName) |
737 | 773 | if err != nil { |
738 | | - return fmt.Errorf("failed to open catalog %q: %s", catalogName, err) |
| 774 | + return cataloghtml.SiteConfig{}, fmt.Errorf("failed to open catalog %q: %s", cfg.catalogName, err) |
739 | 775 | } |
740 | 776 |
|
741 | 777 | // by default, output to a subdir of the catalog named `_html` |
742 | 778 | // this can be overriden by a cli flag that provides a path |
743 | | - outputPath, err := wsSet.Root().CatalogPath(catalogName) |
| 779 | + outputPath, err := wsSet.Root().CatalogPath(cfg.catalogName) |
744 | 780 | if err != nil { |
745 | | - return err |
| 781 | + return cataloghtml.SiteConfig{}, err |
746 | 782 | } |
747 | 783 | outputPath = filepath.Join("/", outputPath, "_html") |
748 | | - if c.String("output") != "" { |
749 | | - outputPath = c.String("output") |
| 784 | + if cfg.outputPathOverride != "" { |
| 785 | + outputPath = cfg.outputPathOverride |
750 | 786 | } |
751 | 787 |
|
752 | 788 | // by default, the URL prefix is the same as the output path, |
753 | 789 | // this works if the HTML is accessed using `file:///` URLs. |
754 | 790 | // however, to allow for generating a hosted site, this can be |
755 | 791 | // overridden by the CLI |
756 | 792 | urlPrefix := outputPath |
757 | | - if c.String("url-prefix") != "" { |
758 | | - urlPrefix = c.String("url-prefix") |
| 793 | + if cfg.urlPrefix != "" { |
| 794 | + urlPrefix = cfg.urlPrefix |
759 | 795 | } |
760 | 796 |
|
761 | 797 | var warehouseUrl *string = nil |
762 | | - if c.String("download-url") != "" { |
763 | | - dlUrl := c.String("download-url") |
| 798 | + if cfg.downloadUrl != "" { |
| 799 | + dlUrl := cfg.downloadUrl |
764 | 800 | warehouseUrl = &dlUrl |
765 | 801 | } |
766 | 802 |
|
767 | | - cfg := cataloghtml.SiteConfig{ |
768 | | - Ctx: context.Background(), |
| 803 | + return cataloghtml.SiteConfig{ |
| 804 | + Ctx: ctx, |
769 | 805 | Cat_dab: cat, |
770 | 806 | OutputPath: outputPath, |
771 | 807 | URLPrefix: urlPrefix, |
772 | 808 | DownloadURL: warehouseUrl, |
| 809 | + }, nil |
| 810 | +} |
| 811 | + |
| 812 | +func cmdGenerateHtml(c *cli.Context) error { |
| 813 | + pcfg := protoSiteConfig{ |
| 814 | + catalogName: c.String("name"), |
| 815 | + outputPathOverride: c.String("output"), |
| 816 | + urlPrefix: c.String("url-prefix"), |
| 817 | + downloadUrl: c.String("download-url"), |
773 | 818 | } |
| 819 | + cfg, err := pcfg.SiteConfig(c.Context) |
| 820 | + if err != nil { |
| 821 | + return err |
| 822 | + } |
| 823 | + |
774 | 824 | os.RemoveAll(cfg.OutputPath) |
775 | 825 | if err := cfg.CatalogAndChildrenToHtml(); err != nil { |
776 | 826 | return fmt.Errorf("failed to generate html: %s", err) |
777 | 827 | } |
778 | 828 |
|
779 | | - fmt.Printf("published HTML for catalog %q to %s\n", catalogName, outputPath) |
| 829 | + fmt.Printf("published HTML for catalog %q to %s\n", pcfg.catalogName, cfg.OutputPath) |
| 830 | + |
| 831 | + return nil |
| 832 | +} |
780 | 833 |
|
| 834 | +func cmdServe(c *cli.Context) error { |
| 835 | + pcfg := protoSiteConfig{ |
| 836 | + catalogName: c.String("name"), |
| 837 | + outputPathOverride: c.String("output"), |
| 838 | + urlPrefix: c.String("url-prefix"), |
| 839 | + downloadUrl: c.String("download-url"), |
| 840 | + } |
| 841 | + port := c.Uint("port") |
| 842 | + addr := fmt.Sprintf("%s:%d", "localhost", port) |
| 843 | + |
| 844 | + cfg, err := pcfg.SiteConfig(c.Context) |
| 845 | + if err != nil { |
| 846 | + return err |
| 847 | + } |
| 848 | + os.RemoveAll(cfg.OutputPath) |
| 849 | + if err := cfg.CatalogAndChildrenToHtml(); err != nil { |
| 850 | + return fmt.Errorf("failed to generate html: %s", err) |
| 851 | + } |
| 852 | + |
| 853 | + fmt.Printf("published HTML for catalog %q to %s\n", pcfg.catalogName, cfg.OutputPath) |
| 854 | + |
| 855 | + dirHandler := http.Dir(cfg.OutputPath) |
| 856 | + fmt.Printf("Serving at http://%s\n", addr) |
| 857 | + if err := http.ListenAndServe(addr, http.FileServer(dirHandler)); err != nil { |
| 858 | + return err |
| 859 | + } |
781 | 860 | return nil |
782 | 861 | } |
783 | 862 |
|
|
0 commit comments