podrpt 1.0.0 → 1.0.2
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 +4 -4
- data/.DS_Store +0 -0
- data/CHANGELOG.md +13 -1
- data/README.md +36 -10
- data/lib/podrpt/cli.rb +47 -23
- data/lib/podrpt/configuration.rb +55 -12
- data/lib/podrpt/version.rb +1 -1
- metadata +2 -3
- data/podrpt-0.1.0.gem +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ae1f6086149bbe23d778fd9e9ea91efc5bc7b06f8d59b79d0e79f082bd7acb84
|
|
4
|
+
data.tar.gz: 1aa791ecf1d1b95f04be09ca1fd5ed075f8e22e731d9a5a41b3bc9902685f179
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: afbebced78bb8a84f55dd88c34a865a2103d1db1278d6d296a8403d788569c05b51123d130ed808af7be47a70f622b7973c6e6840d519f42966e1fd25b501b6f
|
|
7
|
+
data.tar.gz: b1e194be0f0859a264e208d943965a572b82f825ad3fba9e68bcbd4b32a0486b40173498e6e62071a379bb3311843ac4998f47a0e6d7cfd24fc17da7d4f492ae
|
data/.DS_Store
CHANGED
|
Binary file
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
-
## [1.0.
|
|
3
|
+
## [1.0.2] - 2025-09-28
|
|
4
|
+
|
|
5
|
+
- implementing dry run for testing
|
|
6
|
+
|
|
7
|
+
## [1.0.1] - 2025-09-28
|
|
4
8
|
|
|
5
9
|
- first release of podrpt with all the features so far
|
|
10
|
+
|
|
11
|
+
## [1.0.0] - 2025-09-27
|
|
12
|
+
|
|
13
|
+
- checking how the gem behaves in a project
|
|
14
|
+
|
|
15
|
+
## [0.1.0] - 2025-09-27
|
|
16
|
+
|
|
17
|
+
- test
|
data/README.md
CHANGED
|
@@ -4,38 +4,55 @@ Podrpt is a command-line tool written in Ruby to analyze and report outdated Coc
|
|
|
4
4
|
|
|
5
5
|
It leverages the native CocoaPods API for high-performance analysis, avoiding slow external process calls for version fetching.
|
|
6
6
|
|
|
7
|
-
Features
|
|
8
|
-
- Fast Analysis
|
|
7
|
+
**Features**
|
|
8
|
+
- **Fast Analysis**: Uses the native CocoaPods gem API instead of shelling out to pod search.
|
|
9
9
|
|
|
10
|
-
- Outdated Pod Detection
|
|
10
|
+
- **Outdated Pod Detection**: Compares versions in your **Podfile.lock** against the latest public releases.
|
|
11
11
|
|
|
12
|
-
- Risk Assessment
|
|
12
|
+
- **Risk Assessment**: Assign custom risk scores and owner teams to dependencies via a PodsRisk.yaml file.
|
|
13
13
|
|
|
14
|
-
- Dependency Filtering
|
|
14
|
+
- **Dependency Filtering**: Use an PodsAllowlist.yaml file to filter out transitive dependencies and focus only on the pods you directly manage.
|
|
15
15
|
|
|
16
|
-
- Slack Notifications
|
|
16
|
+
- **Slack Notifications**: Delivers a clean, formatted report directly to a Slack channel, perfect for CI/CD pipelines.
|
|
17
17
|
|
|
18
|
-
- CI/CD Focused
|
|
18
|
+
- **CI/CD Focused**: Designed to run in automated environments without leaving behind unnecessary file artifacts.
|
|
19
19
|
|
|
20
20
|
- Interactive Setup: A simple init command to generate all necessary configuration files.-
|
|
21
21
|
|
|
22
22
|
## Installation
|
|
23
23
|
|
|
24
24
|
Add this line to your application's Gemfile:
|
|
25
|
-
|
|
25
|
+
```ruby
|
|
26
|
+
gem 'podrpt', '~> 1.0.0'
|
|
27
|
+
```
|
|
26
28
|
|
|
27
29
|
And then execute:
|
|
30
|
+
```sh
|
|
28
31
|
bundle install
|
|
32
|
+
```
|
|
29
33
|
|
|
30
34
|
## Setup
|
|
31
35
|
After installing the gem, you need to generate the configuration files in your project's root directory. Navigate to your iOS project's root folder and run the interactive setup command:
|
|
32
36
|
|
|
37
|
+
And then execute:
|
|
38
|
+
```sh
|
|
33
39
|
bundle exec podrpt init
|
|
40
|
+
```
|
|
34
41
|
|
|
35
42
|
This command will:
|
|
36
43
|
|
|
37
|
-
1 Create a sample PodsRisk.yaml file for defining risk scores.
|
|
38
|
-
|
|
44
|
+
1 Create a sample **PodsRisk.yaml** file for defining risk scores.
|
|
45
|
+
```yaml
|
|
46
|
+
default:
|
|
47
|
+
risk: 500
|
|
48
|
+
owners: []
|
|
49
|
+
pods:
|
|
50
|
+
XPTO:
|
|
51
|
+
risk: 100
|
|
52
|
+
owners: ['core-team']
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
2 Create a sample **PodsAllowlist.yaml** file for filtering dependencies.
|
|
39
56
|
3 Prompt you for your Slack Incoming Webhook URL and save it securely in a .podrpt.yml file (which should be added to your .gitignore).
|
|
40
57
|
|
|
41
58
|
After running init, customize the generated .yaml files to fit your project's needs.
|
|
@@ -43,7 +60,16 @@ After running init, customize the generated .yaml files to fit your project's ne
|
|
|
43
60
|
## Usage
|
|
44
61
|
To run an analysis and send a report to Slack, simply execute the run command:
|
|
45
62
|
|
|
63
|
+
And then execute:
|
|
64
|
+
```sh
|
|
46
65
|
bundle exec podrpt run
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
If you want to see what will be sent and what URL is configured, use this command:
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
bundle exec podrpt run --dry-run
|
|
72
|
+
```
|
|
47
73
|
|
|
48
74
|
The report will only include outdated pods by default.
|
|
49
75
|
|
data/lib/podrpt/cli.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# lib/podrpt/cli.rb
|
|
1
2
|
module Podrpt
|
|
2
3
|
class CLI
|
|
3
4
|
def self.start(args)
|
|
@@ -10,7 +11,7 @@ module Podrpt
|
|
|
10
11
|
when '--version', '-v'
|
|
11
12
|
puts Podrpt::VERSION
|
|
12
13
|
else
|
|
13
|
-
puts "
|
|
14
|
+
puts "Comando desconhecido: '#{command}'. Use 'run' ou 'init'."
|
|
14
15
|
exit 1
|
|
15
16
|
end
|
|
16
17
|
end
|
|
@@ -18,24 +19,48 @@ module Podrpt
|
|
|
18
19
|
private
|
|
19
20
|
|
|
20
21
|
def self.initialize_configuration
|
|
21
|
-
puts "🚀
|
|
22
|
-
Podrpt::Configuration.create_risk_file
|
|
23
|
-
Podrpt::Configuration.create_allowlist_file
|
|
22
|
+
puts "🚀 Iniciando a configuração do Podrpt..."
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
pod_names_to_configure = []
|
|
25
|
+
project_dir = Dir.pwd
|
|
26
|
+
lockfile_path = File.join(project_dir, 'Podfile.lock')
|
|
27
|
+
|
|
28
|
+
if File.exist?(lockfile_path)
|
|
29
|
+
puts "📄 `Podfile.lock` encontrado. Analisando pods para pré-popular os arquivos..."
|
|
30
|
+
begin
|
|
31
|
+
# Analisa o lockfile para obter a lista completa de pods externos
|
|
32
|
+
analyzer = Podrpt::LockfileAnalyzer.new(project_dir)
|
|
33
|
+
all_pods_versions = analyzer.pod_versions
|
|
34
|
+
classified_pods = analyzer.classify_pods
|
|
35
|
+
|
|
36
|
+
# Filtramos apenas para pods que não são de desenvolvimento local
|
|
37
|
+
external_pods_filter = classified_pods[:spec_repo].dup
|
|
38
|
+
external_pods_filter -= classified_pods[:dev_path]
|
|
39
|
+
|
|
40
|
+
pods_to_configure = all_pods_versions.slice(*external_pods_filter.to_a)
|
|
41
|
+
pod_names_to_configure = pods_to_configure.keys
|
|
42
|
+
|
|
43
|
+
rescue => e
|
|
44
|
+
puts "⚠️ Erro ao analisar o `Podfile.lock`: #{e.message}. Os arquivos serão criados com exemplos."
|
|
45
|
+
end
|
|
30
46
|
else
|
|
31
|
-
|
|
47
|
+
puts "⚠️ `Podfile.lock` não encontrado. Os arquivos serão criados com exemplos."
|
|
32
48
|
end
|
|
33
|
-
puts "\nSetup complete! Edit the .yaml files and run 'podrpt run'."
|
|
34
|
-
end
|
|
35
49
|
|
|
50
|
+
# Cria os arquivos de configuração, passando a lista de pods encontrados
|
|
51
|
+
Podrpt::Configuration.create_allowlist_file(pod_names: pod_names_to_configure)
|
|
52
|
+
Podrpt::Configuration.create_risk_file(pod_names: pod_names_to_configure)
|
|
53
|
+
|
|
54
|
+
puts "\nAgora, por favor, informe a URL do seu Incoming Webhook do Slack:"
|
|
55
|
+
print "> "
|
|
56
|
+
url = $stdin.gets.chomp
|
|
57
|
+
Podrpt::Configuration.save_slack_url(url)
|
|
58
|
+
puts "\nConfiguração concluída! Edite os arquivos .yaml conforme necessário e execute 'podrpt run'."
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# O método `run_reporter` e seus auxiliares permanecem os mesmos da última versão funcional
|
|
36
62
|
def self.run_reporter(args)
|
|
37
63
|
options = parse_run_options(args)
|
|
38
|
-
|
|
39
64
|
analyzer = Podrpt::LockfileAnalyzer.new(options.project_dir)
|
|
40
65
|
all_pods_versions = analyzer.pod_versions
|
|
41
66
|
classified_pods = analyzer.classify_pods
|
|
@@ -46,7 +71,7 @@ module Podrpt
|
|
|
46
71
|
|
|
47
72
|
allowlist_config = load_allowlist(File.join(options.project_dir, options.allowlist_yaml))
|
|
48
73
|
pods_for_report = apply_allowlist_filter(current_pods, allowlist_config)
|
|
49
|
-
puts "[podrpt]
|
|
74
|
+
puts "[podrpt] Totais lock: #{all_pods_versions.size} | Pré-allowlist: #{current_pods.size} | Relatório final: #{pods_for_report.size}"
|
|
50
75
|
options.total_pods_count = pods_for_report.size
|
|
51
76
|
|
|
52
77
|
risk_config = load_risk_config(File.join(options.project_dir, options.risk_yaml))
|
|
@@ -69,7 +94,7 @@ module Podrpt
|
|
|
69
94
|
|
|
70
95
|
reporter = Podrpt::ReportGenerator.new(final_analysis, options)
|
|
71
96
|
report_text = reporter.build_report_text
|
|
72
|
-
|
|
97
|
+
|
|
73
98
|
Podrpt::SlackNotifier.notify(options.slack_webhook_url, report_text, dry_run: options.dry_run)
|
|
74
99
|
end
|
|
75
100
|
|
|
@@ -83,18 +108,17 @@ module Podrpt
|
|
|
83
108
|
slack_webhook_url: ENV['SLACK_WEBHOOK_URL'] || Podrpt::Configuration.load_slack_url,
|
|
84
109
|
dry_run: false
|
|
85
110
|
)
|
|
86
|
-
|
|
87
111
|
OptionParser.new do |opts|
|
|
88
112
|
opts.banner = "Usage: podrpt run [options]"
|
|
89
|
-
opts.on("--project-dir DIR", "
|
|
90
|
-
opts.on("--slack-webhook-url URL", "URL Webhook (
|
|
91
|
-
opts.on("--show-all", "
|
|
92
|
-
opts.on("--sync-risk-yaml", "
|
|
93
|
-
opts.on("--dry-run", "
|
|
113
|
+
opts.on("--project-dir DIR", "Diretório do projeto") { |v| options.project_dir = v }
|
|
114
|
+
opts.on("--slack-webhook-url URL", "URL do Webhook (sobrescreve config)") { |v| options.slack_webhook_url = v }
|
|
115
|
+
opts.on("--show-all", "Mostra todos os pods") { |v| options.only_outdated = false }
|
|
116
|
+
opts.on("--sync-risk-yaml", "Sincroniza PodsRisk.yaml") { |v| options.sync_risk_yaml = v }
|
|
117
|
+
opts.on("--dry-run", "Simula o envio para o Slack, printando o payload no terminal") { |v| options.dry_run = v }
|
|
94
118
|
end.parse!(args)
|
|
95
119
|
|
|
96
120
|
unless options.slack_webhook_url || options.dry_run
|
|
97
|
-
puts "❌
|
|
121
|
+
puts "❌ ERRO: URL do Slack não configurada. Rode 'podrpt init' ou use --dry-run."
|
|
98
122
|
exit 1
|
|
99
123
|
end
|
|
100
124
|
options
|
|
@@ -113,7 +137,7 @@ module Podrpt
|
|
|
113
137
|
def self.sync_risk_yaml(path, pods, config)
|
|
114
138
|
pods.keys.sort_by(&:downcase).each { |name| config['pods'][name] ||= config['default'].dup }
|
|
115
139
|
File.write(path, config.to_yaml)
|
|
116
|
-
puts "[podrpt] PodsRisk.yaml
|
|
140
|
+
puts "[podrpt] PodsRisk.yaml sincronizado com #{config['pods'].size} pods."
|
|
117
141
|
end
|
|
118
142
|
def self.is_outdated(current, latest); latest && !latest.empty? && Podrpt::VersionComparer.compare(latest, current) > 0; end
|
|
119
143
|
end
|
data/lib/podrpt/configuration.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# lib/podrpt/configuration.rb
|
|
1
2
|
require 'yaml'
|
|
2
3
|
|
|
3
4
|
module Podrpt
|
|
@@ -10,7 +11,7 @@ module Podrpt
|
|
|
10
11
|
config = File.exist?(CONFIG_FILE) ? YAML.load_file(CONFIG_FILE) || {} : {}
|
|
11
12
|
config['slack_webhook_url'] = url
|
|
12
13
|
File.write(CONFIG_FILE, config.to_yaml)
|
|
13
|
-
puts "✅ Slack
|
|
14
|
+
puts "✅ URL do Slack salva em #{CONFIG_FILE}"
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
def self.load_slack_url
|
|
@@ -18,21 +19,63 @@ module Podrpt
|
|
|
18
19
|
YAML.load_file(CONFIG_FILE)['slack_webhook_url']
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
def self.create_risk_file
|
|
22
|
+
def self.create_risk_file(pod_names: [])
|
|
22
23
|
return if File.exist?(RISK_FILE)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
|
|
25
|
+
bands_config = { 'green_max' => 400, 'yellow_max' => 700 }
|
|
26
|
+
default_config = { 'owners' => [], 'risk' => 500 }
|
|
27
|
+
|
|
28
|
+
pods_hash = {}
|
|
29
|
+
if pod_names.empty?
|
|
30
|
+
puts "⚠️ Nenhum pod encontrado para pré-popular. Criando arquivo de risco com um exemplo."
|
|
31
|
+
pods_hash['Firebase'] = { 'owners' => ['core-team'], 'risk' => 100 }
|
|
32
|
+
else
|
|
33
|
+
pod_names.sort_by(&:downcase).each do |name|
|
|
34
|
+
pods_hash[name] = YAML.load(default_config.to_yaml)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
final_structure = {
|
|
39
|
+
'bands' => bands_config,
|
|
40
|
+
'default' => default_config,
|
|
41
|
+
'pods' => pods_hash
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
File.write(RISK_FILE, final_structure.to_yaml)
|
|
45
|
+
puts "✅ Arquivo '#{RISK_FILE}' criado e pré-populado com #{pods_hash.count} pods."
|
|
29
46
|
end
|
|
30
47
|
|
|
31
|
-
def self.create_allowlist_file
|
|
48
|
+
def self.create_allowlist_file(pod_names: [])
|
|
32
49
|
return if File.exist?(ALLOWLIST_FILE)
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
50
|
+
|
|
51
|
+
header = <<~YAML
|
|
52
|
+
# The allowlist is used to filter transitive dependencies (sub-dependencies)
|
|
53
|
+
# and focus only on the pods you manage directly in your Podfile.
|
|
54
|
+
#
|
|
55
|
+
# For each "group" (e.g., Firebase), only the pods listed here will appear in the report.
|
|
56
|
+
# Pods that don't belong to any group (e.g., Alamofire) will appear by default.
|
|
57
|
+
#
|
|
58
|
+
# Uncomment and adjust the examples below, or create your own groups.
|
|
59
|
+
YAML
|
|
60
|
+
|
|
61
|
+
example_content = {
|
|
62
|
+
'allowlist' => {
|
|
63
|
+
'Firebase' => ['FirebaseAnalytics', 'FirebaseCrashlytics']
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
project_pods_comment = pod_names.sort_by(&:downcase).map { |name| "# - #{name}" }.join("\n")
|
|
68
|
+
|
|
69
|
+
final_content = header + example_content.to_yaml
|
|
70
|
+
unless pod_names.empty?
|
|
71
|
+
final_content += "\n# --- Pods Encontrados no seu Projeto (descomente para usar) ---\n"
|
|
72
|
+
final_content += "# allowlist:\n"
|
|
73
|
+
final_content += "# MeuGrupo:\n"
|
|
74
|
+
final_content += project_pods_comment
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
File.write(ALLOWLIST_FILE, final_content)
|
|
78
|
+
puts "✅ Arquivo de exemplo '#{ALLOWLIST_FILE}' criado."
|
|
36
79
|
end
|
|
37
80
|
end
|
|
38
81
|
end
|
data/lib/podrpt/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: podrpt
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Alves
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-09-
|
|
11
|
+
date: 2025-09-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: cocoapods
|
|
@@ -92,7 +92,6 @@ files:
|
|
|
92
92
|
- lib/podrpt/version.rb
|
|
93
93
|
- lib/podrpt/version_comparer.rb
|
|
94
94
|
- lib/podrpt/version_fetcher.rb
|
|
95
|
-
- podrpt-0.1.0.gem
|
|
96
95
|
- sig/podrpt.rbs
|
|
97
96
|
homepage: https://github.com/swiftdrew/podrpt
|
|
98
97
|
licenses:
|
data/podrpt-0.1.0.gem
DELETED
|
Binary file
|