Module: Deliver::Loader

Defined in:
deliver/lib/deliver/loader.rb

Defined Under Namespace

Classes: LanguageFolder

Constant Summary collapse

APPLE_TV_DIR_NAME =

The directory ‘appleTV’ and ‘iMessage` are special folders that will cause our screenshot gathering code to iterate through it as well searching for language folders.

"appleTV".freeze
IMESSAGE_DIR_NAME =
"iMessage".freeze
DEFAULT_DIR_NAME =
"default".freeze
EXPANDABLE_DIR_NAMES =
[APPLE_TV_DIR_NAME, IMESSAGE_DIR_NAME].freeze
SPECIAL_DIR_NAMES =
[APPLE_TV_DIR_NAME, IMESSAGE_DIR_NAME, DEFAULT_DIR_NAME].freeze
SUPPLY_DIR_NAME =

Some exception directories may exist from other actions that should not be iterated through

"android".freeze
FRAMEIT_FONTS_DIR_NAME =
"fonts".freeze
META_DIR_NAMES =
UploadMetadata::ALL_META_SUB_DIRS.map(&:downcase)
EXCEPTION_DIRECTORIES =
(META_DIR_NAMES << SUPPLY_DIR_NAME << FRAMEIT_FONTS_DIR_NAME).freeze

Class Method Summary collapse

Class Method Details

.language_folders(root, ignore_validation, expand_sub_folders = false) ⇒ Array<LanguageFolder>

Returns the list of language folders

Parameters:

  • roort (String)

    A directory path to get the list of language folders

  • ignore_validation (Boolean)

    Set false not to raise the error when finding invalid folder name

  • expand_sub_folders (Boolean) (defaults to: false)

    Set true to expand special folders; such as “iMessage” to nested language folders

Returns:



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'deliver/lib/deliver/loader.rb', line 159

def self.language_folders(root, ignore_validation, expand_sub_folders = false)
  folders = Dir.glob(File.join(root, '*'))
               .select { |path| File.directory?(path) }
               .map { |path| LanguageFolder.new(path, nested: false) }
               .reject(&:skip?)

  selected_folders, rejected_folders = folders.partition(&:valid?)

  if !ignore_validation && !rejected_folders.empty?
    rejected_folders = rejected_folders.map(&:basename)
    UI.user_error!("Unsupported directory name(s) for screenshots/metadata in '#{root}': #{rejected_folders.join(', ')}" \
                   "\nValid directory names are: #{LanguageFolder.allowed_directory_names_with_case}" \
                   "\n\nEnable 'ignore_language_directory_validation' to prevent this validation from happening")
  end

  # Expand selected_folders for the special directories
  if expand_sub_folders
    selected_folders = selected_folders.flat_map do |folder|
      if folder.expandable?
        Dir.glob(File.join(folder.path, '*'))
           .select { |p| File.directory?(p) }
           .map { |p| LanguageFolder.new(p, nested: true) }
           .select(&:valid?)
      else
        folder
      end
    end
  end

  selected_folders
end

.load_app_clip_header_images(root, ignore_validation) ⇒ Object

Returns the list of valid app clip header images. When detecting invalid header images, this will cause an error. There may only be a max of one image per language and each image must be exactly 1800x1200.

finding invalid folder name @return [Array<Deliver::AppClipHeaderImage>] The list of AppClipHeaderImage that exists under given ‘root` directory

Parameters:

  • root (String)

    A directory path

  • ignore_validation (String)

    Set false not to raise the error when



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'deliver/lib/deliver/loader.rb', line 121

def self.load_app_clip_header_images(root, ignore_validation)
  language_folders_list = language_folders(root, ignore_validation, true)

  # Load images from all language folders (including default)
  app_clip_header_images = language_folders_list.flat_map do |language_folder|
    paths = language_folder.file_paths
    paths.map { |path| AppClipHeaderImage.new(path, language_folder.language) }
  end

  # validate the header images are 1800x1200 in size
  app_clip_header_images.each do |header_image|
    size = FastImage.size(header_image.path)
    if size.nil?
      UI.user_error!("Unable to read app clip header image file: #{header_image.path}")
    end
    size = size.join('x')
    unless size.eql?("1800x1200")
      UI.user_error!("App clip header images must be exactly 1800x1200 in size. Offending image has size #{size}: '#{header_image.path}'")
    end
  end

  # validate there is only one header image per language
  # Filter out nil languages (e.g., from default folder) before validation
  app_clip_header_images.map(&:language).compact.each do |language|
    if app_clip_header_images.find_all { |header_image| header_image.language.eql?(language) }.length > 1
      UI.user_error!("There can only be one app clip header image per language. The language #{language} has more than one image.")
    end
  end

  app_clip_header_images
end

.load_app_screenshots(root, ignore_validation) ⇒ Array<Deliver::AppScreenshot>

Returns the list of valid app screenshot. When detecting invalid screenshots, this will cause an error.

Parameters:

  • root (String)

    A directory path

  • ignore_validation (String)

    Set false not to raise the error when finding invalid folder name

Returns:



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
# File 'deliver/lib/deliver/loader.rb', line 87

def self.load_app_screenshots(root, ignore_validation)
  screenshots = language_folders(root, ignore_validation, true).flat_map do |language_folder|
    paths = if language_folder.framed_file_paths.count > 0
              UI.important("Framed screenshots are detected! 🖼 Non-framed screenshot files may be skipped. 🏃")
              # watchOS screenshots can be picked up even when framed ones were found since frameit doesn't support watchOS screenshots
              framed_or_watch, skipped = language_folder.file_paths.partition { |path| path.downcase.include?('framed') || path.downcase.include?('watch') }
              skipped.each { |path| UI.important("🏃 Skipping screenshot file: #{path}") }
              framed_or_watch
            else
              language_folder.file_paths
            end
    paths.map { |path| AppScreenshot.new(path, language_folder.language) }
  end

  errors = []
  valid_screenshots = screenshots.select { |screenshot| Deliver::AppScreenshotValidator.validate(screenshot, errors) }

  unless errors.empty?
    UI.important("🚫 Invalid screenshots were detected! Here are the reasons:")
    errors.each { |error| UI.error(error) }
    UI.user_error!("Canceled uploading screenshots. Please check the error messages above and fix the screenshots.")
  end

  valid_screenshots
end