Documentation
¶
Index ¶
- Constants
- Variables
- func ProfileApp(script string, config map[string]string) (*pprof_profile.Profile, error)
- func SetAuth(cmd *cobra.Command, args []string) error
- type FetchFunc
- type TidbytAppDeploy
- type TidbytBundleUpload
- type TidbytCreateAppReply
- type TidbytCreateAppRequest
- type TidbytInstallationJSON
- type TidbytInstallationListJSON
- type TidbytPushJSON
Constants ¶
View Source
const ( TidbytAPIPush = "https://api.tidbyt.com/v0/devices/%s/push" APITokenEnv = "TIDBYT_API_TOKEN" )
View Source
const MaxRenderTime = 500000000 // 500ms
View Source
const PublicKeysetJSON = `` /* 543-byte string literal not displayed */
View Source
const (
TidbytAPIDelete = "https://api.tidbyt.com/v0/devices/%s/installations/%s"
)
View Source
const (
TidbytAPIList = "https://api.tidbyt.com/v0/devices/%s/installations"
)
View Source
const (
TidbytAPIListDevices = "https://api.tidbyt.com/v0/devices"
)
Variables ¶
View Source
var BundleCmd = &cobra.Command{ Use: "bundle", Short: "Creates a new app bundle", Example: ` pixlet bundle apps/fuzzyclock/`, Long: `This command will create a new app bundle from an app directory. The directory should contain an app manifest and source file. The output of this command will be a gzip compressed tar file that can be uploaded to Tidbyt for deployment.`, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { bundleInput := args[0] info, err := os.Stat(bundleInput) if err != nil { return fmt.Errorf("input directory invalid: %w", err) } if !info.IsDir() { return fmt.Errorf("input must be a directory") } info, err = os.Stat(bundleOutput) if err != nil { return fmt.Errorf("output directory invalid: %w", err) } if !info.IsDir() { return fmt.Errorf("output must be a directory") } ab, err := bundle.InitFromPath(bundleInput) if err != nil { return fmt.Errorf("could not init bundle: %w", err) } return ab.WriteBundleToPath(bundleOutput) }, }
View Source
var CheckCmd = &cobra.Command{ Use: "check <pathspec>...", Example: ` pixlet check app.star`, Short: "Checks if an app is ready to publish", Long: `The check command runs a series of checks to ensure your app is ready to publish in the community repo. Every failed check will have a solution provided. If your app fails a check, try the provided solution and reach out on Discord if you get stuck.`, Args: cobra.MinimumNArgs(1), RunE: checkCmd, }
View Source
var CreateCmd = &cobra.Command{ Use: "create", Short: "Creates a new app", Long: `This command will prompt for all of the information we need to generate a new Tidbyt app. No flags are necessary unless you are creating a private app, which is only available with our Tidbyt For Teams offering.`, RunE: func(cmd *cobra.Command, args []string) error { cwd, err := os.Getwd() if err != nil { return fmt.Errorf("app creation failed, something went wrong with your local filesystem: %w", err) } // Determine what type of app this is an what the root should be. var root string var appType generator.AppType if repo.IsInRepo(cwd, "community") { appType = generator.Community root, err = repo.RepoRoot(cwd) if err != nil { return fmt.Errorf("app creation failed, something went wrong with your community repo: %w", err) } } else if repo.IsInRepo(cwd, "tidbyt") { appType = generator.Internal root, err = repo.RepoRoot(cwd) if err != nil { return fmt.Errorf("app creation failed, something went wrong with your tidbyt repo: %w", err) } } else { appType = generator.Local root = cwd } app, err := community.ManifestPrompt() if err != nil { return fmt.Errorf("app creation, couldn't get user input: %w", err) } if createPrivate { apiToken := oauthTokenFromConfig(cmd.Context()) if apiToken == "" { return fmt.Errorf("login with `pixlet login` or use `pixlet set-auth` to configure auth") } if createOrg == "" { return fmt.Errorf("organization must not be blank") } app.ID, err = createPrivateApp(apiToken, createOrg) if err != nil { if strings.Contains(err.Error(), "user is not authorized to create apps") { return fmt.Errorf("user is not authorized to create apps for organization %s, please reach out to your Tidbyt For Teams account representative to enable this feature for your account", createOrg) } return fmt.Errorf("remote app creation failed: %w", err) } } g, err := generator.NewGenerator(appType, root) if err != nil { return fmt.Errorf("app creation failed %w", err) } absolutePath, err := g.GenerateApp(app) if err != nil { return fmt.Errorf("app creation failed: %w", err) } relativePath, err := filepath.Rel(cwd, absolutePath) if err != nil { return fmt.Errorf("app was created, but we don't know where: %w", err) } fmt.Println("") fmt.Println("App created at:") fmt.Printf("\t%s\n", absolutePath) fmt.Println("") fmt.Println("To start the app, run:") fmt.Printf("\tpixlet serve %s\n", relativePath) fmt.Println("") fmt.Println("For docs, head to:") fmt.Printf("\thttps://tidbyt.dev\n") if createPrivate { fmt.Println("") fmt.Println("To deploy your app:") fmt.Printf("\tpixlet bundle ./\n") fmt.Printf("\tpixlet upload bundle.tar.gz --app %s --version v0.0.1\n", app.ID) fmt.Printf("\tpixlet deploy --app %s --version v0.0.1\n", app.ID) } return nil }, }
CreateCmd prompts the user for info and generates a new app.
View Source
var DeleteCmd = &cobra.Command{ Use: "delete [device ID] [installation ID]", Short: "Delete a pixlet script from a Tidbyt", Args: cobra.MinimumNArgs(2), RunE: delete, }
View Source
var DeployCmd = &cobra.Command{ Use: "deploy", Short: "Deploys an app to production (internal only)", Example: ` pixlet deploy --app fuzzy-clock --version v0.0.1`, Long: `This command will deploy an app to production in the Tidbyt backend. Note, this command is for internal use only at the moment, and normal API tokens will not be able to deploy apps. We fully intend to make this command generally available once our backend can support public deploys.`, RunE: func(cmd *cobra.Command, args []string) error { apiToken := oauthTokenFromConfig(cmd.Context()) if apiToken == "" { return fmt.Errorf("login with `pixlet login` or use `pixlet set-auth` to configure auth") } if deployAppID == "" { return fmt.Errorf("app must not be blank") } if deployVersion == "" { return fmt.Errorf("version must not be blank") } d := &TidbytAppDeploy{ AppID: deployAppID, Version: deployVersion, } b, err := json.Marshal(d) if err != nil { return fmt.Errorf("could not create http request: %w", err) } requestURL := fmt.Sprintf("%s/v0/apps/%s/deploy", deployURL, deployAppID) req, err := http.NewRequest(http.MethodPost, requestURL, bytes.NewBuffer(b)) if err != nil { return fmt.Errorf("could not create http request: %w", err) } req.Header.Set("Content-Type", "application/json") req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", apiToken)) client := http.Client{ Timeout: 30 * time.Second, } resp, err := client.Do(req) if err != nil { return fmt.Errorf("could not make HTTP request to %s: %w", requestURL, err) } defer resp.Body.Close() if resp.StatusCode != 200 { body, _ := io.ReadAll(resp.Body) return fmt.Errorf("request returned status %d with message: %s", resp.StatusCode, body) } return nil }, }
View Source
var DevicesCmd = &cobra.Command{
Use: "devices",
Short: "List devices in your Tidbyt account",
Run: devices,
}
View Source
var EncryptCmd = &cobra.Command{ Use: "encrypt [app name] [secret value]...", Short: "Encrypt a secret for use in the Tidbyt community repo", Example: "encrypt weather my-top-secretweather-api-key-123456", Args: cobra.MinimumNArgs(2), Run: encrypt, }
View Source
var FormatCmd = &cobra.Command{ Use: "format <pathspec>...", Short: "Formats Tidbyt apps", Example: ` pixlet format app.star pixlet format app.star --dry-run pixlet format --recursive ./`, Long: `The format command provides a code formatter for Tidbyt apps. By default, it will format your starlark source code in line. If you wish you see the output before applying, add the --dry-run flag.`, Args: cobra.MinimumNArgs(1), RunE: formatCmd, }
View Source
var LintCmd = &cobra.Command{ Use: "lint <pathspec>...", Example: ` pixlet lint app.star pixlet lint --recursive --fix ./`, Short: "Lints Tidbyt apps", Long: `The lint command provides a linter for Tidbyt apps. It's capable of linting a file, a list of files, or directory with the recursive option. Additionally, it provides an option to automatically fix resolvable linter issues.`, Args: cobra.MinimumNArgs(1), RunE: lintCmd, }
View Source
var ListCmd = &cobra.Command{ Use: "list [device ID]", Short: "Lists all apps installed on a Tidbyt", Args: cobra.MinimumNArgs(1), RunE: listInstallations, }
View Source
var LoginCmd = &cobra.Command{
Use: "login",
Short: "Login to your Tidbyt account",
Example: "login",
Run: login,
}
View Source
var ProfileCmd = &cobra.Command{ Use: "profile [script] [<key>=value>]...", Short: "Run a Pixlet script and print its execution-time profile", Args: cobra.MinimumNArgs(1), RunE: profile, }
View Source
var PushCmd = &cobra.Command{ Use: "push [device ID] [webp image]", Short: "Render a Pixlet script and push the WebP output to a Tidbyt", Args: cobra.MinimumNArgs(2), RunE: push, }
View Source
var RenderCmd = &cobra.Command{ Use: "render [script] [<key>=value>]...", Short: "Run a Pixlet script with provided config parameters", Args: cobra.MinimumNArgs(1), RunE: render, }
View Source
var ServeCmd = &cobra.Command{ Use: "serve [script]", Short: "Serve a Pixlet app in a web server", Args: cobra.ExactArgs(1), RunE: serve, }
View Source
var SetAuthCmd = &cobra.Command{ Use: "set-auth", Short: "Sets a custom access token in the private pixlet config.", Example: ` pixlet set-auth <token_json>`, Long: `This command sets a custom access token for use in subsequent runs. Normal users should not need this - use 'pixlet login' instead.`, Args: cobra.ExactArgs(1), RunE: SetAuth, }
View Source
var UploadCmd = &cobra.Command{ Use: "upload", Short: "Uploads an app bundle to Tidbyt (internal only)", Example: ` pixlet upload bundle.tar.gz --app fuzzy-clock --version v0.0.1 --token {{ api_token }}`, Long: `This command will upload an app bundle (see pixlet bundle) using the specified app ID and version. Note, this is for internal use only at the moment, and normal API tokens will not work with this command. We fully intend to make this command public once our backend is well positioned to support it.`, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { bundleFile := args[0] info, err := os.Stat(bundleFile) if err != nil { return fmt.Errorf("input bundle file invalid: %w", err) } if info.IsDir() { return fmt.Errorf("input bundle must be a file") } if !strings.HasSuffix(bundleFile, "tar.gz") { return fmt.Errorf("input bundle format is not correct, did you create it with `pixlet bundle`?") } apiToken := oauthTokenFromConfig(cmd.Context()) if apiToken == "" { return fmt.Errorf("login with `pixlet login` or use `pixlet set-auth` to configure auth") } if uploadAppID == "" { return fmt.Errorf("app must not be blank") } if uploadVersion == "" { return fmt.Errorf("version must not be blank") } f, err := os.Open(bundleFile) if err != nil { return fmt.Errorf("could not open bundle: %w", err) } defer f.Close() ab, err := bundle.LoadBundle(f) if err != nil { return fmt.Errorf("could not load bundle: %w", err) } buf := &bytes.Buffer{} err = ab.WriteBundle(buf) if err != nil { return fmt.Errorf("could not re-create bundle: %w", err) } uploadBundle := &TidbytBundleUpload{ AppID: uploadAppID, Version: uploadVersion, Bundle: base64.StdEncoding.EncodeToString(buf.Bytes()), } b, err := json.Marshal(uploadBundle) if err != nil { return fmt.Errorf("could not marshal request: %w", err) } requestURL := fmt.Sprintf("%s/v0/apps/%s/upload", uploadURL, uploadAppID) req, err := http.NewRequest(http.MethodPost, requestURL, bytes.NewReader(b)) if err != nil { return fmt.Errorf("could not create http request: %w", err) } req.Header.Set("Content-Type", "application/json") req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", apiToken)) client := http.Client{ Timeout: 30 * time.Second, } resp, err := client.Do(req) if err != nil { return fmt.Errorf("could not make HTTP request to %s: %w", requestURL, err) } defer resp.Body.Close() if resp.StatusCode != 200 { body, _ := io.ReadAll(resp.Body) return fmt.Errorf("request returned status %d with message: %s", resp.StatusCode, body) } return nil }, }
View Source
var Version string
Functions ¶
func ProfileApp ¶ added in v0.27.1
Types ¶
type FetchFunc ¶ added in v0.17.16
type FetchFunc func(src string, duration, timeout time.Duration) (*pprof_profile.Profile, string, error)
We save the profile into an in-memory buffer, which is simpler than the tool expects. Simple adapter to pipe it through.
func MakeFetchFunc ¶ added in v0.17.16
func MakeFetchFunc(prof *pprof_profile.Profile) FetchFunc
type TidbytAppDeploy ¶ added in v0.25.0
type TidbytBundleUpload ¶ added in v0.25.0
type TidbytCreateAppReply ¶ added in v0.28.1
type TidbytCreateAppReply struct {
AppID string `json:"appID"`
}
type TidbytCreateAppRequest ¶ added in v0.28.1
type TidbytCreateAppRequest struct {
OrganizationID string `json:"organizationID"`
}
type TidbytInstallationJSON ¶ added in v0.28.0
type TidbytInstallationListJSON ¶ added in v0.28.0
type TidbytInstallationListJSON struct {
Installations []TidbytInstallationJSON `json:"installations"`
}
Source Files
¶
Click to show internal directories.
Click to hide internal directories.