-
Notifications
You must be signed in to change notification settings - Fork 416
Expand file tree
/
Copy pathDangerfile
More file actions
127 lines (97 loc) · 4.07 KB
/
Dangerfile
File metadata and controls
127 lines (97 loc) · 4.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
danger.import_dangerfile(github: 'RevenueCat/Dangerfile')
require 'pathname'
require 'set'
EXCLUDED_SWIFT_PATH_PREFIXES = [
'Tests/APITesters/'
].freeze
# Check for submodules
submodules = `git submodule status`.strip
if !submodules.empty?
fail("This repository should not contain any submodules. When using Swift Package Manager, developers will get a resolution error because SPM cannot access private submodules.")
end
# Check for new Swift files that aren't added to RevenueCat.xcodeproj
def normalize_path(path)
Pathname(path).cleanpath.to_s.sub(%r{\A\./}, '')
end
def relevant_swift_file?(path)
path = normalize_path(path)
return false unless path.end_with?('.swift')
return false if EXCLUDED_SWIFT_PATH_PREFIXES.any? { |prefix| path.start_with?(prefix) }
in_project_sources = path.start_with?('Sources/') || path.start_with?('RevenueCatUI/')
in_tests = path.start_with?('Tests/')
in_project_sources || in_tests
end
def project_swift_file_paths(project_file)
require 'xcodeproj'
project = Xcodeproj::Project.open(project_file)
root = Pathname.pwd
project.files
.map { |file| file.real_path if file.path }
.compact
.select { |path| path.extname == '.swift' }
.map { |path| normalize_path(path.cleanpath.relative_path_from(root).to_s) }
.to_set
rescue LoadError
warn("xcodeproj gem not available; skipping RevenueCat.xcodeproj sync check")
nil
rescue StandardError => e
warn("Unable to read #{project_file}: #{e.message}")
nil
end
def check_swift_files_in_project
project_file = 'RevenueCat.xcodeproj'
unless File.exist?(project_file)
warn("RevenueCat.xcodeproj not found")
return
end
project_swift_files = project_swift_file_paths(project_file)
return if project_swift_files.nil?
added_swift_files = git.added_files
.select { |file| relevant_swift_file?(file) }
.map { |file| normalize_path(file) }
deleted_swift_files = git.deleted_files
.select { |file| relevant_swift_file?(file) }
.map { |file| normalize_path(file) }
missing_files = added_swift_files.reject { |file| project_swift_files.include?(file) }
lingering_references = deleted_swift_files.select { |file| project_swift_files.include?(file) }
return if missing_files.empty? && lingering_references.empty?
message = "**`RevenueCat.xcodeproj` is out of sync.**\n"
unless missing_files.empty?
message += "\nThe following Swift files were added but are missing from `RevenueCat.xcodeproj`:\n"
missing_files.each { |file| message += "• `#{file}`\n" }
end
unless lingering_references.empty?
message += "\nThe following Swift files were deleted but still referenced in `RevenueCat.xcodeproj`:\n"
lingering_references.each { |file| message += "• `#{file}`\n" }
end
message += "\nTo fix: open `RevenueCat.xcodeproj` in Xcode, add/remove the files above in the appropriate target. "
message += "Check where similar files in the same directory are assigned if you're unsure which target to use."
warn(message)
end
check_swift_files_in_project
# Check for new public enums in Swift files
def check_for_public_enums
swift_files = (git.added_files + git.modified_files)
.select { |file| file.start_with?('Sources/') || file.start_with?('RevenueCatUI/') }
.select { |file| file.end_with?('.swift') }
.select { |file| File.exist?(file) }
public_enum_pattern = /^\+\s*public\s+enum\s+/
spi_public_enum_pattern = /@_spi\([^)]*\)\s*public\s+enum/
files_with_public_enums = []
swift_files.each do |file|
diff = git.diff_for_file(file)
next unless diff
diff.patch.each_line do |line|
if line.match?(public_enum_pattern) && !line.match?(spi_public_enum_pattern)
files_with_public_enums << file
break
end
end
end
return if files_with_public_enums.empty?
message = "Public enums should not be added. Consider using a struct with static properties or an @objc enum instead.\n\n"
message += "The following files contain new public enums:\n"
files_with_public_enums.each { |file| message += "• #{file}\n" }
warn(message)
end
check_for_public_enums