Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion .github/workflows/lint-and-validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,30 @@ jobs:
- '**/*.tsx'
- '.github/workflows/lint-and-validate.yml'
kotlin:
- 'packages/gradle-client/**'
- 'packages/build-tools/gradle-plugin/**'
- '.github/workflows/lint-and-validate.yml'
json:
- '*.json'
- '.github/workflows/lint-and-validate.yml'
ruby:
- 'packages/build-tools/cocoapods-plugin/**'
- '.github/workflows/lint-and-validate.yml'

- name: πŸ— Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest

- name: πŸ— Setup Ruby
if: ${{ steps.filter.outputs.ruby == 'true' }}
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.0'

- name: πŸ— Install rubocop
if: ${{ steps.filter.outputs.ruby == 'true' }}
run: gem install rubocop

- name: πŸ—ƒοΈ Cache Bun and Gradle
uses: actions/cache@v4
with:
Expand All @@ -72,6 +85,10 @@ jobs:
if: ${{ steps.filter.outputs.typescript == 'true' }}
run: bun run lint-ts

- name: πŸ” Lint ruby
if: ${{ steps.filter.outputs.ruby == 'true' }}
run: bun run lint-ruby

- name: βœ… Validate JSON files
if: ${{ steps.filter.outputs.json == 'true' }}
run: bun run validate
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"validate": "bun run packages/config/src/validate.ts",
"lint-gradle-client": "./packages/build-tools/gradle-plugin/gradlew -p packages/build-tools/gradle-plugin spotlessCheck -q --no-daemon",
"lint-ts": "eslint . --ext .ts,.tsx",
"lint-ruby": "rubocop packages/build-tools/cocoapods-plugin",
"test-gradle-client": "./packages/build-tools/gradle-plugin/gradlew -p packages/build-tools/gradle-plugin test --info --no-daemon"
},
"author": "",
Expand Down
13 changes: 13 additions & 0 deletions packages/build-tools/cocoapods-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,16 @@ node_modules/
β”‚ └── {package-name}.xcframework/
└── Current/ (symlink created at build time β†’ Debug or Release)
```

### Lint

To run the linter, use the following command:

```bash
# Install rubocop if you don't have it yet
gem install rubocop
# Run
rubocop
# Or with auto-correct
rubocop -a
```
90 changes: 52 additions & 38 deletions packages/build-tools/cocoapods-plugin/lib/downloader.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# frozen_string_literal: true

require 'net/http'
require 'uri'
require 'fileutils'
require 'zip'

module CocoapodsRnrepo
# Handles artifact download and extraction for RNRepo CocoaPods integration.
class Downloader
@@repo_url = "https://packages.rnrepo.org/releases"
@repo_url = 'https://packages.rnrepo.org/releases'

def self.validate_artifact_spec(artifact_spec, required_keys)
missing_keys = required_keys.select { |key| !artifact_spec.key?(key) || artifact_spec[key].nil? }
Expand All @@ -19,7 +22,10 @@ def self.validate_artifact_spec(artifact_spec, required_keys)

def self.build_artifact_url(artifact_spec)
worklets_suffix = artifact_spec[:worklets_version] ? "-worklets#{artifact_spec[:worklets_version]}" : ''
"#{@@repo_url}/org/rnrepo/public/#{artifact_spec[:sanitized_name]}/#{artifact_spec[:version]}/#{artifact_spec[:sanitized_name]}-#{artifact_spec[:version]}-rn#{artifact_spec[:rn_version]}#{worklets_suffix}-#{artifact_spec[:configuration]}.xcframework.zip"
"#{@repo_url}/org/rnrepo/public/#{artifact_spec[:sanitized_name]}/" \
"#{artifact_spec[:version]}/#{artifact_spec[:sanitized_name]}-" \
"#{artifact_spec[:version]}-rn#{artifact_spec[:rn_version]}" \
"#{worklets_suffix}-#{artifact_spec[:configuration]}.xcframework.zip"
end

def self.build_http_client(uri, read_timeout)
Expand All @@ -31,64 +37,72 @@ def self.build_http_client(uri, read_timeout)
end

# Download file via HTTP request
# Requires: artifact_spec hash with :sanitized_name, :version, :rn_version, :configuration, :destination, :worklets_version (optional)
# Requires: artifact_spec hash with :sanitized_name, :version, :rn_version,
# :configuration, :destination, :worklets_version (optional)
# Returns: destination path if successful, nil on failure
def self.download_file(artifact_spec)
Logger.log "Preparing to download: #{artifact_spec[:package]}@#{artifact_spec[:version]}"

required_keys = [:sanitized_name, :version, :rn_version, :configuration, :destination]
required_keys = %i[sanitized_name version rn_version configuration destination]
return nil unless validate_artifact_spec(artifact_spec, required_keys)

url = build_artifact_url(artifact_spec)
Logger.log "Downloading from #{url}..."

uri = URI.parse(url)
http = build_http_client(uri, 60)

request = Net::HTTP::Get.new(uri.request_uri)

http.request(request) do |response|
if response.code.to_i == 200
File.open(artifact_spec[:destination], 'wb') do |file|
response.read_body do |chunk|
file.write(chunk)
end
end
return artifact_spec[:destination]
else
Logger.log "Failed to download #{url}: HTTP #{response.code}"
return nil
end
end
rescue => e
download_http_file(url, artifact_spec[:destination])
rescue StandardError => e
Logger.log "Error downloading #{url}: #{e.message}"
return nil
nil
end

# Unzip file to destination directory
def self.unzip_file(zip_path, destination)
Logger.log "Extracting to #{destination}..."

FileUtils.mkdir_p(destination)

Zip::File.open(zip_path) do |zip_file|
zip_file.each do |entry|
entry_path = File.join(destination, entry.name)
FileUtils.mkdir_p(File.dirname(entry_path))
zip_file.each { |entry| extract_zip_entry(destination, entry) }
end

Logger.log 'Extracted successfully'
true
rescue StandardError => e
Logger.log "Error extracting #{zip_path}: #{e.message}"
false
end

def self.download_http_file(url, destination)
uri = URI.parse(url)
http = build_http_client(uri, 60)
request = Net::HTTP::Get.new(uri.request_uri)

# Remove existing file if it exists
FileUtils.rm_f(entry_path) if File.exist?(entry_path)
http.request(request) do |response|
return handle_download_response(response, url, destination)
end
end

entry.extract(entry_path)
def self.handle_download_response(response, url, destination)
if response.code.to_i == 200
write_response_body(response, destination)
destination
else
Logger.log "Failed to download #{url}: HTTP #{response.code}"
nil
end
end

def self.write_response_body(response, destination)
File.open(destination, 'wb') do |file|
response.read_body do |chunk|
file.write(chunk)
end
end
end

Logger.log "Extracted successfully"
true
rescue => e
Logger.log "Error extracting #{zip_path}: #{e.message}"
return false
def self.extract_zip_entry(destination, entry)
entry_path = File.join(destination, entry.name)
FileUtils.mkdir_p(File.dirname(entry_path))
FileUtils.rm_f(entry_path) if File.exist?(entry_path)
entry.extract(entry_path)
end
end
end

3 changes: 2 additions & 1 deletion packages/build-tools/cocoapods-plugin/lib/gem_version.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# frozen_string_literal: true

module CocoapodsRnrepo
VERSION = '0.1.0'
end

6 changes: 4 additions & 2 deletions packages/build-tools/cocoapods-plugin/lib/logger.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# frozen_string_literal: true

module CocoapodsRnrepo
# Simple logger for RNRepo CocoaPods plugin with colored output.
class Logger
# Colored prefix for logs
def self.log_prefix
"[πŸ“¦ RNRepo]".cyan
'[πŸ“¦ RNRepo]'.cyan
end

# Log helper method
Expand All @@ -11,4 +14,3 @@ def self.log(message)
end
end
end

Loading