Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
sshaw committed Aug 9, 2021
0 parents commit 8f5f1d6
Show file tree
Hide file tree
Showing 14 changed files with 1,428 additions and 0 deletions.
26 changes: 26 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

# Created by https://www.toptal.com/developers/gitignore/api/go
# Edit at https://www.toptal.com/developers/gitignore?templates=go

### Go ###
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

### Go Patch ###
/vendor/
/Godeps/

# End of https://www.toptal.com/developers/gitignore/api/go
13 changes: 13 additions & 0 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin

snapshot:
name_template: "{{ .Tag }}-next"

changelog:
skip: true
187 changes: 187 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
# Shopify Development Tools

Command-line program to assist with the development and/or maintenance of Shopify apps and stores.

## Installation

Download the version for your platform on the [releases page](https://github.com/ScreenStaring/shopify_dev_tools/releases).
Windows, macOS/OS X, and GNU/Linux are supported.

## Usage

NAME:
sdt - Shopify Development Tools

USAGE:
sdt command [command options] [arguments...]

VERSION:
0.0.1

COMMANDS:
admin, a Open admin pages
metafield, m, meta Metafield utilities
shop, s Information about the given shop
webhook, webhooks, hooks, w Webhook utilities
help, h Shows a list of commands or help for one command

GLOBAL OPTIONS:
--help, -h show help (default: false)
--version, -v print the version (default: false)

### Credentials

You'll need access to the Shopify store you want to execute commands against.

#### Access Token

If the store has your app installed you can use the credentials generated when the shop installed your app:
```
sdt COMMAND --shop shopname --access-token value
```

In this scenario you will likely need to execute the command against many shops, and having to lookup the token every
time you need it can become annoying. To simplify this process you can [specify an Access Token Command](#access-token-command).

#### Key & Password

If you have access to the store via the Shopify Admin you can authenticate by
[generating private app API credentials](https://shopify.dev/tutorials/generate-api-credentials). Once obtained they can be specified as follows:
```
sdt COMMAND --shop shopname --api-key thekey --api-password thepassword
```

#### Access Token Command

Instead of specifying an access token per store you can provide a custom command that can lookup the token for the given `shop`.
For example:

```
sdt COMMAND --shop shopname --access-token '<shopify-access-token.sh'
```

Note that `--access-token`'s argument begins with a `<`. This tells Shopify Development Tools to treat the remaining argument
as a command, execute it, and use the first line of its output as shop's access token.

The access token command will be passed the shop's name, as given on the command-line.

For example, if your app used Rails `shopify-access-token.sh` may contain the following:
```sh
#!/bin/bash

shop=$1
ssh example.com 'cd /app && RAILS_ENV=production bundle exec rails r "print Shop.find_by(:shopify_domain => ARGV[0]).token" "$shop"'
```

Furthermore, you can use the [`SHOPIFY_ACCESS_TOKEN` environment variable](#environment-variables) to reduce the required options to
just `shop`:

```
export SHOPIFY_ACCESS_TOKEN='<shopify-access-token.sh'
# ...
sdt COMMAND --shop shopname
```

#### Environment Variables

You can use the following environment variables to set credentials:

- `SHOPIFY_SHOP`
- `SHOPIFY_ACCESS_TOKEN`
- `SHOPIFY_API_PASSWORD`
- `SHOPIFY_API_KEY`

### Commands

#### Metafields

Metafield utilities

NAME:
sdt metafield - Metafield utilities

USAGE:
sdt metafield command [command options] [arguments...]

COMMANDS:
product, products, prod, p
shop, s
storefront, sf Storefront API utilities
variant, var, v
help, h Shows a list of commands or help for one command

OPTIONS:
--help, -h show help (default: false)


#### Shop

Information about the given shop

NAME:
sdt shop - Information about the given shop

USAGE:
sdt shop command [command options] [arguments...]

COMMANDS:
info, i Information about the shop
help, h Shows a list of commands or help for one command

OPTIONS:
--help, -h show help (default: false)

#### Shopify Admin

Open admin pages

NAME:
sdt admin - Open admin pages

USAGE:
sdt admin command [command options] [arguments...]

COMMANDS:
order, orders, o Open the given order ID for editing; if no ID given open the orders page
product, products, prod, p Open the given product ID for editing; if no ID given open the products page
theme, t Open the currently published theme or given theme ID for editing
themes Open themes section of the admin (not for editing)
help, h Shows a list of commands or help for one command

OPTIONS:
--help, -h show help (default: false)

#### Webhooks

Webhooks utilities

NAME:
sdt webhook - Webhook utilities

USAGE:
sdt webhook command [command options] [arguments...]

COMMANDS:
create, c
delete, del, rm, d
ls
help, h Shows a list of commands or help for one command

OPTIONS:
--shop value Shopify domain or shop name to perform command against [$SHOPIFY_SHOP]
--api-password value Shopify API password [$SHOPIFY_API_PASSWORD]
--access-token value Shopify access token for shop [$SHOPIFY_ACCESS_TOKEN]
--api-key value Shopify API key to for shop [$SHOPIFY_API_KEY]
--help, -h show help (default: false)

## See Also

- [Shopify ID Export](https://github.com/ScreenStaring/shopify_id_export/) - Dump Shopify product and variant IDs —along with other identifiers— to a CSV or JSON file.

## License

Released under the MIT License: http://www.opensource.org/licenses/MIT

---

Made by [ScreenStaring](http://screenstaring.com)
151 changes: 151 additions & 0 deletions cmd/admin/admin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package admin

import (
"errors"
"fmt"
"strconv"

"github.com/pkg/browser"
"github.com/urfave/cli/v2"

"github.com/ScreenStaring/shopify-dev-tools/cmd"
)

var Cmd cli.Command

type themeOptions struct {
Fields []string `url:"fields[]"`
}

func findPublishedTheme(c *cli.Context) (int64, error) {
shopify := cmd.NewShopifyClient(c)
options := themeOptions{[]string{"id", "role"}}

themes, err := shopify.Theme.List(options)
if err != nil {
return 0, err
}

var id int64
for _, theme := range(themes) {
if theme.Role == "main" {
id = theme.ID
break
}
}

return id, nil
}

func orderAction(c *cli.Context) error {
var qs map[string]string

admin := NewAdminURL(c.String("shop"))

if c.NArg() == 0 {
browser.OpenURL(admin.Orders(qs))
return nil
}

id, err := strconv.ParseInt(c.Args().Get(0), 10, 64)
if err != nil {
return fmt.Errorf("Order id '%s' invalid: must be an int", c.Args().Get(0))
}

browser.OpenURL(admin.Order(id, qs))
return nil
}


func productAction(c *cli.Context) error {
var qs map[string]string

admin := NewAdminURL(c.String("shop"))

if c.NArg() == 0 {
browser.OpenURL(admin.Products(qs))
return nil
}

id, err := strconv.ParseInt(c.Args().Get(0), 10, 64)
if err != nil {
return fmt.Errorf("Product id '%s' invalid: must be an int", c.Args().Get(0))
}

browser.OpenURL(admin.Product(id, qs))
return nil
}


func themeAction(c *cli.Context) error {
var id int64
var err error

var qs map[string]string

admin := NewAdminURL(c.String("shop"))

if c.NArg() == 0 {
id, err = findPublishedTheme(c)
if err != nil {
return fmt.Errorf("Error finding published theme: %s", err)
}

if id == 0 {
return errors.New("No published theme")
}
} else {
id, err = strconv.ParseInt(c.Args().Get(0), 10, 64)
if err != nil {
return fmt.Errorf("Theme id '%s' invalid: must be an int", c.Args().Get(0))
}
}

browser.OpenURL(admin.Theme(id, qs))
return nil
}

func themesAction(c *cli.Context) error {
var qs map[string]string

admin := NewAdminURL(c.String("shop"))
browser.OpenURL(admin.Themes(qs))
return nil
}

func init() {
Cmd = cli.Command{
Name: "admin",
Aliases: []string{"a"},
Usage: "Open admin pages",
Subcommands: []*cli.Command{
{
Name: "order",
Aliases: []string{"orders", "o"},
Usage: "Open the given order ID for editing; if no ID given open the orders page",
Flags: cmd.Flags,
Action: orderAction,
},
{
Name: "product",
Aliases: []string{"products", "prod", "p"},
Usage: "Open the given product ID for editing; if no ID given open the products page",
Flags: cmd.Flags,
Action: productAction,
},
{
Name: "theme",
Usage: "Open the currently published theme or given theme ID for editing",
Aliases: []string{"t"},
Flags: cmd.Flags,
Action: themeAction,
},
{
Name: "themes",
Usage: "Open themes section of the admin (not for editing)",
Flags: cmd.Flags,
Action: themesAction,
},
},
}
}
Loading

0 comments on commit 8f5f1d6

Please sign in to comment.