Cleaning up runner API prior to package rewrite
This commit is contained in:
parent
e051c4a982
commit
622c90c82c
|
@ -90,7 +90,7 @@ func New(ctxt context.Context, opts ...Option) (*CDP, error) {
|
||||||
|
|
||||||
// watch handlers
|
// watch handlers
|
||||||
if c.watch == nil {
|
if c.watch == nil {
|
||||||
c.watch = c.r.WatchPageTargets(ctxt)
|
c.watch = c.r.Client().WatchPageTargets(ctxt)
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
|
6
pool.go
6
pool.go
|
@ -74,7 +74,11 @@ func (p *Pool) Allocate(ctxt context.Context, opts ...runner.CommandLineOption)
|
||||||
|
|
||||||
// create runner
|
// create runner
|
||||||
r.r, err = runner.New(append([]runner.CommandLineOption{
|
r.r, err = runner.New(append([]runner.CommandLineOption{
|
||||||
runner.HeadlessPathPort("", r.port),
|
runner.ExecPath(runner.LookChromeNames("headless_shell")),
|
||||||
|
runner.RemoteDebuggingPort(r.port),
|
||||||
|
runner.NoDefaultBrowserCheck,
|
||||||
|
runner.NoFirstRun,
|
||||||
|
runner.Headless,
|
||||||
}, opts...)...)
|
}, opts...)...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
defer r.Release()
|
defer r.Release()
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
package runner
|
package runner
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DefaultChromePath is the default path to the Chrome application.
|
// DefaultChromePath is the default path to use for Chrome if the
|
||||||
|
// executable is not in $PATH.
|
||||||
DefaultChromePath = `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`
|
DefaultChromePath = `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`
|
||||||
)
|
)
|
||||||
|
|
||||||
func findChromePath() string {
|
// DefaultChromeNames are the default Chrome executable names to look for in
|
||||||
return DefaultChromePath
|
// $PATH.
|
||||||
}
|
var DefaultChromeNames []string
|
||||||
|
|
|
@ -2,30 +2,18 @@
|
||||||
|
|
||||||
package runner
|
package runner
|
||||||
|
|
||||||
import "os/exec"
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DefaultChromePath is the default path to the google-chrome executable if
|
// DefaultChromePath is the default path to use for Chrome if the
|
||||||
// a variant cannot be found on $PATH.
|
// executable is not in $PATH.
|
||||||
DefaultChromePath = "/usr/bin/google-chrome"
|
DefaultChromePath = "/usr/bin/google-chrome"
|
||||||
)
|
)
|
||||||
|
|
||||||
// chromeNames are the Chrome executable names to search for in the path.
|
// DefaultChromeNames are the default Chrome executable names to look for in
|
||||||
var chromeNames = []string{
|
// $PATH.
|
||||||
|
var DefaultChromeNames = []string{
|
||||||
"google-chrome",
|
"google-chrome",
|
||||||
"chromium-browser",
|
"chromium-browser",
|
||||||
"chromium",
|
"chromium",
|
||||||
"google-chrome-beta",
|
"google-chrome-beta",
|
||||||
"google-chrome-unstable",
|
"google-chrome-unstable",
|
||||||
}
|
}
|
||||||
|
|
||||||
func findChromePath() string {
|
|
||||||
for _, p := range chromeNames {
|
|
||||||
path, err := exec.LookPath(p)
|
|
||||||
if err == nil {
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return DefaultChromePath
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,32 +2,12 @@
|
||||||
|
|
||||||
package runner
|
package runner
|
||||||
|
|
||||||
import "os/exec"
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DefaultChromePath is the default path to use for Google Chrome if the
|
// DefaultChromePath is the default path to use for Chrome if the
|
||||||
// executable is not in %PATH%.
|
// executable is not in %PATH%.
|
||||||
DefaultChromePath = `C:\Program Files (x86)\Google\Chrome\Application\chrome.exe`
|
DefaultChromePath = `C:\Program Files (x86)\Google\Chrome\Application\chrome.exe`
|
||||||
|
|
||||||
// DefaultEdgeDiagnosticsAdapterPath is the default path to use for the
|
|
||||||
// Microsoft Edge Diagnostics Adapter if the executable is not in %PATH%.
|
|
||||||
DefaultEdgeDiagnosticsAdapterPath = `c:\Edge\EdgeDiagnosticsAdapter\x64\EdgeDiagnosticsAdapter.exe`
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func findChromePath() string {
|
// DefaultChromeNames are the default Chrome executable names to look for in
|
||||||
path, err := exec.LookPath(`chrome.exe`)
|
// %PATH%.
|
||||||
if err == nil {
|
var DefaultChromeNames = []string{`chrome.exe`}
|
||||||
return path
|
|
||||||
}
|
|
||||||
|
|
||||||
return DefaultChromePath
|
|
||||||
}
|
|
||||||
|
|
||||||
func findEdgePath() string {
|
|
||||||
path, err := exec.LookPath(`EdgeDiagnosticsAdapter.exe`)
|
|
||||||
if err == nil {
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
|
|
||||||
return DefaultEdgeDiagnosticsAdapterPath
|
|
||||||
}
|
|
||||||
|
|
192
runner/runner.go
192
runner/runner.go
|
@ -5,7 +5,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/url"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -16,6 +15,11 @@ import (
|
||||||
"github.com/chromedp/chromedp/client"
|
"github.com/chromedp/chromedp/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// DefaultUserDataDirPrefix is the default user data directory prefix.
|
||||||
|
DefaultUserDataDirPrefix = "chromedp-runner.%d."
|
||||||
|
)
|
||||||
|
|
||||||
// Error is a runner error.
|
// Error is a runner error.
|
||||||
type Error string
|
type Error string
|
||||||
|
|
||||||
|
@ -32,19 +36,17 @@ const (
|
||||||
// ErrAlreadyWaiting is the already waiting error.
|
// ErrAlreadyWaiting is the already waiting error.
|
||||||
ErrAlreadyWaiting Error = "already waiting"
|
ErrAlreadyWaiting Error = "already waiting"
|
||||||
|
|
||||||
|
// ErrInvalidURLs is the invalid url-opts error.
|
||||||
|
ErrInvalidURLOpts Error = "invalid url-opts"
|
||||||
|
|
||||||
// ErrInvalidCmdOpts is the invalid cmd-opts error.
|
// ErrInvalidCmdOpts is the invalid cmd-opts error.
|
||||||
ErrInvalidCmdOpts Error = "invalid cmd-opts"
|
ErrInvalidCmdOpts Error = "invalid cmd-opts"
|
||||||
|
|
||||||
// ErrInvalidProcessOpts is the invalid process-opts error.
|
// ErrInvalidProcessOpts is the invalid process-opts error.
|
||||||
ErrInvalidProcessOpts Error = "invalid process-opts"
|
ErrInvalidProcessOpts Error = "invalid process-opts"
|
||||||
|
|
||||||
// ErrExecPathNotSet is the exec-path not set set error.
|
// ErrInvalidExecPath is the invalid exec-path error.
|
||||||
ErrExecPathNotSet Error = "exec-path command line option not set, or chrome executable not found in PATH"
|
ErrInvalidExecPath Error = "invalid exec-path"
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// DefaultUserDataDirPrefix is the default user data directory prefix.
|
|
||||||
DefaultUserDataDirPrefix = "chromedp-runner.%d."
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Runner holds information about a running Chrome process.
|
// Runner holds information about a running Chrome process.
|
||||||
|
@ -59,19 +61,18 @@ type Runner struct {
|
||||||
func New(opts ...CommandLineOption) (*Runner, error) {
|
func New(opts ...CommandLineOption) (*Runner, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
cliOpts := map[string]interface{}{}
|
cliOpts := make(map[string]interface{})
|
||||||
|
|
||||||
// apply opts
|
// apply opts
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
err = o(cliOpts)
|
if err = o(cliOpts); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set default Chrome options if exec-path not provided
|
// set default Chrome options if exec-path not provided
|
||||||
if _, ok := cliOpts["exec-path"]; !ok {
|
if _, ok := cliOpts["exec-path"]; !ok {
|
||||||
cliOpts["exec-path"] = findChromePath()
|
cliOpts["exec-path"] = LookChromeNames()
|
||||||
for k, v := range map[string]interface{}{
|
for k, v := range map[string]interface{}{
|
||||||
"no-first-run": true,
|
"no-first-run": true,
|
||||||
"no-default-browser-check": true,
|
"no-default-browser-check": true,
|
||||||
|
@ -86,8 +87,7 @@ func New(opts ...CommandLineOption) (*Runner, error) {
|
||||||
// add KillProcessGroup and ForceKill if no other cmd opts provided
|
// add KillProcessGroup and ForceKill if no other cmd opts provided
|
||||||
if _, ok := cliOpts["cmd-opts"]; !ok {
|
if _, ok := cliOpts["cmd-opts"]; !ok {
|
||||||
for _, o := range []CommandLineOption{KillProcessGroup, ForceKill} {
|
for _, o := range []CommandLineOption{KillProcessGroup, ForceKill} {
|
||||||
err = o(cliOpts)
|
if err = o(cliOpts); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,9 +104,9 @@ var cliOptRE = regexp.MustCompile(`^[a-z0-9\-]+$`)
|
||||||
// buildOpts generates the command line options for Chrome.
|
// buildOpts generates the command line options for Chrome.
|
||||||
func (r *Runner) buildOpts() []string {
|
func (r *Runner) buildOpts() []string {
|
||||||
var opts []string
|
var opts []string
|
||||||
|
var urls []string
|
||||||
|
|
||||||
// process options
|
// process opts
|
||||||
var urlstr string
|
|
||||||
for k, v := range r.opts {
|
for k, v := range r.opts {
|
||||||
if !cliOptRE.MatchString(k) || v == nil {
|
if !cliOptRE.MatchString(k) || v == nil {
|
||||||
continue
|
continue
|
||||||
|
@ -116,8 +116,8 @@ func (r *Runner) buildOpts() []string {
|
||||||
case "exec-path", "cmd-opts", "process-opts":
|
case "exec-path", "cmd-opts", "process-opts":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
case "start-url":
|
case "url-opts":
|
||||||
urlstr = v.(string)
|
urls = v.([]string)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
switch z := v.(type) {
|
switch z := v.(type) {
|
||||||
|
@ -135,16 +135,16 @@ func (r *Runner) buildOpts() []string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if urlstr == "" {
|
if urls == nil {
|
||||||
urlstr = "about:blank"
|
urls = append(urls, "about:blank")
|
||||||
}
|
}
|
||||||
|
|
||||||
return append(opts, urlstr)
|
return append(opts, urls...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start starts a Chrome process using the specified context. The Chrome
|
// Start starts a Chrome process using the specified context. The Chrome
|
||||||
// process can be terminated by closing the passed context.
|
// process can be terminated by closing the passed context.
|
||||||
func (r *Runner) Start(ctxt context.Context) error {
|
func (r *Runner) Start(ctxt context.Context, opts ...string) error {
|
||||||
var err error
|
var err error
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|
||||||
|
@ -156,11 +156,6 @@ func (r *Runner) Start(ctxt context.Context) error {
|
||||||
return ErrAlreadyStarted
|
return ErrAlreadyStarted
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup context
|
|
||||||
if ctxt == nil {
|
|
||||||
ctxt = context.Background()
|
|
||||||
}
|
|
||||||
|
|
||||||
// set user data dir, if not provided
|
// set user data dir, if not provided
|
||||||
_, ok = r.opts["user-data-dir"]
|
_, ok = r.opts["user-data-dir"]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -172,36 +167,41 @@ func (r *Runner) Start(ctxt context.Context) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure exec-path set
|
// get exec path
|
||||||
execPath, ok := r.opts["exec-path"]
|
var execPath string
|
||||||
if !ok {
|
if p, ok := r.opts["exec-path"]; ok {
|
||||||
return ErrExecPathNotSet
|
execPath, ok = p.(string)
|
||||||
|
if !ok {
|
||||||
|
return ErrInvalidExecPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure execPath is valid
|
||||||
|
if execPath == "" {
|
||||||
|
return ErrInvalidExecPath
|
||||||
}
|
}
|
||||||
|
|
||||||
// create cmd
|
// create cmd
|
||||||
r.cmd = exec.CommandContext(ctxt, execPath.(string), r.buildOpts()...)
|
r.cmd = exec.CommandContext(ctxt, execPath, append(r.buildOpts(), opts...)...)
|
||||||
|
|
||||||
// apply cmd opts
|
// apply cmd opts
|
||||||
if cmdOpts, ok := r.opts["cmd-opts"]; ok {
|
if cmdOpts, ok := r.opts["cmd-opts"]; ok {
|
||||||
for _, co := range cmdOpts.([]func(*exec.Cmd) error) {
|
for _, co := range cmdOpts.([]func(*exec.Cmd) error) {
|
||||||
err = co(r.cmd)
|
if err = co(r.cmd); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// start process
|
// start process
|
||||||
err = r.cmd.Start()
|
if err = r.cmd.Start(); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply process opts
|
// apply process opts
|
||||||
if processOpts, ok := r.opts["process-opts"]; ok {
|
if processOpts, ok := r.opts["process-opts"]; ok {
|
||||||
for _, po := range processOpts.([]func(*os.Process) error) {
|
for _, po := range processOpts.([]func(*os.Process) error) {
|
||||||
err = po(r.cmd.Process)
|
if err = po(r.cmd.Process); err != nil {
|
||||||
if err != nil {
|
|
||||||
// TODO: do something better here, as we want to kill
|
// TODO: do something better here, as we want to kill
|
||||||
// the child process, do cleanup, etc.
|
// the child process, do cleanup, etc.
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -305,12 +305,6 @@ func (r *Runner) Client(opts ...client.Option) *client.Client {
|
||||||
)...)
|
)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WatchPageTargets returns a channel that will receive new page targets as
|
|
||||||
// they are created.
|
|
||||||
func (r *Runner) WatchPageTargets(ctxt context.Context, opts ...client.Option) <-chan client.Target {
|
|
||||||
return r.Client(opts...).WatchPageTargets(ctxt)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run starts a new Chrome process runner, using the provided context and
|
// Run starts a new Chrome process runner, using the provided context and
|
||||||
// command line options.
|
// command line options.
|
||||||
func Run(ctxt context.Context, opts ...CommandLineOption) (*Runner, error) {
|
func Run(ctxt context.Context, opts ...CommandLineOption) (*Runner, error) {
|
||||||
|
@ -323,20 +317,19 @@ func Run(ctxt context.Context, opts ...CommandLineOption) (*Runner, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// start
|
// start
|
||||||
err = r.Start(ctxt)
|
if err = r.Start(ctxt); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CommandLineOption is a Chrome command line option.
|
// CommandLineOption is a runner command line option.
|
||||||
//
|
//
|
||||||
// see: http://peter.sh/experiments/chromium-command-line-switches/
|
// see: http://peter.sh/experiments/chromium-command-line-switches/
|
||||||
type CommandLineOption func(map[string]interface{}) error
|
type CommandLineOption func(map[string]interface{}) error
|
||||||
|
|
||||||
// Flag is a generic Chrome command line option to pass a name=value flag to
|
// Flag is a generic command line option to pass a name=value flag to
|
||||||
// Chrome.
|
// Chrome.
|
||||||
func Flag(name string, value interface{}) CommandLineOption {
|
func Flag(name string, value interface{}) CommandLineOption {
|
||||||
return func(m map[string]interface{}) error {
|
return func(m map[string]interface{}) error {
|
||||||
|
@ -360,33 +353,12 @@ func Path(path string) CommandLineOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HeadlessPathPort is the Chrome command line option to set the default
|
// ExecPath is a command line option to set the exec path.
|
||||||
// settings for running the headless_shell executable. If path is empty, then
|
|
||||||
// an attempt will be made to find headless_shell on the path.
|
|
||||||
func HeadlessPathPort(path string, port int) CommandLineOption {
|
|
||||||
if path == "" {
|
|
||||||
path, _ = exec.LookPath("headless_shell")
|
|
||||||
}
|
|
||||||
|
|
||||||
return func(m map[string]interface{}) error {
|
|
||||||
m["exec-path"] = path
|
|
||||||
m["remote-debugging-port"] = port
|
|
||||||
m["headless"] = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExecPath is a Chrome command line option to set the exec path.
|
|
||||||
func ExecPath(path string) CommandLineOption {
|
func ExecPath(path string) CommandLineOption {
|
||||||
return Flag("exec-path", path)
|
return Flag("exec-path", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Port is the Chrome command line option to set the remote debugging port.
|
// UserDataDir is the command line option to set the user data dir.
|
||||||
func Port(port int) CommandLineOption {
|
|
||||||
return Flag("remote-debugging-port", port)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UserDataDir is the Chrome command line option to set the user data dir.
|
|
||||||
//
|
//
|
||||||
// Note: set this option to manually set the profile directory used by Chrome.
|
// Note: set this option to manually set the profile directory used by Chrome.
|
||||||
// When this is not set, then a default path will be created in the /tmp
|
// When this is not set, then a default path will be created in the /tmp
|
||||||
|
@ -395,27 +367,17 @@ func UserDataDir(dir string) CommandLineOption {
|
||||||
return Flag("user-data-dir", dir)
|
return Flag("user-data-dir", dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartURL is the Chrome command line option to set the initial URL.
|
// ProxyServer is the command line option to set the outbound proxy server.
|
||||||
func StartURL(urlstr string) CommandLineOption {
|
func ProxyServer(proxy string) CommandLineOption {
|
||||||
return Flag("start-url", urlstr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proxy is the Chrome command line option to set the outbound proxy.
|
|
||||||
func Proxy(proxy string) CommandLineOption {
|
|
||||||
return Flag("proxy-server", proxy)
|
return Flag("proxy-server", proxy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProxyPacURL is the Chrome command line option to set the URL of a proxy PAC file.
|
// WindowSize is the command line option to set the initial window size.
|
||||||
func ProxyPacURL(pacURL url.URL) CommandLineOption {
|
|
||||||
return Flag("proxy-pac-url", pacURL.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
// WindowSize is the Chrome command line option to set the initial window size.
|
|
||||||
func WindowSize(width, height int) CommandLineOption {
|
func WindowSize(width, height int) CommandLineOption {
|
||||||
return Flag("window-size", fmt.Sprintf("%d,%d", width, height))
|
return Flag("window-size", fmt.Sprintf("%d,%d", width, height))
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserAgent is the Chrome command line option to set the default User-Agent
|
// UserAgent is the command line option to set the default User-Agent
|
||||||
// header.
|
// header.
|
||||||
func UserAgent(userAgent string) CommandLineOption {
|
func UserAgent(userAgent string) CommandLineOption {
|
||||||
return Flag("user-agent", userAgent)
|
return Flag("user-agent", userAgent)
|
||||||
|
@ -438,45 +400,83 @@ func NoDefaultBrowserCheck(m map[string]interface{}) error {
|
||||||
return Flag("no-default-browser-check", true)(m)
|
return Flag("no-default-browser-check", true)(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisableGPU is the Chrome command line option to disable the GPU process.
|
// RemoteDebuggingPort is the command line option to set the remote
|
||||||
|
// debugging port.
|
||||||
|
func RemoteDebuggingPort(port int) CommandLineOption {
|
||||||
|
return Flag("remote-debugging-port", port)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Headless is the command line option to run in headless mode.
|
||||||
|
func Headless(m map[string]interface{}) error {
|
||||||
|
return Flag("headless", true)(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableGPU is the command line option to disable the GPU process.
|
||||||
func DisableGPU(m map[string]interface{}) error {
|
func DisableGPU(m map[string]interface{}) error {
|
||||||
return Flag("disable-gpu", true)(m)
|
return Flag("disable-gpu", true)(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CmdOpt is a Chrome command line option to modify the underlying exec.Cmd
|
// URL is the command line option to add a URL to open on process start.
|
||||||
// prior to invocation.
|
//
|
||||||
|
// Note: this can be specified multiple times, and each URL will be opened in a
|
||||||
|
// new tab.
|
||||||
|
func URL(urlstr string) CommandLineOption {
|
||||||
|
return func(m map[string]interface{}) error {
|
||||||
|
var urls []string
|
||||||
|
if u, ok := m["url-opts"]; ok {
|
||||||
|
urls, ok = u.([]string)
|
||||||
|
if !ok {
|
||||||
|
return ErrInvalidURLOpts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m["url-opts"] = append(urls, urlstr)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CmdOpt is a command line option to modify the underlying exec.Cmd
|
||||||
|
// prior to the call to exec.Cmd.Start in Run.
|
||||||
func CmdOpt(o func(*exec.Cmd) error) CommandLineOption {
|
func CmdOpt(o func(*exec.Cmd) error) CommandLineOption {
|
||||||
return func(m map[string]interface{}) error {
|
return func(m map[string]interface{}) error {
|
||||||
var opts []func(*exec.Cmd) error
|
var opts []func(*exec.Cmd) error
|
||||||
|
|
||||||
if e, ok := m["cmd-opts"]; ok {
|
if e, ok := m["cmd-opts"]; ok {
|
||||||
opts, ok = e.([]func(*exec.Cmd) error)
|
opts, ok = e.([]func(*exec.Cmd) error)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrInvalidCmdOpts
|
return ErrInvalidCmdOpts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m["cmd-opts"] = append(opts, o)
|
m["cmd-opts"] = append(opts, o)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessOpt is a Chrome command line option to modify the child os.Process
|
// ProcessOpt is a command line option to modify the child os.Process
|
||||||
// after started exec.Cmd.Start.
|
// after the call to exec.Cmd.Start in Run.
|
||||||
func ProcessOpt(o func(*os.Process) error) CommandLineOption {
|
func ProcessOpt(o func(*os.Process) error) CommandLineOption {
|
||||||
return func(m map[string]interface{}) error {
|
return func(m map[string]interface{}) error {
|
||||||
var opts []func(*os.Process) error
|
var opts []func(*os.Process) error
|
||||||
|
|
||||||
if e, ok := m["process-opts"]; ok {
|
if e, ok := m["process-opts"]; ok {
|
||||||
opts, ok = e.([]func(*os.Process) error)
|
opts, ok = e.([]func(*os.Process) error)
|
||||||
if !ok {
|
if !ok {
|
||||||
return ErrInvalidProcessOpts
|
return ErrInvalidProcessOpts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m["process-opts"] = append(opts, o)
|
m["process-opts"] = append(opts, o)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LookChromeNames looks for the platform's DefaultChromeNames and any
|
||||||
|
// additional names using exec.LookPath, returning the first encountered
|
||||||
|
// location or the platform's DefaultChromePath if no names are found on the
|
||||||
|
// path.
|
||||||
|
func LookChromeNames(additional ...string) string {
|
||||||
|
for _, p := range append(additional, DefaultChromeNames...) {
|
||||||
|
path, err := exec.LookPath(p)
|
||||||
|
if err == nil {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefaultChromePath
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user