fastlane-plugin-stream_actions 0.4.7 → 0.4.8

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: '055284ce7665f25768ac9f5fae0b7e09c35b971f9dd7b1b15f54eb90d257d638'
4
- data.tar.gz: bf845ed3db8e5b1cff88acc700190ab9735e0349dbde1bc1f2d31fc31644c3d1
3
+ metadata.gz: c541f74e6e0f551a8b1a2b4b19709a52c84a5e73e7dfb2d5b2dd0a4e4be33fa5
4
+ data.tar.gz: b3a06af31fbf2f66fee224c99e0c83cf9926fde456a2d4c26d2e71faf0bf9373
5
5
  SHA512:
6
- metadata.gz: 38f2c907628a4ea73b7150f91106f1f89eb5e2d9913ba7fefc4c2f61116a48356556c708e6a2ce107196b422cd8f1ad7d8f6f175e969bd9d052bd51cf600e5d2
7
- data.tar.gz: 3c902fe10e1676a649653ae6e35f91b1c22665fb06a0f9744a8e4e37f48aaf2dc0e06fe2107e1b830c7e9b362b6f4051e6c5574769125ab9dca4a858b689f0ac
6
+ metadata.gz: 201aadf11567df58b11f6294bc84575d2f0a13c296ce71d6de46487c9f46cee7304e08ca88982f0b2fcf8758fe0dc4a6a99ea186c897772d9293cd279f1877a9
7
+ data.tar.gz: 831a890635a955cc88da0e8d14f1dfc0cc1ca17229a063a90cdfcc5f2053d59c7ccfc645d9e113efcebcf349ae0d08bd5ef2a30178c6d1d980b891422a67e928
@@ -0,0 +1,122 @@
1
+ module Fastlane
2
+ module Actions
3
+ class LintSwiftPackageAction < Action
4
+ def self.run(params)
5
+ path = params[:swift_package_path]
6
+ UI.user_error!("Package.swift not found at path: #{path}") unless File.exist?(path)
7
+
8
+ dependencies = package_declarations(File.read(path))
9
+ violations = dependencies.flat_map { |dependency| dependency_violations(dependency) }
10
+ violations += duplicate_violations(dependencies)
11
+
12
+ if violations.any?
13
+ UI.user_error!("Package.swift contains #{violations.size} dependency issue(s):\n#{violations.join("\n")}")
14
+ end
15
+
16
+ UI.success("Package.swift dependencies look good 🚀")
17
+ end
18
+
19
+ def self.dependency_violations(dependency)
20
+ body = dependency[:body]
21
+ violations = []
22
+ if body =~ /\bbranch:/ || body.include?('.branch(')
23
+ violations << violation(dependency, 'branch-based dependency — pin it with `from:` or `exact:` instead')
24
+ end
25
+ if body =~ /\brevision:/ || body.include?('.revision(')
26
+ violations << violation(dependency, 'revision-pinned dependency — pin it with `from:` or `exact:` instead')
27
+ end
28
+ if body.include?('..<') || body =~ /"\s*\.\.\.\s*"/ || body.include?('.upToNextMinor(')
29
+ violations << violation(dependency, 'version-range dependency — pin it with `from:` or `exact:` instead')
30
+ end
31
+ if body =~ /\bpath:/
32
+ violations << violation(dependency, 'local path dependency — it will not resolve for package consumers')
33
+ end
34
+ if dependency[:url] && dependency[:url] !~ %r{\Ahttps://}
35
+ violations << violation(dependency, 'insecure or non-https url — use `https://`')
36
+ end
37
+ if violations.empty? && body !~ /\b(from|exact):/ && !body.include?('.exact(') && !body.include?('.upToNextMajor(')
38
+ violations << violation(dependency, 'missing version requirement — pin it with `from:` or `exact:`')
39
+ end
40
+ violations
41
+ end
42
+
43
+ def self.duplicate_violations(dependencies)
44
+ dependencies
45
+ .select { |dependency| dependency[:url] }
46
+ .group_by { |dependency| dependency[:url].downcase.sub(/\.git\z/, '') }
47
+ .values
48
+ .select { |group| group.size > 1 }
49
+ .map do |group|
50
+ lines = group.map { |dependency| dependency[:line] }.join(', ')
51
+ "- #{group.first[:url]} (lines #{lines}): duplicate dependency"
52
+ end
53
+ end
54
+
55
+ def self.violation(dependency, message)
56
+ location = dependency[:url] ? "#{dependency[:url]} (line #{dependency[:line]})" : "line #{dependency[:line]}"
57
+ "- #{location}: #{message}"
58
+ end
59
+
60
+ def self.package_declarations(content)
61
+ declarations = []
62
+ offset = 0
63
+ while (start = content.index('.package(', offset))
64
+ body_start = start + 9 # '.package('.length
65
+ index = body_start
66
+ depth = 1
67
+ in_string = false
68
+ while index < content.length && depth > 0
69
+ char = content[index]
70
+ if in_string
71
+ in_string = false if char == '"' && content[index - 1] != '\\'
72
+ else
73
+ case char
74
+ when '"' then in_string = true
75
+ when '(' then depth += 1
76
+ when ')' then depth -= 1
77
+ end
78
+ end
79
+ index += 1
80
+ end
81
+ body = content[body_start...(index - 1)]
82
+ declarations << {
83
+ body: body,
84
+ url: body[/url:\s*"([^"]+)"/, 1],
85
+ line: content[0..start].count("\n") + 1
86
+ }
87
+ offset = index
88
+ end
89
+ declarations
90
+ end
91
+
92
+ #####################################################
93
+ # @!group Documentation
94
+ #####################################################
95
+
96
+ def self.description
97
+ 'Scans Package.swift for common mistakes in dependency declarations'
98
+ end
99
+
100
+ def self.details
101
+ 'Fails if any dependency is declared via branch, revision, version range, local path, ' \
102
+ 'insecure url, or is duplicated. All dependencies should be pinned with `from:` or `exact:`.'
103
+ end
104
+
105
+ def self.available_options
106
+ [
107
+ FastlaneCore::ConfigItem.new(
108
+ key: :swift_package_path,
109
+ description: 'The path to your project Package.swift',
110
+ is_string: true,
111
+ default_value: './Package.swift',
112
+ optional: false
113
+ )
114
+ ]
115
+ end
116
+
117
+ def self.is_supported?(platform)
118
+ true
119
+ end
120
+ end
121
+ end
122
+ end
@@ -18,8 +18,12 @@ module Fastlane
18
18
  changes << line
19
19
  end
20
20
 
21
- UI.user_error!("No changelog found for #{params[:version]}") unless changes.length > 0
22
- UI.success("Changelog for #{params[:version]}: \n#{changes}")
21
+ if changes.strip.empty?
22
+ changes = params[:default_changes]
23
+ UI.important("No changelog found for #{params[:version]}, using default: \n#{changes}")
24
+ else
25
+ UI.success("Changelog for #{params[:version]}: \n#{changes}")
26
+ end
23
27
  changes
24
28
  end
25
29
 
@@ -47,6 +51,13 @@ module Fastlane
47
51
  is_string: true,
48
52
  default_value: './CHANGELOG.md',
49
53
  optional: true
54
+ ),
55
+ FastlaneCore::ConfigItem.new(
56
+ key: :default_changes,
57
+ description: 'The default changelog entry if no changes provided',
58
+ is_string: true,
59
+ default_value: '- Bug fixes and improvements',
60
+ optional: true
50
61
  )
51
62
  ]
52
63
  end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module StreamActions
3
- VERSION = '0.4.7'
3
+ VERSION = '0.4.8'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-stream_actions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.7
4
+ version: 0.4.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - GetStream
@@ -240,6 +240,7 @@ files:
240
240
  - lib/fastlane/plugin/stream_actions/actions/git_status.rb
241
241
  - lib/fastlane/plugin/stream_actions/actions/install_ios_runtime.rb
242
242
  - lib/fastlane/plugin/stream_actions/actions/is_check_required.rb
243
+ - lib/fastlane/plugin/stream_actions/actions/lint_swift_package.rb
243
244
  - lib/fastlane/plugin/stream_actions/actions/merge_main_to_develop.rb
244
245
  - lib/fastlane/plugin/stream_actions/actions/merge_release_to_main.rb
245
246
  - lib/fastlane/plugin/stream_actions/actions/next_pr_number.rb