Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add strings minification command #45

Merged
merged 1 commit into from
Dec 25, 2024
Merged
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
99 changes: 99 additions & 0 deletions lib/commands/autofixes/minify_strings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
require 'dry/cli'
require 'xcodeproj'

module EmergeCLI
module Commands
module Autofixes
class MinifyStrings < EmergeCLI::Commands::GlobalOptions
desc 'Minify strings in the app'

option :path, type: :string, required: true, desc: 'Path to the xcarchive'

# Constants
SCRIPT_NAME = 'EmergeTools Minify Strings'.freeze
ENABLE_USER_SCRIPT_SANDBOXING = 'ENABLE_USER_SCRIPT_SANDBOXING'.freeze
STRINGS_FILE_OUTPUT_ENCODING = 'STRINGS_FILE_OUTPUT_ENCODING'.freeze
STRINGS_FILE_OUTPUT_ENCODING_VALUE = 'UTF-8'.freeze
SCRIPT_CONTENT = %{import os
import json
from multiprocessing.pool import ThreadPool

def minify(file_path):
os.system(f"plutil -convert json '{file_path}'")
new_content = ''
try:
with open(file_path, 'r') as input_file:
data = json.load(input_file)

for key, value in data.items():
fixed_key = json.dumps(key, ensure_ascii=False).encode('utf8').decode()
fixed_value = json.dumps(value, ensure_ascii=False).encode('utf8').decode()
new_line = f'{fixed_key} = {fixed_value};\\n'
new_content += new_line

with open(file_path, 'w') as output_file:
output_file.write(new_content)
except:
return

file_extension = '.strings'
stringFiles = []

for root, _, files in os.walk(os.environ['BUILT_PRODUCTS_DIR'], followlinks=True):
for filename in files:
if filename.endswith(file_extension):
input_path = os.path.join(root, filename)
stringFiles.append(input_path)

# create a thread pool
with ThreadPool() as pool:
pool.map(minify, stringFiles)
}.freeze

def call(**options)
@options = options
before(options)

raise 'Path must be an xcodeproj' unless @options[:path].end_with?('.xcodeproj')
raise 'Path does not exist' unless File.exist?(@options[:path])

Sync do
project = Xcodeproj::Project.open(@options[:path])

project.targets.each do |target|
target.build_configurations.each do |config|
enable_user_script_sandboxing(config)
set_output_encoding(config)
end

add_run_script(target)
end

project.save
end
end

private

def enable_user_script_sandboxing(config)
Logger.info "Enabling user script sandboxing for #{config.name}"
config.build_settings[ENABLE_USER_SCRIPT_SANDBOXING] = 'NO'
end

def set_output_encoding(config)
Logger.info "Setting output encoding for #{config.name}"
config.build_settings[STRINGS_FILE_OUTPUT_ENCODING] = STRINGS_FILE_OUTPUT_ENCODING_VALUE
end

def add_run_script(target)
phase = target.shell_script_build_phases.find { |item| item.name == SCRIPT_NAME }
return unless phase.nil?
Logger.info "Creating script '#{SCRIPT_NAME}'"
phase = target.new_shell_script_build_phase(SCRIPT_NAME)
phase.shell_script = SCRIPT_CONTENT
phase.shell_path = `which python3`.strip
end
end
end
end
end
5 changes: 5 additions & 0 deletions lib/emerge_cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
require_relative 'commands/order_files/validate_xcode_project'
require_relative 'commands/upload/build'
require_relative 'commands/build_distribution/validate_app'
require_relative 'commands/autofixes/minify_strings'

require_relative 'reaper/ast_parser'
require_relative 'reaper/code_deleter'
Expand Down Expand Up @@ -66,6 +67,10 @@ module EmergeCLI
register 'build-distribution' do |prefix|
prefix.register 'validate-app', Commands::BuildDistribution::ValidateApp
end

register 'autofix' do |prefix|
prefix.register 'minify-strings', Commands::Autofixes::MinifyStrings
end
end

# By default the log level is INFO, but can be overridden by the --debug flag
Expand Down
68 changes: 68 additions & 0 deletions test/commands/autofixes/minify_strings_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
require 'test_helper'

module EmergeCLI
module Commands
module Autofixes
class MinifyStringsTest < Minitest::Test
SCRIPT_NAME = 'EmergeTools Minify Strings'.freeze
ENABLE_USER_SCRIPT_SANDBOXING = 'ENABLE_USER_SCRIPT_SANDBOXING'.freeze
STRINGS_FILE_OUTPUT_ENCODING = 'STRINGS_FILE_OUTPUT_ENCODING'.freeze
STRINGS_FILE_OUTPUT_ENCODING_VALUE = 'UTF-8'.freeze

def setup
@command = EmergeCLI::Commands::Autofixes::MinifyStrings.new

FileUtils.mkdir_p('tmp/test_autofix_strings')
FileUtils.cp_r('test/test_files/ExampleApp.xcodeproj', 'tmp/test_autofix_strings/ExampleApp.xcodeproj')
end

def teardown
FileUtils.rm_rf('tmp/test_autofix_strings')
end

def test_script_is_created
options = {
path: 'tmp/test_autofix_strings/ExampleApp.xcodeproj'
}

@command.call(**options)

project = Xcodeproj::Project.open('tmp/test_autofix_strings/ExampleApp.xcodeproj')

phase = project.targets[0].shell_script_build_phases.find do |item|
item.name == SCRIPT_NAME
end
assert_equal SCRIPT_NAME, phase.name
end

def test_user_script_sandboxing_is_disabled
options = {
path: 'tmp/test_autofix_strings/ExampleApp.xcodeproj'
}

@command.call(**options)

project = Xcodeproj::Project.open('tmp/test_autofix_strings/ExampleApp.xcodeproj')

project.targets[0].build_configurations.each do |config|
assert_equal 'NO', config.build_settings[ENABLE_USER_SCRIPT_SANDBOXING]
end
end

def test_strings_encoding_is_utf8
options = {
path: 'tmp/test_autofix_strings/ExampleApp.xcodeproj'
}

@command.call(**options)

project = Xcodeproj::Project.open('tmp/test_autofix_strings/ExampleApp.xcodeproj')

project.targets[0].build_configurations.each do |config|
assert_equal STRINGS_FILE_OUTPUT_ENCODING_VALUE, config.build_settings[STRINGS_FILE_OUTPUT_ENCODING]
end
end
end
end
end
end
Loading