Skip to content
Snippets Groups Projects
Commit 645dceb0 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets
Browse files

Run plugins as separate process and pass data via STDIN

parent eff5746b
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -66,4 +66,4 @@ eslint-report.html
/locale/**/LC_MESSAGES
/locale/**/*.time_stamp
/.rspec
/plugins/*
/plugins/enabled/*
Loading
Loading
@@ -28,7 +28,6 @@ module Gitlab
config.eager_load_paths.push(*%W[#{config.root}/lib
#{config.root}/app/models/hooks
#{config.root}/app/models/members
#{config.root}/plugins
#{config.root}/app/models/project_services
#{config.root}/app/workers/concerns
#{config.root}/app/services/concerns
Loading
Loading
# Requirements
# * File name must end with _s.rb. For example, jenkins_plugin.rb.
# * All code should be inside class. No code should be executed on file load.
# * Class name must be same as file name.
# If file name is jenkins_plugin.rb then class name must be JenkinsPlugin.
#
# Reccomendations
# * Code should not depend on or use GitLab classes and other code.
# * Consider contributing your plugin to GitLab source code so we can test it
# and make sure it will work in further version.
#
class $NAMEPlugin
def execute(data)
# TODO: Implement me
end
end
module Gitlab
module Plugin
def self.files
Dir.glob(Rails.root.join('plugins', '*_plugin.rb'))
Dir.glob(Rails.root.join('plugins/enabled/*'))
end
 
def self.execute_all_async(data)
files.each do |file|
puts file
PluginWorker.perform_async(file, data)
end
end
 
def self.execute(file, data)
# TODO: Implement
#
# Reuse some code from gitlab-shell https://gitlab.com/gitlab-org/gitlab-shell/blob/master/lib/gitlab_custom_hook.rb#L40
# Pass data as STDIN (or JSON encode?)
#
# 1. Return true if 0 exit code
# 2. Return false if non-zero exit code
# Prepare the hook subprocess. Attach a pipe to its stdin, and merge
# both its stdout and stderr into our own stdout.
stdin_reader, stdin_writer = IO.pipe
hook_pid = spawn({}, file, in: stdin_reader, err: :out)
stdin_reader.close
# Submit changes to the hook via its stdin.
begin
IO.copy_stream(StringIO.new(data.to_json), stdin_writer)
rescue Errno::EPIPE
# It is not an error if the hook does not consume all of its input.
end
# Close the pipe to let the hook know there is no further input.
stdin_writer.close
Process.wait(hook_pid)
$?.success?
end
end
end
namespace :plugins do
desc 'Generate skeleton for new plugin'
task generate: :environment do
ARGV.each { |a| task a.to_sym { } }
name = ARGV[1]
unless name.present?
puts 'Error. You need to specify a name for the plugin'
exit 1
end
class_name = name.classify
param = name.underscore
file_path = Rails.root.join('plugins', param + '_plugin.rb')
template = File.read(Rails.root.join('generator_templates', 'plugins', 'template.rb'))
template.gsub!('$NAME', class_name)
if File.write(file_path, template)
puts "Done. Your plugin saved under #{file_path}."
puts 'Feel free to edit it.'
else
puts "Failed to save #{file_path}."
end
end
desc 'Validate existing plugins'
task validate: :environment do
puts 'Validating plugins from /plugins directory'
Loading
Loading
#!/usr/bin/env clojure
(let [in (slurp *in*)]
(spit "/tmp/clj-data.txt" in))
#!/usr/bin/env ruby
x = STDIN.read
File.write('/tmp/rb-data.txt', x)
File moved
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment