20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
# File 'lib/feature_pack.rb', line 20
def self.setup(features_path:)
raise 'FeaturePack already setup!' if defined?(@@setup_executed_flag)
@@path = Pathname.new(__dir__)
load @@path.join('feature_pack/error.rb')
@@features_path = Pathname.new(features_path)
raise "Invalid features_path: '#{@@features_path}'" if @@features_path.nil?
raise "Inexistent features_path: '#{@@features_path}'" unless Dir.exist?(@@features_path)
@@groups_controllers_paths = []
@@features_controllers_paths = []
@@ignored_paths = Dir.glob("#{@@features_path}/[!]*/")
@@javascript_files_paths = Dir.glob("#{@@features_path}/[!_]*/**/*.js")
.map { |js_path| js_path.sub(/^#{Regexp.escape(@@features_path.to_s)}\//, '') }.to_a
ATTR_READERS.each { |attr| define_singleton_method(attr) { class_variable_get("@@#{attr}") } }
@@ignored_paths << @@path.join('feature_pack/feature_pack_routes.rb')
raise "No Groups found in: '#{@@features_path}'" if Dir.glob("#{@@features_path}/[!_]*/").empty?
@@groups = Dir.glob("#{@@features_path}/[!_]*/").map do |group_path|
relative_path = Pathname.new(group_path)
base_path = File.basename(group_path, File::SEPARATOR)
routes_file = File.exist?(File.join(group_path, GROUP_METADATA_DIRECTORY, 'routes.rb')) ? File.join(base_path, GROUP_METADATA_DIRECTORY, 'routes') : nil
@@groups_controllers_paths << File.join(group_path, GROUP_METADATA_DIRECTORY, CONTROLLER_FILE_NAME)
raise "Group '#{base_path}' does not have a valid ID" if base_path.scan(GROUP_ID_PATTERN).empty?
group = OpenStruct.new(
id: base_path.scan(GROUP_ID_PATTERN).first.delete_suffix('_'),
name: base_path.gsub(GROUP_ID_PATTERN, '').to_sym,
metadata_path: @@features_path.join(group_path, GROUP_METADATA_DIRECTORY),
relative_path: relative_path,
base_dir: File.basename(relative_path, File::SEPARATOR),
routes_file: routes_file,
features: [],
manifest: YAML.load_file(File.join(group_path, GROUP_METADATA_DIRECTORY, MANIFEST_FILE_NAME)).deep_symbolize_keys
)
def group.feature(feature_name) = features.find { |p| p.name.eql?(feature_name) }
def group.views_path = "#{base_dir}/#{GROUP_METADATA_DIRECTORY}/views"
def group.view(view_name) = "#{base_dir}/#{GROUP_METADATA_DIRECTORY}/views/#{view_name}"
def group.javascript_module(javascript_file_name) = "#{base_dir}/#{GROUP_METADATA_DIRECTORY}/javascript/#{javascript_file_name}"
group
end
@@groups.each do |group|
Dir.glob("#{group.relative_path}[!_]*/").each do |feature_path|
absolute_path = @@features_path.join(feature_path)
relative_path = Pathname.new(feature_path)
base_path = File.basename(feature_path, File::SEPARATOR)
feature_name = base_path.gsub(FEATURE_ID_PATTERN, '').to_sym
routes_file_path = relative_path.join('routes.rb')
@@ignored_paths << routes_file_path
@@features_controllers_paths << relative_path.join(CONTROLLER_FILE_NAME)
@@ignored_paths << relative_path.join(CONTROLLER_FILE_NAME)
raise "Resource '#{relative_path}' does not have a valid ID" if base_path.scan(FEATURE_ID_PATTERN).empty?
feature_sub_path = relative_path.sub(/^#{Regexp.escape(@@features_path.to_s)}\//, '')
feature = OpenStruct.new(
id: base_path.scan(FEATURE_ID_PATTERN).first.delete_suffix('_'),
name: feature_name,
group: group,
absolute_path: absolute_path,
relative_path: relative_path,
sub_path: feature_sub_path,
routes_file_path: routes_file_path,
routes_file: feature_sub_path.join('routes'),
views_absolute_path: absolute_path.join('views'),
views_relative_path: relative_path.sub(/^#{Regexp.escape(@@features_path.to_s)}\//, '').join('views'),
javascript_relative_path: relative_path.sub(/^#{Regexp.escape(@@features_path.to_s)}\//, '').join('javascript'),
manifest: YAML.load_file(File.join(feature_path, MANIFEST_FILE_NAME)).deep_symbolize_keys
)
def feature.class_name = "FeaturePack::#{group.name.name.camelize}::#{name.name.camelize}"
def feature.namespace = class_name.constantize
feature.manifest.fetch(:const_aliases, []).each do |alias_data|
alias_method_name, alias_const_name = alias_data.first
feature.define_singleton_method(alias_method_name) { "#{class_name}::#{alias_const_name}".constantize }
end
def feature.view(view_name) = "#{views_relative_path}/#{view_name}"
def feature.javascript_module(javascript_file_name) = "#{javascript_relative_path}/#{javascript_file_name}"
group.features << feature
end
end
@@setup_executed_flag = true
end
|