errbit-ng-plugin 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a71eb449292cc07bf9a78044ca8b24e2eb9f4db9e1f67efef131712106a10ef3
4
+ data.tar.gz: 2adfcf8f85aeff119d76f63b969559d64729b054e687ff4786a47d6c55248eae
5
+ SHA512:
6
+ metadata.gz: 923ee8e3edf7bd66037568fe9532734b320142bb41908e5f2d0daf4552fa84049888b7ea1672fcb907f136e493e46b914b3c45d28d85c0997f33d89b2c871ccc
7
+ data.tar.gz: 30eded126d9a71985383cb8df0abe5268ce1aef57928dbd2bf5ae4931de1ee796b94acf37d69d2dfb489d7417d87831684ae0f6fc4cc7fda90875f0e23c398d8
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.1.6
data/.standard.yml ADDED
@@ -0,0 +1 @@
1
+ ruby_version: 3.1
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ ## main
4
+
5
+ * Rename `errbit_plugin` to `errbit-ng-plugin`
data/LICENSE.txt ADDED
@@ -0,0 +1,23 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Errbit
4
+ Copyright (c) 2013 Cyril Mougel
5
+ Copyright (c) 2025 Errbit-NG Team
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in
15
+ all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,134 @@
1
+ # ErrbitPlugin [![Build Status](https://travis-ci.org/errbit/errbit_plugin.svg?branch=master)](https://travis-ci.org/errbit/errbit_plugin)
2
+
3
+ ErrbitPlugin provides a set of base classes that you can extend to create
4
+ Errbit plugins.
5
+
6
+ ## Creating plugins
7
+
8
+ ErrbitPlugins are Ruby gems that extend the functionality of Errbit. To get
9
+ started, create a Ruby gem and add 'errbit_plugin' as a dependency in your
10
+ gem's gemspec.
11
+
12
+ Now you can start adding plugins. At the moment, there is only one kind of
13
+ plugin you can create, and that is the issue tracker.
14
+
15
+ ### Issue Trackers
16
+
17
+ An issue tracker plugin is a Ruby class that enables you to link errors within
18
+ errbit to an issue in an external issue tracker like Github. An app within
19
+ errbit can be associated an issue tracker or not. When there is an association,
20
+ errbit users can choose 'create issue' from an error page which will both
21
+ create an issue on the external issue tracker out of the given error and link
22
+ that issue to the errbit error. Likewise, a user can also choose 'close issue'
23
+ to close the issue on the external issue tracker, if your plugin provides a
24
+ method to do so.
25
+
26
+ Your issue tracker plugin is responsible for providing the interface defined by
27
+ ErrbitPlugin::IssueTracker. All of the required methods must be implemented and
28
+ the class must extend ErrbitPlugin::IssueTracker. Here's an example:
29
+
30
+ ```ruby
31
+ class MyIssueTracker < ErrbitPlugin::IssueTracker
32
+ # A unique label for your tracker plugin used internally by errbit
33
+ def self.label
34
+ "my-tracker"
35
+ end
36
+
37
+ def self.note
38
+ "a note about this tracker that users will see"
39
+ end
40
+
41
+ # Form fields that will be presented to the administrator when setting up
42
+ # or editing the errbit app. The values we collect will be availble for use
43
+ # later when we have an instance of this class.
44
+ def self.fields
45
+ {
46
+ username: {
47
+ placeholder: "Some placeholder text"
48
+ },
49
+ password: {
50
+ placeholder: "Some more placeholder text",
51
+ label: "Passphrase" # a label to use in the UI instead of 'password'
52
+ }
53
+ }
54
+ end
55
+
56
+ # Icons to display during user interactions with this issue tracker. This
57
+ # method should return a hash of two-tuples, the key names being 'create',
58
+ # 'goto', and 'inactive'. The two-tuples should contain the icon media type
59
+ # and the binary icon data.
60
+ def self.icons
61
+ @icons ||= {
62
+ create: ["image/png", File.read("./path/to/create.png")],
63
+ goto: ["image/png", File.read("./path/to/goto.png")],
64
+ inactive: ["image/png", File.read("./path/to/inactive.png")]
65
+ }
66
+ end
67
+
68
+ # If this tracker can be in a configured or non-configured state, you can let
69
+ # errbit know by returning a Boolean here
70
+ def configured?
71
+ # In this case, we'll say this issue tracker is configured when username
72
+ # and password are set
73
+ options[:username].present? && options[:password].present?
74
+ end
75
+
76
+ # Called to validate user input. Just return a hash of errors if there are
77
+ # any
78
+ def errors
79
+ if options[:username]
80
+ {}
81
+ else
82
+ {field_one: "username must be present"}
83
+ end
84
+ end
85
+
86
+ # This is where you actually go create the issue on the external issue
87
+ # tracker. You get access to everything in options, an issue title, body and
88
+ # a user record representing the user who's creating the issue.
89
+ #
90
+ # Return a string with a link to the issue
91
+ def create_issue(title, body, user: {})
92
+ # Create an issue! Then update the problem to link it.
93
+
94
+ "https://sometracker.com/my/issue/123"
95
+ end
96
+
97
+ # This method is optional. Errbit will create body text for your issue by
98
+ # calling render_to_string with some arguments. If you want control over
99
+ # those arguments, you can specify them here. You can control which file is
100
+ # rendered and anything else Rails allows you to specify as arguments in
101
+ # render_to_string.
102
+ #
103
+ # If you don't implement this method, Errbit will render a body using a
104
+ # default template
105
+ #
106
+ # @see http://apidock.com/rails/ActionController/Base/render_to_string
107
+ def render_body_args
108
+ # In this example, we want to render a special file
109
+ ["/path/to/some/template", formats: [:rdoc]]
110
+ end
111
+
112
+ # This method is optional, and is where you actually go close the issue on
113
+ # the external issue tracker. You get access to everything in options, a
114
+ # string with a link to the issue # and a user resource.
115
+ #
116
+ # return true if successful, false otherwise
117
+ def close_issue(issue_link, user = {})
118
+ # Close the issue! (Perhaps using the passed in issue_link url to identify it.)
119
+ end
120
+
121
+ # The URL for your remote issue tracker
122
+ def url
123
+ "https://some-remote-tracker.com"
124
+ end
125
+ end
126
+ ```
127
+
128
+ ## Contributing
129
+
130
+ Bug reports and pull requests are welcome on GitHub at https://github.com/errbit-ng/errbit-ng-plugin.
131
+
132
+ ## License
133
+
134
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "errbit_plugin"
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ErrbitPlugin
4
+ # abstract class for issue trackers
5
+ class IssueTracker
6
+ attr_reader :options
7
+
8
+ def initialize(options)
9
+ @options = options
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ErrbitPlugin
4
+ class NoneIssueTracker < IssueTracker
5
+ def self.label
6
+ "none"
7
+ end
8
+
9
+ def self.note
10
+ "When no issue tracker has been configured, you will be able to leave comments on errors."
11
+ end
12
+
13
+ def self.fields
14
+ {}
15
+ end
16
+
17
+ def self.icons
18
+ @icons ||= {
19
+ create: ["image/png", read_static_file("none_create.png")],
20
+ goto: ["image/png", read_static_file("none_create.png")],
21
+ inactive: ["image/png", read_static_file("none_inactive.png")]
22
+ }
23
+ end
24
+
25
+ def self.read_static_file(file)
26
+ File.read(File.expand_path(File.join(
27
+ File.dirname(__FILE__), "..", "..", "..", "static", file
28
+ )))
29
+ end
30
+
31
+ ##
32
+ # The NoneIssueTracker is mark like configured? false because it not valid
33
+ # like a real IssueTracker
34
+ def configured?
35
+ false
36
+ end
37
+
38
+ def errors
39
+ {}
40
+ end
41
+
42
+ def url
43
+ ""
44
+ end
45
+
46
+ def create_issue(*)
47
+ false
48
+ end
49
+
50
+ def close_issue(*)
51
+ false
52
+ end
53
+ end
54
+ end
55
+
56
+ ErrbitPlugin::Registry.add_issue_tracker(ErrbitPlugin::NoneIssueTracker)
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ErrbitPlugin
4
+ class IncompatibilityError < StandardError
5
+ end
6
+
7
+ class AlreadyRegisteredError < StandardError
8
+ end
9
+
10
+ class Registry
11
+ def self.add_issue_tracker(klass)
12
+ key = klass.label
13
+
14
+ if issue_trackers.has_key?(key)
15
+ raise AlreadyRegisteredError, "issue_tracker '#{key}' already registered"
16
+ end
17
+
18
+ validate = ValidateIssueTracker.new(klass)
19
+
20
+ if validate.valid?
21
+ @issue_trackers[key] = klass
22
+ else
23
+ raise IncompatibilityError.new(validate.errors.join("; "))
24
+ end
25
+ end
26
+
27
+ def self.clear_issue_trackers
28
+ @issue_trackers = {}
29
+ end
30
+
31
+ def self.issue_trackers
32
+ @issue_trackers ||= {}
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ErrbitPlugin
4
+ class ValidateIssueTracker
5
+ attr_reader :errors
6
+
7
+ def initialize(klass)
8
+ @klass = klass
9
+ @errors = []
10
+ end
11
+
12
+ def valid?
13
+ valid_inherit = good_inherit?
14
+ valid_instance_methods = implements_instance_methods?
15
+ valid_class_methods = implements_class_methods?
16
+
17
+ valid_inherit && valid_instance_methods && valid_class_methods
18
+ end
19
+
20
+ private
21
+
22
+ def good_inherit?
23
+ if @klass.ancestors.include?(ErrbitPlugin::IssueTracker)
24
+ true
25
+ else
26
+ add_errors(:not_inherited)
27
+
28
+ false
29
+ end
30
+ end
31
+
32
+ def implements_instance_methods?
33
+ impl = [:configured?, :errors, :create_issue, :url].map do |method|
34
+ if instance.respond_to?(method)
35
+ true
36
+ else
37
+ add_errors(:instance_method_missing, method)
38
+
39
+ false
40
+ end
41
+ end
42
+
43
+ impl.all? { |value| value == true }
44
+ end
45
+
46
+ def implements_class_methods?
47
+ impl = [:label, :fields, :note, :icons].map do |method|
48
+ if @klass.respond_to?(method)
49
+ true
50
+ else
51
+ add_errors(:class_method_missing, method)
52
+
53
+ false
54
+ end
55
+ end
56
+
57
+ impl.all? { |value| value == true }
58
+ end
59
+
60
+ def instance
61
+ @instance ||= @klass.new({})
62
+ end
63
+
64
+ def add_errors(key, value = nil)
65
+ @errors << [key, value].compact
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ErrbitPlugin
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "errbit_plugin/version"
4
+ require "errbit_plugin/registry"
5
+ require "errbit_plugin/issue_tracker"
6
+ require "errbit_plugin/validate_issue_tracker"
7
+ require "errbit_plugin/none_issue_tracker"
Binary file
Binary file
Binary file
Binary file
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: errbit-ng-plugin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ihor Zubkov
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 2025-01-31 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: Base to create an Errbit-NG plugins
13
+ email:
14
+ - igor.zubkov@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - ".rspec"
20
+ - ".ruby-version"
21
+ - ".standard.yml"
22
+ - CHANGELOG.md
23
+ - LICENSE.txt
24
+ - README.md
25
+ - Rakefile
26
+ - lib/errbit-ng-plugin.rb
27
+ - lib/errbit_plugin.rb
28
+ - lib/errbit_plugin/issue_tracker.rb
29
+ - lib/errbit_plugin/none_issue_tracker.rb
30
+ - lib/errbit_plugin/registry.rb
31
+ - lib/errbit_plugin/validate_issue_tracker.rb
32
+ - lib/errbit_plugin/version.rb
33
+ - static/fake_create.png
34
+ - static/fake_inactive.png
35
+ - static/none_create.png
36
+ - static/none_inactive.png
37
+ homepage: https://github.com/errbit-ng/errbit-ng-plugin
38
+ licenses:
39
+ - MIT
40
+ metadata:
41
+ rubygems_mfa_required: 'true'
42
+ bug_tracker_uri: https://github.com/errbit-ng/errbit-ng-plugin/issues
43
+ changelog_uri: https://github.com/errbit-ng/errbit-ng-plugin/blob/main/CHANGELOG.md
44
+ documentation_uri: https://github.com/errbit-ng/errbit-ng-plugin/blob/main/README.md
45
+ homepage_uri: https://github.com/errbit-ng/errbit-ng-plugin
46
+ source_code_uri: https://github.com/errbit-ng/errbit-ng-plugin
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 3.1.0
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubygems_version: 3.6.3
62
+ specification_version: 4
63
+ summary: Base to create an Errbit-NG plugins
64
+ test_files: []