rubocop-openproject 0.6.0 → 0.7.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b6399b37d75f31159de26fc061439ab6107f3621da14770ab2e3f4a263e4748e
|
|
4
|
+
data.tar.gz: c0bc045863a214c19a10fe29e4b23edd6d60f3598158f665fdfb4fefba851946
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5089a09294d79954f16b4fe511fd6b3aabe57b9272ebf41fa4a376feb7a6fcf8c2872b072fd6e3c7eb8493484e0e5b3eb2dc88f2bbfb964fa5fb67f0cdd8e5d8
|
|
7
|
+
data.tar.gz: 46759bc28c398aeefb4fb18305dd9494056a5296a859bb7789d4c37548b785a935a254f0cfcc98442cccceeb70fc5a788113316b3c58707dc0172506ab6462e0
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
4.0.
|
|
1
|
+
4.0.6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# rubocop-openproject
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ad3ff98: Add `OpenProject/UseEffectiveTypeForConfiguration` cop to catch reading a type's
|
|
8
|
+
configuration off `#type` instead of `#effective_type`. A work package stores the root of its
|
|
9
|
+
type family while its project may resolve that family to a variant configured differently, so
|
|
10
|
+
reading an aspect (form configuration, workflows, custom fields, defaults, export templates)
|
|
11
|
+
off the stored type silently answers with the root's configuration. The failure is quiet — a
|
|
12
|
+
project running the root behaves correctly, so a spec written without a variant passes while
|
|
13
|
+
the feature is broken wherever a variant is resolved. Inherited core settings (`name`,
|
|
14
|
+
`color`, `is_milestone`, `is_in_roadmap`) are read from the root by design and are not flagged.
|
|
15
|
+
|
|
3
16
|
## 0.6.0
|
|
4
17
|
|
|
5
18
|
### Minor Changes
|
data/config/default.yml
CHANGED
|
@@ -23,6 +23,11 @@ OpenProject/NoSleepInFeatureSpecs:
|
|
|
23
23
|
Enabled: true
|
|
24
24
|
VersionAdded: '0.1.0'
|
|
25
25
|
|
|
26
|
+
OpenProject/UseEffectiveTypeForConfiguration:
|
|
27
|
+
Description: 'Read a type''s configuration through `effective_type`, not `type`, so the project''s variant is honoured.'
|
|
28
|
+
Enabled: true
|
|
29
|
+
VersionAdded: '0.7.0'
|
|
30
|
+
|
|
26
31
|
OpenProject/UseRenderModeInsteadOfPrimitives:
|
|
27
32
|
Description: 'Use `render_mode:` instead of `static_html:`/`plain_text:`/`only_path:` on `format_text`.'
|
|
28
33
|
Enabled: true
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module OpenProject
|
|
6
|
+
# Flags reading a type's configuration off `#type` rather than `#effective_type`.
|
|
7
|
+
#
|
|
8
|
+
# A work package stores the root of its type family, while the project it lives in may
|
|
9
|
+
# resolve that family to a variant configured differently — a different form
|
|
10
|
+
# configuration, workflow, set of custom fields, defaults or export templates. Reading a
|
|
11
|
+
# configuration aspect off the stored type therefore answers with the root's
|
|
12
|
+
# configuration and silently ignores the variant.
|
|
13
|
+
#
|
|
14
|
+
# The failure mode is quiet: a project running the root behaves correctly, so a spec
|
|
15
|
+
# written without a variant passes while the feature is broken for every project that
|
|
16
|
+
# resolves one. That is what this cop is here to catch.
|
|
17
|
+
#
|
|
18
|
+
# Only configuration aspects are flagged. `name`, `color`, `is_milestone` and
|
|
19
|
+
# `is_in_roadmap` are inherited from the root by design, so reading those off `#type` is
|
|
20
|
+
# correct and left alone.
|
|
21
|
+
#
|
|
22
|
+
# Deliberately narrow: it fires when the receiver is literally a `type` call, which is
|
|
23
|
+
# the shape the mistake takes in practice. Administration code holding an explicit type
|
|
24
|
+
# (`@type.attribute_groups`) is reading that member's own configuration on purpose and is
|
|
25
|
+
# not flagged, and neither is a type held in a local variable.
|
|
26
|
+
#
|
|
27
|
+
# @example
|
|
28
|
+
# # bad
|
|
29
|
+
# work_package.type.attribute_groups
|
|
30
|
+
#
|
|
31
|
+
# # bad
|
|
32
|
+
# work_package.type.custom_fields
|
|
33
|
+
#
|
|
34
|
+
# # bad — inside WorkPackage itself
|
|
35
|
+
# type.statuses(include_default: true)
|
|
36
|
+
#
|
|
37
|
+
# # good
|
|
38
|
+
# work_package.effective_type.attribute_groups
|
|
39
|
+
#
|
|
40
|
+
# # good — when there is no work package to ask
|
|
41
|
+
# project.effective_type(type).attribute_groups
|
|
42
|
+
#
|
|
43
|
+
# # good — inherited from the root by design
|
|
44
|
+
# work_package.type.name
|
|
45
|
+
# work_package.type.is_milestone?
|
|
46
|
+
#
|
|
47
|
+
# # good — administration reads a specific member's own configuration
|
|
48
|
+
# @type.attribute_groups
|
|
49
|
+
class UseEffectiveTypeForConfiguration < Base
|
|
50
|
+
MSG = "Read configuration through `effective_type`, not `type` — the stored type is " \
|
|
51
|
+
"the family's root, so this ignores the variant the project resolves to."
|
|
52
|
+
|
|
53
|
+
# Configuration aspects, per Type::ConfigurationLink::ASPECTS and the readers
|
|
54
|
+
# Type::ConfigurationLinkable resolves through the link chain.
|
|
55
|
+
CONFIGURATION_METHODS = %i[
|
|
56
|
+
artefact_export_enabled?
|
|
57
|
+
artefact_export_mode
|
|
58
|
+
attribute_groups
|
|
59
|
+
custom_field_ids
|
|
60
|
+
custom_fields
|
|
61
|
+
description
|
|
62
|
+
export_templates_disabled
|
|
63
|
+
export_templates_order
|
|
64
|
+
patterns
|
|
65
|
+
project_custom_field_type_mappings
|
|
66
|
+
statuses
|
|
67
|
+
workflows
|
|
68
|
+
].freeze
|
|
69
|
+
|
|
70
|
+
RESTRICT_ON_SEND = CONFIGURATION_METHODS
|
|
71
|
+
|
|
72
|
+
def_node_matcher :type_call?, <<~PATTERN
|
|
73
|
+
(send _ :type)
|
|
74
|
+
PATTERN
|
|
75
|
+
|
|
76
|
+
def on_send(node)
|
|
77
|
+
return unless type_call?(node.receiver)
|
|
78
|
+
|
|
79
|
+
add_offense(node)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -5,4 +5,5 @@ require_relative "open_project/no_not_implemented_error"
|
|
|
5
5
|
require_relative "open_project/no_params_in_work_package_where_id"
|
|
6
6
|
require_relative "open_project/use_service_result_factory_methods"
|
|
7
7
|
require_relative "open_project/no_sleep_in_feature_specs"
|
|
8
|
+
require_relative "open_project/use_effective_type_for_configuration"
|
|
8
9
|
require_relative "open_project/use_render_mode_instead_of_primitives"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubocop-openproject
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- OpenProject GmbH
|
|
@@ -43,6 +43,7 @@ files:
|
|
|
43
43
|
- lib/rubocop/cop/open_project/no_not_implemented_error.rb
|
|
44
44
|
- lib/rubocop/cop/open_project/no_params_in_work_package_where_id.rb
|
|
45
45
|
- lib/rubocop/cop/open_project/no_sleep_in_feature_specs.rb
|
|
46
|
+
- lib/rubocop/cop/open_project/use_effective_type_for_configuration.rb
|
|
46
47
|
- lib/rubocop/cop/open_project/use_render_mode_instead_of_primitives.rb
|
|
47
48
|
- lib/rubocop/cop/open_project/use_service_result_factory_methods.rb
|
|
48
49
|
- lib/rubocop/cop/open_project_cops.rb
|
|
@@ -71,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
71
72
|
- !ruby/object:Gem::Version
|
|
72
73
|
version: '0'
|
|
73
74
|
requirements: []
|
|
74
|
-
rubygems_version: 4.0.
|
|
75
|
+
rubygems_version: 4.0.16
|
|
75
76
|
specification_version: 4
|
|
76
77
|
summary: RuboCop cops for OpenProject
|
|
77
78
|
test_files: []
|