-
Notifications
You must be signed in to change notification settings - Fork 202
class ShopifyCli::Context
Context captures a lot about the current running command. It captures the environment, output, system and file operations. It is useful to have the context especially in tests so that you have a single access point to these resoures.
- Constants
- Attributes
- Class Methods
-
Instance Methods
- os
- mac?
- linux?
- windows?
- unknown_os?
- tty?
- system?
- development?
- testing?
- ci?
- debug?
- getenv
- setenv
- write
- read
- binread
- binwrite
- chdir
- dir_exist?
- file_exist?
- cp_r
- cp
- rename
- rm
- rm_r
- rm_rf
- mkdir_p
- open_url!
- open_browser_url!
- print_task
- puts
- warn
- done
- abort
- debug
- message
- uname
- system
- capture2
- capture2e
- capture3
- on_siginfo
- which
- new_version
- executable_file_extension
GEM_LATEST_URI
VERSION_CHECK_SECTION
LAST_CHECKED_AT_FIELD
VERSION_CHECK_INTERVAL
-
messages
-
root
is the directory root that the current command is running in. If you want to simulate acd
for the file operations, you can change this variable. -
env
is an accessor for environment variables. These variables are also added to any command run by the context.
load_messages(messages)
adds a new set of messages to be used by the CLI. The messages are expected to
be a hash of symbols, and multiple levels are allowed. When fetching messages
a dot notation is used to separate different levels. See Context::message for
more information.
-
messages
- Hash containing the new keys to register
see source
# File lib/shopify-cli/context.rb, line 30
def load_messages(messages)
@messages ||= {}
@messages = @messages.merge(messages) do |key|
Context.new.abort("Message key '#{key}' already exists and cannot be registered") if @messages.key?(key)
end
end
message(key, *params)
returns the user-facing messages for the given key. Returns the key if no
message is available.
-
key
- a symbol representing the message -
params
- the parameters to format the string with
see source
# File lib/shopify-cli/context.rb, line 42
def message(key, *params)
key_parts = key.split(".").map(&:to_sym)
str = Context.messages.dig(*key_parts)
str ? str % params : key
end
os()
will return which operating system that the cli is running on [:mac, :linux]
see source
# File lib/shopify-cli/context.rb, line 62
def os
host = uname
return :mac if /darwin/i.match(host)
return :windows if /mswin|mingw|cygwin/i.match(host)
return :linux if /linux|bsd/i.match(host)
:unknown
end
mac?()
will return true if the cli is running on an apple computer.
see source
# File lib/shopify-cli/context.rb, line 71
def mac?
os == :mac
end
linux?()
will return true if the cli is running on a linux distro
see source
# File lib/shopify-cli/context.rb, line 76
def linux?
os == :linux
end
windows?()
will return true if the cli is running on Windows
see source
# File lib/shopify-cli/context.rb, line 81
def windows?
os == :windows
end
unknown_os?()
will return true if the os is unknown
see source
# File lib/shopify-cli/context.rb, line 86
def unknown_os?
os == :unknown
end
tty?()
will return true if being launched from a tty
see source
# File lib/shopify-cli/context.rb, line 91
def tty?
$stdin.tty? && !testing?
end
system?()
will return true if the cli is being run from an installation, and not a
development instance. The gem installation will not have a 'test' directory.
See #development?
for checking for development environment.
see source
# File lib/shopify-cli/context.rb, line 99
def system?
!Dir.exist?(File.join(ShopifyCli::ROOT, "test"))
end
development?()
will return true if the cli is running on your development instance.
see source
# File lib/shopify-cli/context.rb, line 105
def development?
!system? && !testing?
end
testing?()
will return true while tests are running, either locally or on CI
see source
# File lib/shopify-cli/context.rb, line 110
def testing?
ci? || ENV["TEST"]
end
ci?()
will return true if the cli is being tested on CI
see source
# File lib/shopify-cli/context.rb, line 116
def ci?
ENV["CI"]
end
debug?()
will return true if the cli is running with the DEBUG flag
see source
# File lib/shopify-cli/context.rb, line 122
def debug?
getenv("DEBUG")
end
getenv(name)
get a environment variable value by name.
-
name
- the name of the environment variable that you want to fetch
-
value
- will return the value, or nil if the variable does not exist
see source
# File lib/shopify-cli/context.rb, line 134
def getenv(name)
v = @env[name]
v == "" ? nil : v
end
setenv(key, value)
set a environment variable value by name.
-
key
- the name of the environment variable that you want to set -
value
- the value of the variable
see source
# File lib/shopify-cli/context.rb, line 145
def setenv(key, value)
@env[key] = value
end
write(fname, content)
will write/overwrite a file with the provided contents, relative to the
context root unless the file path is absolute.
-
fname
- filename of the file that you are writing, relative to root unless it is absolute. -
content
- the body contents of the file that you are writing
@ctx.write('new.txt', 'hello world')
see source
# File lib/shopify-cli/context.rb, line 160
def write(fname, content)
File.write(ctx_path(fname), content)
end
read(fname)
will read a file relative to the context root unless the file path is
absolute.
-
fname
- filename of the file that you are reading, relative to root unless it is absolute.
@ctx.read('file.txt')
see source
# File lib/shopify-cli/context.rb, line 173
def read(fname)
File.read(ctx_path(fname))
end
binread(fname)
will read a binary file relative to the context root unless the file path is
absolute.
-
fname
- filename of the file that you are reading, relative to root unless it is absolute.
@ctx.read('binary.out')
see source
# File lib/shopify-cli/context.rb, line 186
def binread(fname)
File.binread(ctx_path(fname))
end
binwrite(fname, content)
will write/overwrite a binary file with the provided contents, relative to the
context root unless the file path is absolute.
-
fname
- filename of the file that you are writing, relative to root unless it is absolute. -
content
- the body contents of the file that you are writing
@ctx.binwrite('binary.out', 'ASCII-8BIT encoded binary')
see source
# File lib/shopify-cli/context.rb, line 201
def binwrite(fname, content)
File.binwrite(ctx_path(fname), content)
end
chdir(path)
will change directories and update the root, the filepath is relative to the
command root unless absolute
-
path
- the file path to a directory, relative to the context root to remove from the FS
see source
# File lib/shopify-cli/context.rb, line 210
def chdir(path)
Dir.chdir(ctx_path(path))
self.root = ctx_path(path)
end
dir_exist?(path)
checks if a directory exists, the filepath is relative to the command root
unless absolute
-
path
- the file path to a directory, relative to the context root to remove from the FS
see source
# File lib/shopify-cli/context.rb, line 220
def dir_exist?(path)
Dir.exist?(ctx_path(path))
end
file_exist?(path)
checks if a file exists, the filepath is relative to the command root unless
absolute
-
path
- the file path to a file, relative to the context root to remove from the FS
see source
# File lib/shopify-cli/context.rb, line 229
def file_exist?(path)
File.exist?(ctx_path(path))
end
cp_r(from, to)
will recursively copy a directory from the FS, the filepath is relative to the
command root unless absolute
-
from
- the path of the original file -
to
- the destination path
see source
# File lib/shopify-cli/context.rb, line 240
def cp_r(from, to)
FileUtils.cp_r(ctx_path(from), ctx_path(to))
end
cp(from, to)
will copy a directory from the FS, the filepath is relative to the command
root unless absolute
-
from
- the path of the original file -
to
- the destination path
see source
# File lib/shopify-cli/context.rb, line 251
def cp(from, to)
FileUtils.cp(ctx_path(from), ctx_path(to))
end
rename(from, to)
will rename a file from one place to another, relative to the command root
unless the path is absolute.
-
from
- the path of the original file -
to
- the destination path
see source
# File lib/shopify-cli/context.rb, line 262
def rename(from, to)
File.rename(ctx_path(from), ctx_path(to))
end
rm(fname)
will remove a plain file from the FS, the filepath is relative to the command
root unless absolute.
-
fname
- the file path relative to the context root to remove from the FS
see source
# File lib/shopify-cli/context.rb, line 272
def rm(fname)
FileUtils.rm(ctx_path(fname))
end
rm_r(fname)
will remove a directory from the FS, the filepath is relative to the command
root unless absolute
-
fname
- the file path to a directory, relative to the context root to remove from the FS
see source
# File lib/shopify-cli/context.rb, line 282
def rm_r(fname)
FileUtils.rm_r(ctx_path(fname))
end
rm_rf(fname)
will force remove a directory from the FS, the filepath is relative to the
command root unless absolute
-
fname
- the file path to a directory, relative to the context root to remove from the FS
see source
# File lib/shopify-cli/context.rb, line 292
def rm_rf(fname)
FileUtils.rm_rf(ctx_path(fname))
end
mkdir_p(path)
will create a directory, recursively if it does not exist. So if you create a
directory foo/bar/dun
, this will also create the directories foo
and
foo/bar
if they do not exist. The path will be made relative to the command
root unless absolute
-
path
- file path of the directory that you want to create
see source
# File lib/shopify-cli/context.rb, line 304
def mkdir_p(path)
FileUtils.mkdir_p(path)
end
open_url!(uri)
will output to the console a link for the user to either copy/paste or click
on.
-
uri
- a http URI to open in a browser
see source
# File lib/shopify-cli/context.rb, line 314
def open_url!(uri)
help = message("core.context.open_url", uri)
puts(help)
end
open_browser_url!(uri)
will output to the console a link for the user to either copy/paste or click
on.
-
uri
- a http URI to open in a browser
see source
# File lib/shopify-cli/context.rb, line 325
def open_browser_url!(uri)
if tty?
if linux? && which("xdg-open")
system("xdg-open", uri.to_s)
elsif windows?
system("start", uri.to_s)
elsif mac?
system("open", uri.to_s)
else
open_url!(uri)
end
else
open_url!(uri)
end
end
print_task(text)
will output a message, prefixed by a yellow star, indicating that task
started.
-
text
- a string message to output
see source
# File lib/shopify-cli/context.rb, line 347
def print_task(text)
puts "{{yellow:*}} #{text}"
end
puts(*args)
a wrapper around Kernel.puts to allow for easy formatting
-
text
- a string message to output
see source
# File lib/shopify-cli/context.rb, line 356
def puts(*args)
Kernel.puts(CLI::UI.fmt(*args))
end
warn(*args)
a wrapper around Kernel.warn to allow for easy formatting
-
text
- a string message to output
see source
# File lib/shopify-cli/context.rb, line 365
def warn(*args)
Kernel.warn(CLI::UI.fmt(*args))
end
done(text)
outputs a message, prefixed by a checkmark indicating that something completed
-
text
- a string message to output
see source
# File lib/shopify-cli/context.rb, line 374
def done(text)
puts("{{v}} #{text}")
end
abort(text)
aborts the current running command and outputs an error message, prefixed by a
red x
-
text
- a string message to output
see source
# File lib/shopify-cli/context.rb, line 384
def abort(text)
raise ShopifyCli::Abort, "{{x}} #{text}"
end
debug(text)
outputs a message, prefixed by a red DEBUG
tag. This will only output to the
console if you have DEBUG=1
set in your shell environment.
-
text
- a string message to output
see source
# File lib/shopify-cli/context.rb, line 394
def debug(text)
puts("{{red:DEBUG}} #{text}") if debug?
end
message(key, *params)
proxy call to Context.message.
-
key
- a symbol representing the message -
params
- the parameters to format the string with
see source
# File lib/shopify-cli/context.rb, line 403
def message(key, *params)
Context.message(key, *params)
end
uname()
will grab the host info of the computer running the cli. This indicates the
computer architecture and operating system
see source
# File lib/shopify-cli/context.rb, line 409
def uname
@uname ||= RbConfig::CONFIG["host"]
end
system(*args, **kwargs)
Execute a command in the user's environment Outputs result of the command
without capturing it
-
*args
: A splat of arguments evaluated as a command. (e.g.'rm', folder
is equivalent torm #{folder}
) -
**kwargs
: additional keyword arguments to pass to Process.spawn
-
status
: TheProcess::Status
result of the command execution.
stat = @ctx.system('ls', 'a_folder')
see source
# File lib/shopify-cli/context.rb, line 427
def system(*args, **kwargs)
process_status = CLI::Kit::System.system(*args, env: @env, **kwargs)
unless process_status.success?
abort("System call failed: #{args.join(" ")}")
end
process_status
end
capture2(*args, **kwargs)
Execute a command in the user's environment This is meant to be largely
equivalent to backticks, only with the env passed in. Captures the results of
the command without output to the console
-
*args
: A splat of arguments evaluated as a command. (e.g.'rm', folder
is equivalent torm #{folder}
) -
**kwargs
: additional arguments to pass to Open3.capture2
-
output
: output (STDOUT) of the command execution -
status
: boolean success status of the command execution
out, stat = @ctx.capture2('ls', 'a_folder')
see source
# File lib/shopify-cli/context.rb, line 451
def capture2(*args, **kwargs)
CLI::Kit::System.capture2(*args, env: @env, **kwargs)
end
capture2e(*args, **kwargs)
Execute a command in the user's environment This is meant to be largely
equivalent to backticks, only with the env passed in. Captures the results of
the command without output to the console
-
*args
: A splat of arguments evaluated as a command. (e.g.'rm', folder
is equivalent torm #{folder}
) -
**kwargs
: additional arguments to pass to Open3.capture2e
-
output
: output (STDOUT merged with STDERR) of the command execution -
status
: boolean success status of the command execution
out_and_err, stat = @ctx.capture2e('ls', 'a_folder')
see source
# File lib/shopify-cli/context.rb, line 471
def capture2e(*args, **kwargs)
CLI::Kit::System.capture2e(*args, env: @env, **kwargs)
end
capture3(*args, **kwargs)
Execute a command in the user's environment This is meant to be largely
equivalent to backticks, only with the env passed in. Captures the results of
the command without output to the console
-
*args
: A splat of arguments evaluated as a command. (e.g.'rm', folder
is equivalent torm #{folder}
) -
**kwargs
: additional arguments to pass to Open3.capture3
-
output
: STDOUT of the command execution -
error
: STDERR of the command execution -
status
: boolean success status of the command execution
out, err, stat = @ctx.capture3('ls', 'a_folder')
see source
# File lib/shopify-cli/context.rb, line 492
def capture3(*args, **kwargs)
CLI::Kit::System.capture3(*args, env: @env, **kwargs)
end
on_siginfo() { || ... }
captures the info signal (ctrl-T) and provide a handler to it.
@ctx.on_siginfo do
@ctx.open_url!("http://google.com")
end
see source
# File lib/shopify-cli/context.rb, line 504
def on_siginfo
# Reset any previous SIGINFO handling we had so the only action we take is the given block
trap("INFO", "DEFAULT")
fork do
begin
r, w = IO.pipe
@signal = false
trap("SIGINFO") do
@signal = true
w.write(0)
end
while r.read(1)
next unless @signal
@signal = false
yield
end
rescue Interrupt
exit(0)
end
end
end
which(cmd)
Checks if the given command exists in the system
-
cmd
: The command to test
@todo This is currently a duplicate of CLI::Kit::System.which() - we should make that method public when we make Kit changes and make this a wrapper instead.
see source
# File lib/shopify-cli/context.rb, line 537
def which(cmd)
exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : [""]
ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
exts.each do |ext|
exe = File.join(File.expand_path(path), "#{cmd}#{ext}")
return exe if File.executable?(exe) && !File.directory?(exe)
end
end
nil
end
new_version()
Checks if there's a newer version of the CLI available and returns version
string if this should be conveyed to the user (i.e., if it's been over 24
hours since last check)
-
version
: string of newer version available, IFF new version is available AND it's time to inform user, : nil otherwise
see source
# File lib/shopify-cli/context.rb, line 558
def new_version
if (time_of_last_check + VERSION_CHECK_INTERVAL) < (now = Time.now.to_i)
update_time_of_last_check(now)
latest_version = retrieve_latest_gem_version
latest_version unless latest_version == ShopifyCli::VERSION
end
end
executable_file_extension(ext = ".exe")
Returns file extension depending on OS since windows has multiple extensions,
the default is .exe unless otherwise specified
- ext: optional extension for windows file
- ext: string for file extension on windows : empty string otherwise
see source
# File lib/shopify-cli/context.rb, line 575
def executable_file_extension(ext = ".exe")
if windows?
ext
else
""
end
end