gitall 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/gitall +58 -0
- data/lib/cli/app.rb +0 -0
- data/lib/gitall/gitall.rb +200 -0
- data/lib/gitall/logger.rb +21 -0
- data/lib/gitall/parsers/bitbucket.rb +13 -0
- data/lib/gitall/parsers/github.rb +191 -0
- data/lib/gitall/parsers/gitlab.rb +103 -0
- data/lib/gitall/plugins/admin.rb +78 -0
- data/lib/gitall/plugins/chancontrol.rb +127 -0
- data/lib/gitall/plugins/eval.rb +17 -0
- data/lib/gitall/plugins/git.rb +28 -0
- data/lib/gitall/version.rb +3 -0
- data/lib/views/_403.erb +1 -0
- metadata +224 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 023bf7ff2db1c44f15f8f8f66d02356ee0d5d88c53a4e4b1b78a374873041e7a
|
|
4
|
+
data.tar.gz: c0f0f44647496761ff884cb2380ea5891d27ad41ee9f8c5c3bcfab55e6912ff4
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: f385058ddb774533779b5efb63a53ca3ca46094575fabf15ca43444d7a8fa93806c481059bd394a5eeb61eadbde2947396a3e54e2aa6906d5156e612a4ce9c87
|
|
7
|
+
data.tar.gz: d3a6e33ff86b316dc41042f809731624a5777c537a2dd22d28b6252d2cb39f6ccd6095aaf2f965e02bfd465142debc4ed88bf255fd9f1291a6140d9b0e47d8e6
|
data/bin/gitall
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require './bot_version.rb'
|
|
4
|
+
require 'sinatra/base'
|
|
5
|
+
require 'json'
|
|
6
|
+
require 'cinch'
|
|
7
|
+
require 'cinch/plugins/basic_ctcp'
|
|
8
|
+
require 'cinch/plugins/identify'
|
|
9
|
+
require 'ostruct'
|
|
10
|
+
require 'recursive-open-struct'
|
|
11
|
+
require 'yaml'
|
|
12
|
+
require 'unirest'
|
|
13
|
+
require 'base64'
|
|
14
|
+
require 'active_support/all'
|
|
15
|
+
Thread.abort_on_exception = true
|
|
16
|
+
|
|
17
|
+
# @note Load the plugins
|
|
18
|
+
require 'gitallchancontrol.rb'
|
|
19
|
+
require './lib/admin.rb'
|
|
20
|
+
require './lib/logger.rb'
|
|
21
|
+
require './lib/eval.rb'
|
|
22
|
+
|
|
23
|
+
# @note Load the parsers
|
|
24
|
+
require 'gitall/parsers/gitlab'
|
|
25
|
+
require 'gitall/parsers/github.rb'
|
|
26
|
+
|
|
27
|
+
# Cinch
|
|
28
|
+
|
|
29
|
+
$cfg = YAML.load_file(`echo ~/.gitall-rc.yml`.chomp!)
|
|
30
|
+
$bots = Hash.new
|
|
31
|
+
$threads = Array.new
|
|
32
|
+
|
|
33
|
+
# For the sake of this example, we'll create an ORM-like model and give it an
|
|
34
|
+
# authenticate method, that checks if a given password matches.
|
|
35
|
+
class User < Struct.new :nickname, :password, :type
|
|
36
|
+
def authenticate(pass)
|
|
37
|
+
password == pass
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Simulate a database.
|
|
42
|
+
$users = []
|
|
43
|
+
@users = YAML.load_file(`echo ~/.gitall-rc.yml`.chomp!)['users']
|
|
44
|
+
@users.each do |user, hash|
|
|
45
|
+
password = hash['password']
|
|
46
|
+
role = hash['role']
|
|
47
|
+
$users << User.new(user, password, role)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
$bots.each do |key, bot|
|
|
52
|
+
puts "Starting IRC connection for #{key}..."
|
|
53
|
+
$threads << Thread.new { bot.start }
|
|
54
|
+
end
|
|
55
|
+
$threads << Thread.new {
|
|
56
|
+
WebHook.run! if __FILE__ == $PROGRAM_NAME
|
|
57
|
+
}
|
|
58
|
+
$threads.each(&:join)
|
data/lib/cli/app.rb
ADDED
|
File without changes
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
require 'recursive_open_struct'
|
|
2
|
+
require 'json'
|
|
3
|
+
|
|
4
|
+
require 'parsers/github'
|
|
5
|
+
require 'parsers/gitlab'
|
|
6
|
+
|
|
7
|
+
require 'plugins/admin'
|
|
8
|
+
require 'plugins/chancontrol'
|
|
9
|
+
require 'plugins/git'
|
|
10
|
+
require 'plugins/eval'
|
|
11
|
+
|
|
12
|
+
module GitAll
|
|
13
|
+
CFG = File.open(Pathname(Dir.home).join('gitall-rc.yml'), 'r').read
|
|
14
|
+
USERS = CFG['users']
|
|
15
|
+
PROJECTS = CFG['projects']
|
|
16
|
+
# Houses all the gitall bots and their data
|
|
17
|
+
|
|
18
|
+
class Users
|
|
19
|
+
attr :users
|
|
20
|
+
@users = []
|
|
21
|
+
|
|
22
|
+
class User < Struct.new :nickname, :password, :type
|
|
23
|
+
def authenticate(pass)
|
|
24
|
+
password == pass
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
USERS.each do |user, hash|
|
|
29
|
+
password = hash['password']
|
|
30
|
+
role = hash['role']
|
|
31
|
+
@users << User.new(user, password, role)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
class Bots
|
|
35
|
+
attr :bots, :config
|
|
36
|
+
|
|
37
|
+
@bots = {}
|
|
38
|
+
@config = GitAll::CFG
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def add_bots
|
|
43
|
+
@config['networks'].each do |name, ncfg|
|
|
44
|
+
bot = Cinch::Bot.new do
|
|
45
|
+
configure do |c|
|
|
46
|
+
c.server = ncfg.fetch('server')
|
|
47
|
+
c.port = ncfg.fetch('port')
|
|
48
|
+
c.nick = ncfg.fetch('nickname')
|
|
49
|
+
c.user = ncfg.fetch('username')
|
|
50
|
+
c.realname = ncfg.fetch('realname')
|
|
51
|
+
c.plugins.prefix = Regexp.new(ncfg.fetch('prefix'))
|
|
52
|
+
c.plugins.plugins << Cinch::Plugins::Identify
|
|
53
|
+
identify_with = ncfg.fetch('identify-with')
|
|
54
|
+
case identify_with
|
|
55
|
+
when 'nickserv'
|
|
56
|
+
begin
|
|
57
|
+
c.plugins.options[Cinch::Plugins::Identify] = {
|
|
58
|
+
:username => ncfg.fetch('sasl-username'),
|
|
59
|
+
:password => ncfg.fetch('sasl-password'),
|
|
60
|
+
:type => :nickserv,
|
|
61
|
+
}
|
|
62
|
+
rescue KeyError
|
|
63
|
+
# ignored
|
|
64
|
+
end
|
|
65
|
+
when 'sasl'
|
|
66
|
+
begin
|
|
67
|
+
c.sasl.username = ncfg.fetch('sasl-username')
|
|
68
|
+
c.sasl.password = ncfg.fetch('sasl-password')
|
|
69
|
+
rescue KeyError
|
|
70
|
+
# ignored
|
|
71
|
+
end
|
|
72
|
+
when 'cert'
|
|
73
|
+
begin
|
|
74
|
+
c.ssl.client_cert = ncfg.fetch('certfp')
|
|
75
|
+
rescue KeyError
|
|
76
|
+
# ignored
|
|
77
|
+
end
|
|
78
|
+
when 'none'
|
|
79
|
+
# Don't identify
|
|
80
|
+
else
|
|
81
|
+
# noop
|
|
82
|
+
end
|
|
83
|
+
c.channels = ncfg.fetch('channels')
|
|
84
|
+
c.ssl.use = ncfg.fetch('ssl')
|
|
85
|
+
c.ssl.verify = ncfg.fetch('sslverify')
|
|
86
|
+
c.messages_per_second = ncfg.fetch('mps')
|
|
87
|
+
# Global configuration. This means that all plugins / matchers that
|
|
88
|
+
# implement authentication make use of the :login strategy, with a user
|
|
89
|
+
# level of :users.
|
|
90
|
+
c.authentication = Cinch::Configuration::Authentication.new
|
|
91
|
+
c.authentication.strategy = :login
|
|
92
|
+
c.authentication.level = :users
|
|
93
|
+
# The UserLogin plugin will call this lambda when a user runs !register.
|
|
94
|
+
#c.authentication.registration = lambda { |nickname, password|
|
|
95
|
+
# If you were using an ORM, you'd do something like
|
|
96
|
+
# `User.create(:nickname => nickname, :password => password)` here.
|
|
97
|
+
# return false if Users.users.one? { |user| user.nickname == nickname }
|
|
98
|
+
# Users.users << User.new(nickname, password, 'user')
|
|
99
|
+
#}
|
|
100
|
+
# The UserLogin plugin will call this lambda when a user runs !login. Note:
|
|
101
|
+
# the class it returns must respond to #authenticate with 1 argument (the
|
|
102
|
+
# password the user tries to login with).
|
|
103
|
+
c.authentication.fetch_user = lambda { |nickname|
|
|
104
|
+
# If you were using an ORM, you'd probably do something like
|
|
105
|
+
# `User.first(:nickname => nickname)` here.
|
|
106
|
+
Users.users.find { |user| user.nickname == nickname } }
|
|
107
|
+
# The Authentication mixin will call these lambdas to check if a user is
|
|
108
|
+
# allowed to run a command.
|
|
109
|
+
c.authentication.users = lambda { |user| user.type == 'user' }
|
|
110
|
+
c.authentication.admins = lambda { |user| user.type == 'admin' }
|
|
111
|
+
c.plugins.plugins << Cinch::Plugins::UserLogin
|
|
112
|
+
c.plugins.plugins << Cinch::Plugins::BasicCTCP
|
|
113
|
+
c.plugins.options[Cinch::Plugins::BasicCTCP][:replies] = {
|
|
114
|
+
version: Version::Bot.version,
|
|
115
|
+
source: 'https://gitlab.com/gitall/gitall'
|
|
116
|
+
}
|
|
117
|
+
c.plugins.plugins << ChanControl
|
|
118
|
+
c.plugins.options[ChanControl][:authentication_level] = :admins
|
|
119
|
+
c.plugins.plugins << Admin
|
|
120
|
+
c.plugins.options[Admin][:authentication_level] = :admins
|
|
121
|
+
c.plugins.plugins << Eval
|
|
122
|
+
c.plugins.options[Eval][:authentication_level] = :admins
|
|
123
|
+
c.plugins.plugins << Cinch::Plugins::UserList
|
|
124
|
+
c.plugins.options[Cinch::Plugins::UserList][:authentication_level] = :admins
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
bot.loggers.clear
|
|
128
|
+
bot.loggers << GitLogger.new(name, File.open("log/gitall-#{name}.log", 'a'))
|
|
129
|
+
bot.loggers << GitLogger.new(name, STDOUT)
|
|
130
|
+
bot.loggers.level = :debug
|
|
131
|
+
self.bots[name] = bot
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
class WebHook < Sinatra::Base
|
|
136
|
+
set :port, 8008
|
|
137
|
+
set :bind, '127.0.0.1'
|
|
138
|
+
set :environment, 'production'
|
|
139
|
+
set :threaded, true
|
|
140
|
+
post '/hook/?' do
|
|
141
|
+
request.body.rewind
|
|
142
|
+
payload = request.body.read
|
|
143
|
+
json = JSON.load(payload)
|
|
144
|
+
j = RecursiveOpenStruct.new(json)
|
|
145
|
+
repo = ''
|
|
146
|
+
if request.env.key? 'HTTP_X_GITLAB_TOKEN'
|
|
147
|
+
repo = j.project.path_with_namespace
|
|
148
|
+
resp = GitLabParser.parse json
|
|
149
|
+
phash = PROJECTS[repo]
|
|
150
|
+
if phash['token'] == request.env['HTTP_X_GITLAB_TOKEN']
|
|
151
|
+
channels = phash['channels']
|
|
152
|
+
channels.each do |channet|
|
|
153
|
+
channel = channet.split(',')[0]
|
|
154
|
+
net = channet.split(',')[1]
|
|
155
|
+
resp.each do |n|
|
|
156
|
+
Bots.bots[net].Channel(channel).send("#{n}")
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
elsif request.env.key? 'HTTP_X_HUB_SIGNATURE'
|
|
161
|
+
if !j.repository.full_name.nil?
|
|
162
|
+
repo = j.repository.full_name
|
|
163
|
+
elsif !j.organization.login.nil?
|
|
164
|
+
repo = j.organization.login
|
|
165
|
+
else
|
|
166
|
+
end
|
|
167
|
+
# phash includes orgs and repos
|
|
168
|
+
phash = PROJECTS[repo.to_sym]
|
|
169
|
+
token = phash['token']
|
|
170
|
+
sent_token = request.env['HTTP_X_HUB_SIGNATURE']
|
|
171
|
+
signature = "sha1=#{OpenSSL::HMAC.hexdigest('sha1', token, payload.strip).chomp}"
|
|
172
|
+
resp = GitHubParser.parse json, request.env['HTTP_X_GITHUB_EVENT']
|
|
173
|
+
if signature.to_s == sent_token.to_s
|
|
174
|
+
channels = phash['channels'.to_sym]
|
|
175
|
+
channels.each {
|
|
176
|
+
|channet|
|
|
177
|
+
channel = channet.split(',')[0]
|
|
178
|
+
network = channet.split(',')[1]
|
|
179
|
+
resp.each {
|
|
180
|
+
|n|
|
|
181
|
+
GitAll::Bots.bots[network].Channel(channel).send("#{n}")
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
elsif request.env.key?('HTTP_X_GOGS_EVENT')
|
|
187
|
+
|
|
188
|
+
elsif request.env.key?('HTTP_X_EVENT_KEY')
|
|
189
|
+
# BitBucket's Webhooks
|
|
190
|
+
# Requires HTTPS and does not
|
|
191
|
+
# implement a secret unless set into
|
|
192
|
+
# the url.
|
|
193
|
+
status 404
|
|
194
|
+
body 'bitbucket not implemented'
|
|
195
|
+
else
|
|
196
|
+
[404, "I can't help with that"]
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# lib/logger.rb
|
|
2
|
+
# Ken Spencer <ken@electrocode.net>
|
|
3
|
+
#
|
|
4
|
+
# This module is part of GitAll and is released under the
|
|
5
|
+
# MIT license: http://opensource.org/licenses/MIT
|
|
6
|
+
|
|
7
|
+
require 'cinch'
|
|
8
|
+
|
|
9
|
+
class GitLogger < Cinch::Logger::FormattedLogger
|
|
10
|
+
def initialize(network, *args)
|
|
11
|
+
@network = network
|
|
12
|
+
super(*args)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def format_general(message)
|
|
16
|
+
message.gsub!(/[^[:print:][:space:]]/) do |m|
|
|
17
|
+
colorize(m.inspect[1..-2], :bg_white, :black)
|
|
18
|
+
end
|
|
19
|
+
"[#{@network}] #{message}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# lib/bitbucket.rb
|
|
2
|
+
# Ken Spencer <ken@electrocode.net>
|
|
3
|
+
#
|
|
4
|
+
# This module is part of GitAll and is released under the
|
|
5
|
+
# MIT license: http://opensource.org/licenses/MIT
|
|
6
|
+
|
|
7
|
+
class BitBucketParser
|
|
8
|
+
# @param [Object] json json object
|
|
9
|
+
# @param [Object] event the github event
|
|
10
|
+
def self.parse(json, event)
|
|
11
|
+
ec, e = event.split(':')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# lib/github.rb
|
|
2
|
+
# Ken Spencer <ken@electrocode.net>
|
|
3
|
+
#
|
|
4
|
+
# This module is part of GitAll and is released under the
|
|
5
|
+
# MIT license: http://opensource.org/licenses/MIT
|
|
6
|
+
|
|
7
|
+
# GitHub Event Parsing
|
|
8
|
+
# noinspection RubyUnusedLocalVariable
|
|
9
|
+
require 'cinch'
|
|
10
|
+
class GitHubParser
|
|
11
|
+
# @param [Object] json json object
|
|
12
|
+
# @param [Object] event the github event
|
|
13
|
+
def self.parse(json, event)
|
|
14
|
+
j = RecursiveOpenStruct.new(json)
|
|
15
|
+
response = []
|
|
16
|
+
case event
|
|
17
|
+
when 'ping'
|
|
18
|
+
zen = j.zen
|
|
19
|
+
id = j.hook_id
|
|
20
|
+
response << "Hook #{id} [PING] '#{zen}'"
|
|
21
|
+
when 'issue_comment'
|
|
22
|
+
when 'member'
|
|
23
|
+
when 'membership'
|
|
24
|
+
when 'milestone'
|
|
25
|
+
when 'label'
|
|
26
|
+
# "action":"created",
|
|
27
|
+
# "label":{
|
|
28
|
+
# "url":"https://api.github.com/repos/baxterandthehackers/public-repo/labels/blocked",
|
|
29
|
+
# "name":"blocked",
|
|
30
|
+
# "color":"ff0000"
|
|
31
|
+
# },
|
|
32
|
+
action = j.action
|
|
33
|
+
l = j.label
|
|
34
|
+
repo = j.repository.full_name
|
|
35
|
+
user = j.sender.login
|
|
36
|
+
lurl = l.url
|
|
37
|
+
lname = l.name
|
|
38
|
+
case action
|
|
39
|
+
when 'created', 'deleted'
|
|
40
|
+
response << "[#{repo}] #{user} #{action} label #{lname} <#{lurl}>"
|
|
41
|
+
when 'edited'
|
|
42
|
+
old = l.changes.name.from
|
|
43
|
+
new = lname
|
|
44
|
+
if old != new
|
|
45
|
+
response << "[#{repo}] #{user} #{action} Old: #{old} New: #{new}"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
when 'team'
|
|
49
|
+
when 'team_add'
|
|
50
|
+
when 'fork'
|
|
51
|
+
f = RecursiveOpenStruct.new(j.forkee)
|
|
52
|
+
user = j.sender.login
|
|
53
|
+
fork = f.full_name
|
|
54
|
+
repo = j.repository.full_name
|
|
55
|
+
response << "[#{repo}] #{user} forked the repository to #{fork}"
|
|
56
|
+
when 'pull_request'
|
|
57
|
+
p = RecursiveOpenStruct.new(j.pull_request)
|
|
58
|
+
action = j.action
|
|
59
|
+
case action
|
|
60
|
+
when 'opened'
|
|
61
|
+
when 'closed'
|
|
62
|
+
end
|
|
63
|
+
when 'pull_request_review'
|
|
64
|
+
action = j.action
|
|
65
|
+
case action
|
|
66
|
+
when 'created'
|
|
67
|
+
when 'deleted'
|
|
68
|
+
end
|
|
69
|
+
when 'pull_request_review_comment'
|
|
70
|
+
c = RecursiveOpenStruct.new(j.comment)
|
|
71
|
+
action = j.action
|
|
72
|
+
case action
|
|
73
|
+
when 'created'
|
|
74
|
+
when 'deleted'
|
|
75
|
+
when 'edited'
|
|
76
|
+
end
|
|
77
|
+
when 'commit_comment'
|
|
78
|
+
when 'gollum'
|
|
79
|
+
p = j.pages
|
|
80
|
+
action = j.action
|
|
81
|
+
when 'create'
|
|
82
|
+
when 'delete'
|
|
83
|
+
when 'organization'
|
|
84
|
+
action = j.action
|
|
85
|
+
case action
|
|
86
|
+
when 'member_add'
|
|
87
|
+
when 'member_del'
|
|
88
|
+
end
|
|
89
|
+
when 'repository'
|
|
90
|
+
r = RecursiveOpenStruct.new(j.repository)
|
|
91
|
+
action = j.action
|
|
92
|
+
repo = r.full_name
|
|
93
|
+
user = j.sender.login
|
|
94
|
+
case action
|
|
95
|
+
when 'created'
|
|
96
|
+
response << "#{user} created repository #{repo}"
|
|
97
|
+
when 'deleted'
|
|
98
|
+
# XXX: Only triggers on Organization webhooks
|
|
99
|
+
response << "#{user} deleted #{r.full_name}"
|
|
100
|
+
end
|
|
101
|
+
when 'release'
|
|
102
|
+
r = RecursiveOpenStruct.new(j.release)
|
|
103
|
+
tag = r.tag_name
|
|
104
|
+
action = j.action
|
|
105
|
+
repo = j.repository.full_name
|
|
106
|
+
case action
|
|
107
|
+
when 'published'
|
|
108
|
+
response << "[#{repo}] released #{tag}!"
|
|
109
|
+
else
|
|
110
|
+
response << "[#{repo}] #{action} something!"
|
|
111
|
+
response << "**\u000304This is a fallback for when new actions are added to the 'ReleaseEvent'**"
|
|
112
|
+
response << 'Please submit an issue at https://github.com/IotaSpencer/gitall'
|
|
113
|
+
response << ' or join #gitall on the freenode or ElectroCode IRC networks.'
|
|
114
|
+
end
|
|
115
|
+
when 'watch'
|
|
116
|
+
# XXX: possibly add user's profile url if option set
|
|
117
|
+
response << "[#{repo}] #{user} starred the repository!"
|
|
118
|
+
when 'issue'
|
|
119
|
+
repo = j.repository.full_name
|
|
120
|
+
url = shorten(j.issue.url)
|
|
121
|
+
action = j.action
|
|
122
|
+
id = j.issue.number
|
|
123
|
+
title = j.issue.title
|
|
124
|
+
user = j.issue.user.name
|
|
125
|
+
# assigned", "unassigned", "labeled", "unlabeled", "opened", "edited",
|
|
126
|
+
# "milestoned", "demilestoned", "closed", or "reopened".
|
|
127
|
+
case action
|
|
128
|
+
when 'assigned'
|
|
129
|
+
# do stuff ...
|
|
130
|
+
when 'unassigned'
|
|
131
|
+
# do stuff ...
|
|
132
|
+
when 'labeled'
|
|
133
|
+
label = j.label.name
|
|
134
|
+
response << "[#{repo}] #{user} added #{label}"
|
|
135
|
+
when 'unlabeled'
|
|
136
|
+
# do stuff ...
|
|
137
|
+
when 'milestoned'
|
|
138
|
+
response << "[#{repo}] #{user} milestoned issue ##{id} "
|
|
139
|
+
when 'demilestoned'
|
|
140
|
+
# do stuff ...
|
|
141
|
+
when 'reopened'
|
|
142
|
+
response << "[#{repo}] #{user} reopened ##{id}"
|
|
143
|
+
|
|
144
|
+
when 'opened'
|
|
145
|
+
response << "[#{repo}] #{user} opened an issue ##{id} - #{title} <#{url}>"
|
|
146
|
+
when 'closed'
|
|
147
|
+
response << "[#{repo}] #{user} closed issue ##{id} - #{title} <#{url}>"
|
|
148
|
+
when 'edited'
|
|
149
|
+
response << "[#{repo}] #{user} edited issue ##{id} - #{title} <#{url}>"
|
|
150
|
+
end
|
|
151
|
+
when 'push'
|
|
152
|
+
repo = j.repository.full_name
|
|
153
|
+
branch = j.ref.split('/')[-1]
|
|
154
|
+
commits = j.commits
|
|
155
|
+
added = 0
|
|
156
|
+
removed = 0
|
|
157
|
+
modified = 0
|
|
158
|
+
commits.each do |h|
|
|
159
|
+
added += h['added'].length
|
|
160
|
+
removed += h['removed'].length
|
|
161
|
+
modified += h['modified'].length
|
|
162
|
+
end
|
|
163
|
+
pusher = j.pusher.name
|
|
164
|
+
commit_count = commits.length
|
|
165
|
+
compare_url = shorten(j.compare)
|
|
166
|
+
response << "[#{repo}] #{pusher} pushed #{commit_count} commit(s) [+#{added}/-#{removed}/±#{modified}] to [#{branch}] <#{compare_url}>"
|
|
167
|
+
if commits.length > 3
|
|
168
|
+
coms = commits[0..2]
|
|
169
|
+
coms.each do |n|
|
|
170
|
+
id = n.dig('id')
|
|
171
|
+
id = id[0...7]
|
|
172
|
+
msg = n.dig('message').lines[0].chomp
|
|
173
|
+
author = n.dig 'committer', 'name'
|
|
174
|
+
response << "#{author} — #{msg} [#{id}]"
|
|
175
|
+
end
|
|
176
|
+
response << "and #{commits.length - 3} commits..."
|
|
177
|
+
else
|
|
178
|
+
commits.each do |n|
|
|
179
|
+
id = n.dig('id')
|
|
180
|
+
id = id[0...7]
|
|
181
|
+
msg = n.dig('message').lines[0].chomp
|
|
182
|
+
author = n.dig 'committer', 'name'
|
|
183
|
+
response << "#{author} — #{msg} [#{id}]"
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
else
|
|
187
|
+
'format not implemented'
|
|
188
|
+
end
|
|
189
|
+
response
|
|
190
|
+
end
|
|
191
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# lib/gitlab.rb
|
|
2
|
+
# Ken Spencer <ken@electrocode.net>
|
|
3
|
+
#
|
|
4
|
+
# This module is part of GitAll and is released under the
|
|
5
|
+
# MIT license: http://opensource.org/licenses/MIT
|
|
6
|
+
|
|
7
|
+
# GitLab Event Parsing
|
|
8
|
+
class GitLabParser
|
|
9
|
+
def GitLabParser.parse(json)
|
|
10
|
+
j = RecursiveOpenStruct.new(json)
|
|
11
|
+
response = []
|
|
12
|
+
kind = j.object_kind
|
|
13
|
+
case kind
|
|
14
|
+
when 'note'
|
|
15
|
+
repo = j.project.path_with_namespace
|
|
16
|
+
ntype = j.object_attributes.noteable_type
|
|
17
|
+
case ntype
|
|
18
|
+
when 'MergeRequest'
|
|
19
|
+
mr_note = j.object_attributes.note
|
|
20
|
+
mr_url = shorten(j.object_attributes.url)
|
|
21
|
+
mr_title = j.merge_request.title
|
|
22
|
+
mr_id = j.merge_request.iid
|
|
23
|
+
mr_user = j.user.name
|
|
24
|
+
response << "[#{repo}] #{mr_user} commented on Merge Request ##{mr_id} \u2014 #{mr_note}"
|
|
25
|
+
response << "'#{mr_title}' => #{mr_url}"
|
|
26
|
+
when 'Commit'
|
|
27
|
+
c_note = j.object_attributes.note
|
|
28
|
+
c_sha = j.commit.id[0...7]
|
|
29
|
+
c_url = shorten(j.object_attributes.url)
|
|
30
|
+
c_user = j.user.name
|
|
31
|
+
response << "[#{repo}] #{c_user} commented on commit (#{c_sha}) \u2014 #{c_note} <#{c_url}>"
|
|
32
|
+
when 'Issue'
|
|
33
|
+
i_id = j.issue.iid
|
|
34
|
+
i_url = shorten(j.object_attributes.url)
|
|
35
|
+
i_msg = j.object_attributes.note
|
|
36
|
+
i_title = j.issue.title
|
|
37
|
+
i_user = j.user.name
|
|
38
|
+
response << "[#{repo}] #{i_user} commented on Issue ##{i_id} (#{i_title}) \u2014 #{i_msg} <#{i_url}>"
|
|
39
|
+
else
|
|
40
|
+
# type code here
|
|
41
|
+
end
|
|
42
|
+
when 'issue'
|
|
43
|
+
i_repo = j.project.path_with_namespace
|
|
44
|
+
i_user = j.user.name
|
|
45
|
+
i_un = j.user.username
|
|
46
|
+
i_id = j.object_attributes.iid
|
|
47
|
+
i_title = j.object_attributes.title
|
|
48
|
+
i_action = j.object_attributes.action
|
|
49
|
+
i_url = shorten(j.object_attributes.url)
|
|
50
|
+
response << "[#{i_repo}] #{i_user}(#{i_un}) #{i_action} issue ##{i_id} - #{i_title} <#{i_url}>"
|
|
51
|
+
when 'merge_request'
|
|
52
|
+
mr_name = j.user.name
|
|
53
|
+
mr_user = j.user.username
|
|
54
|
+
mr_url = shorten(j.url)
|
|
55
|
+
mr_spath = j.object_attributes.source.path_with_namespace
|
|
56
|
+
mr_sbranch = j.object_attributes.source_branch
|
|
57
|
+
mr_tpath = j.object_attributes.target.path_with_namespace
|
|
58
|
+
mr_tbranch = j.object_attributes.target_branch
|
|
59
|
+
mr_lcmessage = j.object_attributes.last_commit.message
|
|
60
|
+
mr_lcsha = j.object_attributes.last_commit.id[0...7]
|
|
61
|
+
response << "#{mr_name}(#{mr_user}) opened a merge request. #{mr_spath}[#{mr_sbranch}] ~> #{mr_tpath}[#{mr_tbranch}]"
|
|
62
|
+
response << "[#{mr_lcsha}] \u2014 #{mr_lcmessage} <#{mr_url}>"
|
|
63
|
+
when 'push' # comes to
|
|
64
|
+
# shove
|
|
65
|
+
branch = j.ref.split('/')[-1]
|
|
66
|
+
commits = j.commits
|
|
67
|
+
added = 0
|
|
68
|
+
removed = 0
|
|
69
|
+
modified = 0
|
|
70
|
+
commits.each do |h|
|
|
71
|
+
added += h['added'].length
|
|
72
|
+
removed += h['removed'].length
|
|
73
|
+
modified += h['modified'].length
|
|
74
|
+
end
|
|
75
|
+
owner = j.project.namespace
|
|
76
|
+
project = j.project.name
|
|
77
|
+
pusher = j.user_name
|
|
78
|
+
commit_count = j.total_commits_count
|
|
79
|
+
repo_url = shorten(j.project.web_url)
|
|
80
|
+
response << "[#{owner}/#{project}] #{pusher} pushed #{commit_count} commit(s) [+#{added}/-#{removed}/±#{modified}] to [#{branch}] at <#{repo_url}>"
|
|
81
|
+
if commits.length > 3
|
|
82
|
+
coms = commits[0..2]
|
|
83
|
+
coms.each do |n|
|
|
84
|
+
id = n['id']
|
|
85
|
+
msg = n['message'].lines[0]
|
|
86
|
+
author = n['author']['name']
|
|
87
|
+
response << "#{author} — #{msg.chomp!} [#{id[0...7]}]"
|
|
88
|
+
end
|
|
89
|
+
response << "and #{commits.from(3).length} commits..."
|
|
90
|
+
else
|
|
91
|
+
commits.each do |n|
|
|
92
|
+
id = n['id'][0...7]
|
|
93
|
+
msg = n['message'].lines[0]
|
|
94
|
+
author = n['author']['name']
|
|
95
|
+
response << "#{author} — #{msg.chomp!} [#{id}]"
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
else
|
|
99
|
+
# type code here
|
|
100
|
+
end
|
|
101
|
+
return response
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# lib/admin.rb
|
|
2
|
+
# Ken Spencer <ken@electrocode.net>
|
|
3
|
+
#
|
|
4
|
+
# This module is part of GitAll and is released under the
|
|
5
|
+
# MIT license: http://opensource.org/licenses/MIT
|
|
6
|
+
|
|
7
|
+
require 'cinch'
|
|
8
|
+
require 'cinch/extensions/authentication'
|
|
9
|
+
require 'yaml'
|
|
10
|
+
require 'recursive-open-struct'
|
|
11
|
+
|
|
12
|
+
# @class Admin Plugin
|
|
13
|
+
class Admin
|
|
14
|
+
include Cinch::Plugin
|
|
15
|
+
include Cinch::Extensions::Authentication
|
|
16
|
+
match /quit$/, method: :do_Quit, group: :quit
|
|
17
|
+
match /quit (.+)$/, method: :do_Quit, group: :quit
|
|
18
|
+
|
|
19
|
+
match /join$/, method: :do_Join, group: :join
|
|
20
|
+
match /join (.+)/, method: :do_Join, group: :join
|
|
21
|
+
|
|
22
|
+
match /announce$/, method: :do_Announce, group: :announce
|
|
23
|
+
match /announce (.+)$/, method: :do_Announce, group: :announce
|
|
24
|
+
match /global$/, method: :do_Announce, group: :announce
|
|
25
|
+
match /global (.+)$/, method: :do_Announce, group: :announce
|
|
26
|
+
|
|
27
|
+
def do_Announce(m, msg = nil)
|
|
28
|
+
return unless authenticated? m
|
|
29
|
+
if msg.nil?
|
|
30
|
+
command = m.command
|
|
31
|
+
m.reply "Syntax: !#{command} Message to announce..."
|
|
32
|
+
else
|
|
33
|
+
$bots.each do |net, bot|
|
|
34
|
+
info("Announcing to #{net}")
|
|
35
|
+
debug("Announcing '#{msg}'")
|
|
36
|
+
bot.channels.each do |c|
|
|
37
|
+
Channel(c).send("[GLOBAL - #{m.user}@#{m.bot.irc.isupport.fetch('NETWORK')}] #{msg}",
|
|
38
|
+
notice=false)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def do_Quit(m, msg = nil)
|
|
45
|
+
return unless authenticated? m
|
|
46
|
+
if msg.nil?
|
|
47
|
+
$bots.each do |net, bot|
|
|
48
|
+
info("Exiting from #{net}")
|
|
49
|
+
bot.quit('QUIT received!')
|
|
50
|
+
end
|
|
51
|
+
else
|
|
52
|
+
$bots.each do |net, bot|
|
|
53
|
+
info("Exiting from #{net}")
|
|
54
|
+
bot.quit(msg)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
$threads.each(&:exit)
|
|
58
|
+
end
|
|
59
|
+
def do_Join(m, channels = nil)
|
|
60
|
+
return unless authenticated? m
|
|
61
|
+
if channels.nil?
|
|
62
|
+
m.reply 'Syntax: join #channel[,#channel2,#channel3]'
|
|
63
|
+
else
|
|
64
|
+
chans = channels.split(',')
|
|
65
|
+
chans.each do |chan|
|
|
66
|
+
Channel(chan).join
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
def do_Part(m, channels = nil, reasons = nil)
|
|
71
|
+
return unless authenticated? m
|
|
72
|
+
if channels.nil? && reasons.nil?
|
|
73
|
+
m.reply 'Syntax: part #channel1[,#channel2,#channel3] [reason1[,reason2,reason3]]'
|
|
74
|
+
else
|
|
75
|
+
m.reply 'Not implemented yet'
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# lib/chancontrol.rb
|
|
2
|
+
# Ken Spencer <ken@electrocode.net>
|
|
3
|
+
#
|
|
4
|
+
# This module is part of GitAll and is released under the
|
|
5
|
+
# MIT license: http://opensource.org/licenses/MIT
|
|
6
|
+
|
|
7
|
+
require 'cinch'
|
|
8
|
+
require 'cinch/extensions/authentication'
|
|
9
|
+
require 'yaml'
|
|
10
|
+
require 'recursive-open-struct'
|
|
11
|
+
require 'strgen'
|
|
12
|
+
# @note ChanControl Plugin
|
|
13
|
+
|
|
14
|
+
class ChanControl
|
|
15
|
+
include Cinch::Plugin
|
|
16
|
+
include Cinch::Extensions::Authentication
|
|
17
|
+
|
|
18
|
+
# Write to the config
|
|
19
|
+
# @param [Hash] msg the data to write
|
|
20
|
+
def toFile(msg)
|
|
21
|
+
data = msg
|
|
22
|
+
File.open(`echo ~/.gitall-rc.yml`.chomp, 'w') {|f| f.write(data.to_yaml) }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Load the config
|
|
26
|
+
# @return [Hash] load the current config
|
|
27
|
+
def deFile
|
|
28
|
+
begin
|
|
29
|
+
parsed = YAML.load(File.open(`echo ~/.gitall-rc.yml`.chomp, 'r'))
|
|
30
|
+
rescue ArgumentError => e
|
|
31
|
+
puts "Could not parse YAML: #{e.message}"
|
|
32
|
+
end
|
|
33
|
+
parsed
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
match /padd$/, method: :padd, group: :padd
|
|
37
|
+
match /padd (\S+) (\S+) (\S+) (\S+)/, method: :padd, group: :padd
|
|
38
|
+
|
|
39
|
+
match /list$/, method: :listchans, group: :listchans
|
|
40
|
+
match /list (\S+)/, method: :listchans, group: :listchans
|
|
41
|
+
|
|
42
|
+
match /token$/, method: :getToken, group: :token
|
|
43
|
+
match /token ([0-9]+)/, method: :getToken, group: :token
|
|
44
|
+
|
|
45
|
+
# @param [Message]
|
|
46
|
+
# @param [String] namespace the Repository to watch
|
|
47
|
+
# @param [String] host the Git Service Website
|
|
48
|
+
# @param [String] token Secret Token @seealso {ChanControl#getToken}
|
|
49
|
+
# @param [ChannelList] channels | separated list of channels in the format
|
|
50
|
+
# of #channel,net
|
|
51
|
+
def padd(m, namespace = nil, host = nil, token = nil, channels = nil)
|
|
52
|
+
if namespace.nil?
|
|
53
|
+
m.reply 'Syntax: padd {OWNER/PROJECT} {github, gitlab, bitbucket}
|
|
54
|
+
XXXXXXTOKEN #channel,network[|#channel2,network|#channel3,network2]'
|
|
55
|
+
m.reply 'GitALL works best when using owner/repo webhooks, organization hooks have not been tested.'
|
|
56
|
+
else
|
|
57
|
+
return unless authenticated? m
|
|
58
|
+
config = deFile
|
|
59
|
+
if config[:projects].has_key? namespace
|
|
60
|
+
m.user.send("#{m.user.nick}: #{namespace} already exists in the
|
|
61
|
+
config.")
|
|
62
|
+
else
|
|
63
|
+
config[:projects][namespace] = {
|
|
64
|
+
host: host,
|
|
65
|
+
token: token,
|
|
66
|
+
channels: channels.split('|')
|
|
67
|
+
}
|
|
68
|
+
toFile(config)
|
|
69
|
+
project = deFile().dig(:projects, namespace)
|
|
70
|
+
m.user.send("Inputted: #{project}")
|
|
71
|
+
end
|
|
72
|
+
# @param [String] host
|
|
73
|
+
def cap_host(host)
|
|
74
|
+
case host.downcase
|
|
75
|
+
when 'github'
|
|
76
|
+
'GitHub.com'
|
|
77
|
+
when 'gitlab'
|
|
78
|
+
'GitLab.com'
|
|
79
|
+
when 'bitbucket'
|
|
80
|
+
'BitBucket.org'
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
m.user.send("Remember to add the webhook to #{cap_host(host)} if you
|
|
84
|
+
haven't already.")
|
|
85
|
+
info("Project added: #{project}")
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# @param [Message] m message object
|
|
90
|
+
# @param [Integer] length token length
|
|
91
|
+
# @return [String] Token
|
|
92
|
+
def getToken(m, length = nil)
|
|
93
|
+
token = Strgen.generate do |c|
|
|
94
|
+
if length.nil?
|
|
95
|
+
c.length = 30
|
|
96
|
+
else
|
|
97
|
+
if length.to_i > 100
|
|
98
|
+
c.length = 100
|
|
99
|
+
m.reply 'Truncating to 100 characters due to spam concerns'
|
|
100
|
+
else
|
|
101
|
+
c.length = length
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
c.alpha = true
|
|
105
|
+
c.numbers = true
|
|
106
|
+
c.repeat = false
|
|
107
|
+
c.symbols = false
|
|
108
|
+
c.exclude = %w[1 i I l L 0 o O]
|
|
109
|
+
end
|
|
110
|
+
m.user.send "Token: #{token}"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# @param [Channel] channel name of channel
|
|
114
|
+
# @note Ensures that the channel is joined or known of
|
|
115
|
+
# @returns Boolean true/false
|
|
116
|
+
|
|
117
|
+
def self.joined(channel)
|
|
118
|
+
Channel(channel) ? true : false
|
|
119
|
+
end
|
|
120
|
+
# @param [Object] m Object
|
|
121
|
+
|
|
122
|
+
def listchans(m, project = nil)
|
|
123
|
+
return unless authenticated? m
|
|
124
|
+
project_hash = deFile['projects'][project]
|
|
125
|
+
m.reply "Name: #{project} Host: #{project_hash['host'.to_sym]} Channels: #{project_hash['channels'.to_sym].join(" \xB7 ")}"
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'cinch'
|
|
2
|
+
class Eval
|
|
3
|
+
include Cinch::Plugin
|
|
4
|
+
include Cinch::Extensions::Authentication
|
|
5
|
+
|
|
6
|
+
match /eval$/, method: :do_eval, group: :doeval
|
|
7
|
+
match /eval (.*)/, method: :do_eval, group: :doeval
|
|
8
|
+
|
|
9
|
+
def do_eval(m, string = nil)
|
|
10
|
+
if string.nil?
|
|
11
|
+
m.reply "Syntax: !eval [CODE...]"
|
|
12
|
+
else
|
|
13
|
+
return unless authenticated? m
|
|
14
|
+
m.reply(eval(string))
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# lib/git.rb
|
|
2
|
+
# Ken Spencer <ken@electrocode.net>
|
|
3
|
+
#
|
|
4
|
+
# This module is part of GitAll and is released under the
|
|
5
|
+
# MIT license: http://opensource.org/licenses/MIT
|
|
6
|
+
|
|
7
|
+
require 'cinch'
|
|
8
|
+
require 'cinch/extensions/authentication'
|
|
9
|
+
require 'unirest'
|
|
10
|
+
class ChanControl
|
|
11
|
+
include Cinch::Plugin
|
|
12
|
+
include Cinch::Extensions::Authentication
|
|
13
|
+
|
|
14
|
+
match /(\s+)\:(\S)\/(\S+)\#(\S)/, :method => :getIssue
|
|
15
|
+
|
|
16
|
+
def getIssue(m, host, user, repo, issue)
|
|
17
|
+
case host
|
|
18
|
+
when 'gl'
|
|
19
|
+
m.reply("https://gitlab.com/#{user}/#{repo}/issues/#{issue}")
|
|
20
|
+
when 'gh'
|
|
21
|
+
m.reply("https://github.com/#{user}/#{repo}/issue/#{issue}")
|
|
22
|
+
when 'bb'
|
|
23
|
+
m.reply("https://bitbucket.org/#{user}/#{repo}/issue/#{issue}")
|
|
24
|
+
else
|
|
25
|
+
m.user.notice("I don't know that git-service host")
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/lib/views/_403.erb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Invalid / Missing 'Secret' or 'Token'
|
metadata
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: gitall
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.1.5
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Ken Spencer
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2018-06-21 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: cinch
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 2.3.4
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 2.3.4
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: sinatra
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '2.0'
|
|
34
|
+
- - ">="
|
|
35
|
+
- !ruby/object:Gem::Version
|
|
36
|
+
version: 2.0.2
|
|
37
|
+
type: :runtime
|
|
38
|
+
prerelease: false
|
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - "~>"
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '2.0'
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: 2.0.2
|
|
47
|
+
- !ruby/object:Gem::Dependency
|
|
48
|
+
name: sinatra-contrib
|
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: 2.0.2
|
|
54
|
+
- - ">="
|
|
55
|
+
- !ruby/object:Gem::Version
|
|
56
|
+
version: 2.0.2
|
|
57
|
+
type: :runtime
|
|
58
|
+
prerelease: false
|
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
60
|
+
requirements:
|
|
61
|
+
- - "~>"
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: 2.0.2
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: 2.0.2
|
|
67
|
+
- !ruby/object:Gem::Dependency
|
|
68
|
+
name: thor
|
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - "~>"
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '0.20'
|
|
74
|
+
type: :runtime
|
|
75
|
+
prerelease: false
|
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
77
|
+
requirements:
|
|
78
|
+
- - "~>"
|
|
79
|
+
- !ruby/object:Gem::Version
|
|
80
|
+
version: '0.20'
|
|
81
|
+
- !ruby/object:Gem::Dependency
|
|
82
|
+
name: paint
|
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
|
84
|
+
requirements:
|
|
85
|
+
- - "~>"
|
|
86
|
+
- !ruby/object:Gem::Version
|
|
87
|
+
version: '2.0'
|
|
88
|
+
type: :runtime
|
|
89
|
+
prerelease: false
|
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
91
|
+
requirements:
|
|
92
|
+
- - "~>"
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: '2.0'
|
|
95
|
+
- !ruby/object:Gem::Dependency
|
|
96
|
+
name: git
|
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
|
98
|
+
requirements:
|
|
99
|
+
- - "~>"
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
version: '1.3'
|
|
102
|
+
type: :runtime
|
|
103
|
+
prerelease: false
|
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
105
|
+
requirements:
|
|
106
|
+
- - "~>"
|
|
107
|
+
- !ruby/object:Gem::Version
|
|
108
|
+
version: '1.3'
|
|
109
|
+
- !ruby/object:Gem::Dependency
|
|
110
|
+
name: logging
|
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
|
112
|
+
requirements:
|
|
113
|
+
- - "~>"
|
|
114
|
+
- !ruby/object:Gem::Version
|
|
115
|
+
version: '2.2'
|
|
116
|
+
type: :runtime
|
|
117
|
+
prerelease: false
|
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
119
|
+
requirements:
|
|
120
|
+
- - "~>"
|
|
121
|
+
- !ruby/object:Gem::Version
|
|
122
|
+
version: '2.2'
|
|
123
|
+
- !ruby/object:Gem::Dependency
|
|
124
|
+
name: pry
|
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
|
126
|
+
requirements:
|
|
127
|
+
- - "~>"
|
|
128
|
+
- !ruby/object:Gem::Version
|
|
129
|
+
version: '0.11'
|
|
130
|
+
type: :runtime
|
|
131
|
+
prerelease: false
|
|
132
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
133
|
+
requirements:
|
|
134
|
+
- - "~>"
|
|
135
|
+
- !ruby/object:Gem::Version
|
|
136
|
+
version: '0.11'
|
|
137
|
+
- !ruby/object:Gem::Dependency
|
|
138
|
+
name: bundler
|
|
139
|
+
requirement: !ruby/object:Gem::Requirement
|
|
140
|
+
requirements:
|
|
141
|
+
- - "~>"
|
|
142
|
+
- !ruby/object:Gem::Version
|
|
143
|
+
version: '1.16'
|
|
144
|
+
type: :development
|
|
145
|
+
prerelease: false
|
|
146
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
147
|
+
requirements:
|
|
148
|
+
- - "~>"
|
|
149
|
+
- !ruby/object:Gem::Version
|
|
150
|
+
version: '1.16'
|
|
151
|
+
- !ruby/object:Gem::Dependency
|
|
152
|
+
name: rake
|
|
153
|
+
requirement: !ruby/object:Gem::Requirement
|
|
154
|
+
requirements:
|
|
155
|
+
- - "~>"
|
|
156
|
+
- !ruby/object:Gem::Version
|
|
157
|
+
version: '10.0'
|
|
158
|
+
type: :development
|
|
159
|
+
prerelease: false
|
|
160
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
161
|
+
requirements:
|
|
162
|
+
- - "~>"
|
|
163
|
+
- !ruby/object:Gem::Version
|
|
164
|
+
version: '10.0'
|
|
165
|
+
- !ruby/object:Gem::Dependency
|
|
166
|
+
name: rspec
|
|
167
|
+
requirement: !ruby/object:Gem::Requirement
|
|
168
|
+
requirements:
|
|
169
|
+
- - "~>"
|
|
170
|
+
- !ruby/object:Gem::Version
|
|
171
|
+
version: '3.0'
|
|
172
|
+
type: :development
|
|
173
|
+
prerelease: false
|
|
174
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
175
|
+
requirements:
|
|
176
|
+
- - "~>"
|
|
177
|
+
- !ruby/object:Gem::Version
|
|
178
|
+
version: '3.0'
|
|
179
|
+
description: A git based webhook receiver for GitHub, GitLab, and Gogs
|
|
180
|
+
email:
|
|
181
|
+
- me@iotaspencer.me
|
|
182
|
+
executables:
|
|
183
|
+
- gitall
|
|
184
|
+
extensions: []
|
|
185
|
+
extra_rdoc_files: []
|
|
186
|
+
files:
|
|
187
|
+
- bin/gitall
|
|
188
|
+
- lib/cli/app.rb
|
|
189
|
+
- lib/gitall/gitall.rb
|
|
190
|
+
- lib/gitall/logger.rb
|
|
191
|
+
- lib/gitall/parsers/bitbucket.rb
|
|
192
|
+
- lib/gitall/parsers/github.rb
|
|
193
|
+
- lib/gitall/parsers/gitlab.rb
|
|
194
|
+
- lib/gitall/plugins/admin.rb
|
|
195
|
+
- lib/gitall/plugins/chancontrol.rb
|
|
196
|
+
- lib/gitall/plugins/eval.rb
|
|
197
|
+
- lib/gitall/plugins/git.rb
|
|
198
|
+
- lib/gitall/version.rb
|
|
199
|
+
- lib/views/_403.erb
|
|
200
|
+
homepage: https://gitlab.com/gitall/gitall
|
|
201
|
+
licenses:
|
|
202
|
+
- MIT
|
|
203
|
+
metadata: {}
|
|
204
|
+
post_install_message:
|
|
205
|
+
rdoc_options: []
|
|
206
|
+
require_paths:
|
|
207
|
+
- lib
|
|
208
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
209
|
+
requirements:
|
|
210
|
+
- - "~>"
|
|
211
|
+
- !ruby/object:Gem::Version
|
|
212
|
+
version: '2'
|
|
213
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
214
|
+
requirements:
|
|
215
|
+
- - ">="
|
|
216
|
+
- !ruby/object:Gem::Version
|
|
217
|
+
version: '0'
|
|
218
|
+
requirements: []
|
|
219
|
+
rubyforge_project:
|
|
220
|
+
rubygems_version: 2.7.6
|
|
221
|
+
signing_key:
|
|
222
|
+
specification_version: 4
|
|
223
|
+
summary: Git Based Webservices Webhook Receiver
|
|
224
|
+
test_files: []
|