miniexec 0.0.6 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/bin/miniexec +5 -6
  3. data/lib/miniexec.rb +112 -101
  4. data/lib/util.rb +19 -0
  5. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e5abfbd093e75a0bb48a481b1ce13cddaf849680faf63f02839d151847daf25
4
- data.tar.gz: c759f6ec46d9bbe5812988cdd76706afb2aca6d9d7d7064294f848814ae26bb6
3
+ metadata.gz: 23d8470c6289646978702f3c917e7a8d6e98df6aef7b2a6d8c810eecbaf9e797
4
+ data.tar.gz: bb5725ff2ff691bce7c0a2aa55860889efcd8300bb39add2347415ef4dff516c
5
5
  SHA512:
6
- metadata.gz: a8d3604262b29677b356b0ddaffb581b3527183ce084bed754f286bff5c4cf3e9b980af47048796975cb040b974adb77c58f21ffa1fb54b9cf13bedde15f50f7
7
- data.tar.gz: cd413fee962e6795592637a8c2278c6e9d24b9066a448c2b9c20a6b5b1542dce2007fd9960ad85b038edbb7ddb5d472ab4654104d3314fed66764d9dcaa15740
6
+ metadata.gz: cc22648aa2042168eab09e192e89ad140ae188f20da8250e5817da3218019a580d5b7140320720bd212fbc44d2323c6f41aa1e722d7eb8973be877b6a5727c10
7
+ data.tar.gz: 6a4365689aa47b7be9272d8f6297c939159df7de03862965aa39e2b10c6fa07860d951b208c10b938cfa9b6c2d9b7a5b0660ff46859e732e565cfaa179b9cfea
data/bin/miniexec CHANGED
@@ -5,7 +5,6 @@ lib = File.expand_path('../lib', __dir__)
5
5
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
6
  require 'miniexec'
7
7
  require 'optparse'
8
- require 'pry'
9
8
 
10
9
  options = {
11
10
  binds: [],
@@ -45,9 +44,9 @@ end.parse!
45
44
 
46
45
  raise OptionParser::MissingArgument, 'Specify a job with -j' if options[:job].nil?
47
46
 
48
- MiniExec.config(project_path: options[:path])
49
- exec = MiniExec.new options[:job],
50
- docker_url: options[:docker],
51
- binds: options[:binds],
52
- env: options[:env]
47
+ MiniExec::MiniExec.config(project_path: options[:path])
48
+ exec = MiniExec::MiniExec.new options[:job],
49
+ docker_url: options[:docker],
50
+ binds: options[:binds],
51
+ env: options[:env]
53
52
  exec.run_job
data/lib/miniexec.rb CHANGED
@@ -1,121 +1,132 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Main class
4
- class MiniExec
5
- require 'logger'
6
- require 'docker-api'
7
- require 'json'
8
- require 'tempfile'
9
- require 'yaml'
10
- require 'git'
11
- # Class instance variables
12
- @project_path = '.'
13
- @workflow_file = '.gitlab-ci.yml'
4
+ module MiniExec
5
+ class MiniExec
6
+ require 'logger'
7
+ require 'docker-api'
8
+ require 'json'
9
+ require 'tempfile'
10
+ require 'yaml'
11
+ require 'git'
12
+ require_relative './util'
13
+ # Class instance variables
14
+ @project_path = '.'
15
+ @workflow_file = '.gitlab-ci.yml'
14
16
 
15
- class << self
16
- attr_accessor :project_path, :workflow_file
17
- end
17
+ class << self
18
+ attr_accessor :project_path, :workflow_file
19
+ end
18
20
 
19
- def self.config(project_path: @project_path, workflow_file: @workflow_file)
20
- @project_path = project_path
21
- @workflow_file = workflow_file
22
- self
23
- end
21
+ def self.config(project_path: @project_path, workflow_file: @workflow_file)
22
+ @project_path = project_path
23
+ @workflow_file = workflow_file
24
+ self
25
+ end
24
26
 
25
- attr_accessor :script
27
+ attr_accessor :script
26
28
 
27
- def initialize(job,
28
- project_path: self.class.project_path,
29
- docker_url: nil,
30
- binds: [],
31
- env: {})
32
- @job_name = job
33
- @project_path = project_path
34
- @workflow = YAML.load(File.read("#{@project_path}/#{MiniExec.workflow_file}"))
35
- @job = @workflow[job]
36
- @job['name'] = job
37
- @default_image = @workflow['image'] || 'debian:buster-slim'
38
- @image = set_job_image
39
- @script = compile_script
40
- @binds = binds
41
- @env = env.merge gitlab_env, variables
42
- configure_logger
43
- Docker.options[:read_timeout] = 6000
44
- Docker.url = docker_url if docker_url
45
- end
29
+ def initialize(job,
30
+ project_path: self.class.project_path,
31
+ docker_url: nil,
32
+ binds: [],
33
+ env: {})
34
+ @job_name = job
35
+ @project_path = project_path
36
+ @workflow = YAML.load(File.read("#{@project_path}/#{MiniExec.workflow_file}"))
37
+ @job = @workflow[job]
38
+ @job['name'] = job
39
+ @default_image = @workflow['image'] || 'debian:buster-slim'
40
+ @image = set_job_image
41
+ @binds = binds
42
+ @env = {}
43
+ [
44
+ env,
45
+ gitlab_env,
46
+ @workflow['variables'],
47
+ @job['variables']
48
+ ].each do |var_set|
49
+ @env.merge!(var_set.transform_values { |v| Util.expand_var(v.to_s, @env) }) if var_set
50
+ end
51
+ @script = compile_script
52
+ configure_logger
53
+ Docker.options[:read_timeout] = 6000
54
+ Docker.url = docker_url if docker_url
55
+ end
46
56
 
47
- def run_job
48
- script_path = "/tmp/#{@job['name']}.sh"
49
- @logger.info "Fetching image #{@image}"
50
- Docker::Image.create(fromImage: @image)
51
- @logger.info 'Image fetched'
52
- Dir.chdir(@project_path) do
53
- @logger.info 'Creating container'
54
- container = Docker::Container.create(
55
- Cmd: ['/bin/bash', script_path],
56
- Image: @image,
57
- Volumes: @binds.map { |b| { b => { path_parent: 'rw' } } }.inject(:merge),
58
- Env: @env.map { |k, v| "#{k}=#{v}" }
59
- )
60
- container.store_file(script_path, @script)
61
- container.start({ Binds: [@binds] })
62
- container.tap(&:start).attach { |_, chunk| puts chunk }
57
+ def run_job
58
+ script_path = "/tmp/#{@job['name']}.sh"
59
+ @logger.info "Fetching image #{@image}"
60
+ Docker::Image.create(fromImage: @image)
61
+ @logger.info 'Image fetched'
62
+ Dir.chdir(@project_path) do
63
+ @logger.info 'Creating container'
64
+ container = Docker::Container.create(
65
+ Cmd: ['/bin/bash', script_path],
66
+ Image: @image,
67
+ Volumes: @binds.map { |b| { b => { path_parent: 'rw' } } }.inject(:merge),
68
+ Env: @env.map { |k, v| "#{k}=#{v}" }
69
+ )
70
+ container.store_file(script_path, @script)
71
+ container.start({ Binds: [@binds] })
72
+ container.tap(&:start).attach { |_, chunk| puts chunk }
73
+ end
63
74
  end
64
- end
65
75
 
66
- private
76
+ private
67
77
 
68
- def set_job_image
69
- return @job['image'] if @job['image']
78
+ def set_job_image
79
+ return @job['image'] if @job['image']
70
80
 
71
- @default_image
72
- end
81
+ @default_image
82
+ end
73
83
 
74
- # Set gitlab's predefined env vars as per
75
- # https://docs.gitlab.com/ee/ci/variables/predefined_variables.html
76
- def gitlab_env
77
- g = Git.open(@project_path)
78
- commit = g.gcommit 'HEAD'
79
- tag = g.tags.find { |t| t.objectish == commit.sha }
80
- commit_branch = g.branch.name
81
- if tag.nil?
82
- ref_name = g.branch.name
83
- commit_tag = nil
84
- else
85
- ref_name = tag.name
86
- commit_tag = ref_name
84
+ # Set gitlab's predefined env vars as per
85
+ # https://docs.gitlab.com/ee/ci/variables/predefined_variables.html
86
+ def gitlab_env
87
+ g = Git.open(@project_path)
88
+ commit = g.gcommit 'HEAD'
89
+ tag = g.tags.find { |t| t.objectish == commit.sha }
90
+ commit_branch = g.branch.name
91
+ if tag.nil?
92
+ ref_name = g.branch.name
93
+ commit_tag = nil
94
+ else
95
+ ref_name = tag.name
96
+ commit_tag = ref_name
97
+ end
98
+ {
99
+ 'CI': true,
100
+ 'CI_COMMIT_REF_SHA': commit.sha,
101
+ 'CI_COMMIT_SHORT_SHA': commit.sha[0, 8],
102
+ 'CI_COMMIT_REF_NAME': ref_name,
103
+ 'CI_COMMIT_BRANCH': commit_branch,
104
+ 'CI_COMMIT_TAG': commit_tag,
105
+ 'CI_COMMIT_MESSAGE': commit.message,
106
+ 'CI_COMMIT_REF_PROTECTED': false,
107
+ 'CI_COMMIT_TIMESTAMP': commit.date.strftime('%FT%T')
108
+ }.transform_keys(&:to_s)
87
109
  end
88
- {
89
- 'CI': true,
90
- 'CI_COMMIT_REF_SHA': commit.sha,
91
- 'CI_COMMIT_SHORT_SHA': commit.sha[0, 8],
92
- 'CI_COMMIT_REF_NAME': ref_name,
93
- 'CI_COMMIT_BRANCH': commit_branch,
94
- 'CI_COMMIT_TAG': commit_tag,
95
- 'CI_COMMIT_MESSAGE': commit.message,
96
- 'CI_COMMIT_REF_PROTECTED': false,
97
- 'CI_COMMIT_TIMESTAMP': commit.date.strftime('%FT%T')
98
- }.transform_keys(&:to_s)
99
- end
100
110
 
101
- def variables
102
- globals = @workflow['variables'] || {}
103
- job_locals = @job['variables'] || {}
104
- globals.merge job_locals
105
- end
111
+ def variables
112
+ globals = @workflow['variables'] || {}
113
+ job_locals = @job['variables'] || {}
114
+ globals.merge job_locals
115
+ end
106
116
 
107
- def configure_logger
108
- @logger = Logger.new($stdout)
109
- @logger.formatter = proc do |severity, _, _, msg|
110
- "[#{severity}]: #{msg}\n"
117
+ def configure_logger
118
+ @logger = Logger.new($stdout)
119
+ @logger.formatter = proc do |severity, _, _, msg|
120
+ "[#{severity}]: #{msg}\n"
121
+ end
122
+ @logger.level = ENV['LOGLEVEL'] || Logger::INFO
111
123
  end
112
- @logger.level = ENV['LOGLEVEL'] || Logger::INFO
113
- end
114
124
 
115
- def compile_script
116
- before_script = @job['before_script'] || ''
117
- script = @job['script'] || ''
118
- after_script = @job['after_script'] || ''
119
- [before_script, script, after_script].flatten.join("\n").strip
125
+ def compile_script
126
+ before_script = @job['before_script'] || ''
127
+ script = @job['script'] || ''
128
+ after_script = @job['after_script'] || ''
129
+ [before_script, script, after_script].flatten.join("\n").strip
130
+ end
120
131
  end
121
132
  end
data/lib/util.rb ADDED
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MiniExec
4
+ module Util
5
+ # Given a string and an env, replace any instance of shell-style variables
6
+ # with their value in the env. NOT POSIX COMPLIANT, just mostly hacky so
7
+ # I can get gitlab-ci.yml parsing to work properly. Required in MiniExec
8
+ # because of https://docs.gitlab.com/ee/ci/variables/where_variables_can_be_used.html#gitlab-internal-variable-expansion-mechanism
9
+ def self.expand_var(string, env)
10
+ # Match group 1 = the text to replace
11
+ # Match group 2 = the key from env we want to replace it with
12
+ regex = /(\${?(\w+)}?)/
13
+ string.scan(regex).uniq.each do |match|
14
+ string.gsub! match[0], env[match[1]].to_s
15
+ end
16
+ string
17
+ end
18
+ end
19
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: miniexec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Pugh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-07 00:00:00.000000000 Z
11
+ date: 2021-05-04 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A minimal interpretor/executor for .gitlab-ci.yml
14
14
  email: pugh@s3kr.it
@@ -19,6 +19,7 @@ extra_rdoc_files: []
19
19
  files:
20
20
  - bin/miniexec
21
21
  - lib/miniexec.rb
22
+ - lib/util.rb
22
23
  homepage: https://github.com/s3krit/miniexec
23
24
  licenses:
24
25
  - AGPL-3.0-or-later