Skip to content
代码片段 群组 项目
提交 12edac18 编辑于 作者: Gabriel Mazetto's avatar Gabriel Mazetto
浏览文件

Add Shell::Command abstraction to Gitlab::Backup::Cli

The new class will be responsible for all shell/commands execution
上级 6f5aed4c
No related branches found
No related tags found
无相关合并请求
......@@ -8,6 +8,7 @@ module Cli
autoload :Runner, 'gitlab/backup/cli/runner'
autoload :Utils, 'gitlab/backup/cli/utils'
autoload :Dependencies, 'gitlab/backup/cli/dependencies'
autoload :Shell, 'gitlab/backup/cli/shell'
Error = Class.new(StandardError)
# Your code goes here...
......
# frozen_string_literal: true
require 'open3'
module Gitlab
module Backup
module Cli
module Shell
autoload :Command, 'gitlab/backup/cli/shell/command'
end
end
end
end
# frozen_string_literal: true
module Gitlab
module Backup
module Cli
module Shell
# Abstraction to control shell command execution
# It provides an easier API to common usages
class Command
attr_reader :cmd_args, :env
# Result data structure from running a command
#
# @attr [String] stdout
# @attr [String] stderr
# @attr [Process::Status] status
# @attr [Float] duration
Result = Struct.new(:stdout, :stderr, :status, :duration, keyword_init: true)
# @example Usage
# Shell.new('echo', 'Some amazing output').capture
# @param [Array<String>] cmd_args
# @param [Hash<String,String>] env
def initialize(*cmd_args, env: {})
@cmd_args = cmd_args
@env = env
end
# Execute a process and return its output and status
#
# @return [Command::Result] Captured output from executing a process
def capture
start = Time.now
stdout, stderr, status = Open3.capture3(env, *cmd_args)
duration = Time.now - start
Result.new(stdout: stdout, stderr: stderr, status: status, duration: duration)
end
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Backup::Cli::Shell::Command do
let(:envdata) do
{ 'CUSTOM' => 'data' }
end
subject(:command) { described_class }
describe '#initialize' do
it 'accepts required attributes' do
expect { command.new('ls', '-l') }.not_to raise_exception
end
it 'accepts optional attributes' do
expect { command.new('ls', '-l', env: envdata) }.not_to raise_exception
end
end
describe '#capture' do
it 'returns stdout from executed command' do
expected_output = 'my custom content'
result = command.new('echo', expected_output).capture
expect(result.stdout.chomp).to eq(expected_output)
expect(result.stderr).to be_empty
end
it 'returns stderr from executed command' do
expected_output = 'my custom error content'
result = command.new('sh', '-c', "echo #{expected_output} > /dev/stderr").capture
expect(result.stdout).to be_empty
expect(result.stderr.chomp).to eq(expected_output)
end
it 'returns a Process::Status from the executed command' do
result = command.new('pwd').capture
expect(result.status).to be_a(Process::Status)
expect(result.status).to respond_to(:exited?, :termsig, :stopsig, :exitstatus, :success?, :pid)
end
it 'returns the execution duration' do
result = command.new('sleep 0.1').capture
expect(result.duration).to be > 0.1
end
end
end
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册