Skip to content

Commit

Permalink
Merge pull request #733 from bullet-train-co/feature/separate_transla…
Browse files Browse the repository at this point in the history
…tions_for_api

Introduce separate translations for API documentation
  • Loading branch information
jagthedrummer authored Jan 22, 2024
2 parents bf9b8d8 + 00a78ae commit f3eeddd
Show file tree
Hide file tree
Showing 18 changed files with 339 additions and 12 deletions.
4 changes: 2 additions & 2 deletions bullet_train-api/app/helpers/api/open_api_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ def automatic_paths_for(model, parent, except: [])
end

if custom_output
merge = deep_merge(YAML.load(output), YAML.load(custom_output)).to_yaml.html_safe
# YAML.load escapes emojis https://github.com/ruby/psych/issues/371
merge = deep_merge(YAML.safe_load(output), YAML.safe_load(custom_output)).to_yaml.html_safe
# YAML.safe_load escapes emojis https://github.com/ruby/psych/issues/371
# Next line returns emojis back and removes yaml garbage
output = merge.gsub("---", "").gsub(/\\u[\da-f]{8}/i) { |m| [m[-8..].to_i(16)].pack("U") }
end
Expand Down
9 changes: 9 additions & 0 deletions bullet_train-api/bullet_train-api.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ Gem::Specification.new do |spec|
spec.description = spec.summary
spec.license = "MIT"

# TODO: Remove some time after 1.6.27
spec.post_install_message = "
Bullet Train is switching to separate translations for API documentation.
To automatically update existing translations, run once:
bundle exec rake bullet_train:api:create_translations
"

# Prevent pushing this gem to RubyGems.org. To allow pushes either set the "allowed_push_host"
# to allow pushing to a single host or delete this section to allow pushing to any host.
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
Expand Down
22 changes: 20 additions & 2 deletions bullet_train-api/config/locales/en/platform/access_tokens.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,38 +20,56 @@ en:
destroy: Are you sure you want to remove %{access_token_name}? This will break any active integrations using this token and can't be undone.
fields: &fields
id:
heading: Access Token ID
heading: &id Access Token ID
api_title: *id
api_description: *id
application_id:
heading: Application ID
heading: &application_id Application ID
api_title: *application_id
api_description: *application_id
token:
_: &token Token
label: *token
heading: *token
api_title: *token
api_description: *token
expires_in:
_: &expires_in Expires In
label: *expires_in
heading: *expires_in
api_title: *expires_in
api_description: *expires_in
scopes:
_: &scopes Scopes
label: *scopes
heading: *scopes
api_title: *scopes
api_description: *scopes
last_used_at:
_: &last_used_at Last Used At
label: *last_used_at
heading: *last_used_at
api_title: *last_used_at
api_description: *last_used_at
description:
_: &description Description
label: *description
heading: *description
api_title: *description
api_description: *description
# 🚅 super scaffolding will insert new fields above this line.
created_at:
_: &created_at Created
label: *created_at
heading: *created_at
api_title: *created_at
api_description: *created_at
updated_at:
_: &updated_at Updated
label: *updated_at
heading: *updated_at
api_title: *updated_at
api_description: *updated_at
api:
collection_actions: "Collection Actions for Access Tokens"
index: "List Access Tokens"
Expand Down
22 changes: 18 additions & 4 deletions bullet_train-api/config/locales/en/platform/applications.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,46 @@ en:
name:
_: &name Name
label: *name
heading: Application Name
heading: &application_name Application Name
api_title: *application_name
api_description: *application_name

redirect_uri:
_: &redirect_uri Redirect URI
label: *redirect_uri
heading: *redirect_uri
api_title: *redirect_uri
api_description: *redirect_uri
help: This is only required if you're building an OAuth2-powered integration for other users.

uid:
heading: Client UID
heading: &uid Client UID
api_title: *uid
api_description: *uid

secret:
heading: Client Secret
heading: &secret Client Secret
api_title: *secret
api_description: *secret

label_string:
heading: Application Name
heading: *application_name
api_title: *application_name
api_description: *application_name

# 🚅 super scaffolding will insert new fields above this line.
created_at:
_: &created_at Added
label: *created_at
heading: *created_at
api_title: *created_at
api_description: *created_at
updated_at:
_: &updated_at Updated
label: *updated_at
heading: *updated_at
api_title: *updated_at
api_description: *updated_at
index:
section: "%{teams_possessive} Platform Applications"
contexts:
Expand Down
98 changes: 98 additions & 0 deletions bullet_train-api/lib/tasks/bullet_train/api_tasks.rake
Original file line number Diff line number Diff line change
Expand Up @@ -146,5 +146,103 @@ namespace :bullet_train do
)
end
end

desc "Create `api_title` and `api_description` translations"
task create_translations: :environment do
# Define the root of the locales directory
locales_root = Rails.root.join("config", "locales").to_s

# Define the backup directory
backup_dir = Rails.root.join("tmp", "locales_backup")
FileUtils.mkdir_p(backup_dir) unless Dir.exist?(backup_dir)

original_files = Dir.glob("#{locales_root}/**/*.yml")
differing_files_count = 0

original_files.each do |file|
puts "Processing #{file}..."

lines = File.readlines(file)
new_content = []
inside_fields = false
current_field = nil
fields_indentation = 4
api_title_exists = false
api_description_exists = false

# Read the entire file as a string
lines.each_with_index do |line, index|
# fields are always under locale:model:
if line.start_with?("#{" " * fields_indentation}fields:")
inside_fields = true
new_content << line
next
end

if inside_fields
current_indentation = line.index(/\S/) || 0
if current_indentation <= fields_indentation
# We've exited the fields block
inside_fields = false
current_field = nil
elsif current_indentation == fields_indentation + 2
# We're on a line with a field name
current_field = line.strip.split(":").first

api_title_exists = false
api_description_exists = false

n = 1
until index + n >= lines.length || (lines[index + n].index(/\S/) || 0) <= fields_indentation
if lines[index + n].strip.start_with?("api_title:")
api_title_exists = true
elsif lines[index + n].strip.start_with?("api_description:")
api_description_exists = true
end
n += 1
end

elsif current_field && line.strip.start_with?("heading:")
heading_value = line.split(":").last&.strip
indent = " " * current_indentation

if heading_value&.start_with?("&", "*")
new_content << line
else
heading_value = "&#{current_field} #{heading_value}"
new_content << "#{indent}heading: #{heading_value}\n"
end

field_key = heading_value[1..]&.split(" ")&.first
new_content << "#{indent}api_title: *#{field_key}\n" unless api_title_exists
new_content << "#{indent}api_description: *#{field_key}\n" unless api_description_exists

next
end
end

new_content << line
end

# Only write to file if there are changes
unless lines.join == new_content.join
differing_files_count += 1

# Compute the relative path manually
relative_path = file.sub(/^#{Regexp.escape(locales_root)}\/?/, "")

backup_path = File.join(backup_dir, relative_path)
FileUtils.mkdir_p(File.dirname(backup_path))
FileUtils.cp(file, backup_path)
puts "↳ Updating, backup created: #{backup_path}"

# Write the updated data back to the file
File.write(file, new_content.join)
end
end

puts "---"
puts "Total files updated: #{differing_files_count}/#{original_files.size}"
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,22 @@ en:
_: &name Name
label: *name
heading: *name
api_title: *name
api_description: *name

# 🚅 super scaffolding will insert new fields above this line.
created_at:
_: &created_at Added
label: *created_at
heading: *created_at
api_title: *created_at
api_description: *created_at
updated_at:
_: &updated_at Updated
label: *updated_at
heading: *updated_at
api_title: *updated_at
api_description: *updated_at
list:
section: "Stripe Installations"
contexts:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@ en:
name: &name Name
label: *name
heading: *name
api_title: *name
api_description: *name
# 🚅 super scaffolding will insert new fields above this line.
created_at:
name: &created_at Connected
heading: *created_at
api_title: *created_at
api_description: *created_at
index:
section: '%{users_possessive} Stripe Accounts'
contexts:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,36 +24,50 @@ en:
_: &id Delivery ID
label: *id
heading: *id
api_title: *id
api_description: *id

event_id: &event
_: &event_id Event
label: *event_id
heading: *event_id
api_title: *event_id
api_description: *event_id
placeholder: Select a Event
event: *event

endpoint_url:
_: &endpoint_url Endpoint URL
label: *endpoint_url
heading: *endpoint_url
api_title: *endpoint_url
api_description: *endpoint_url

delivered_at:
_: &delivered_at Delivered At
label: *delivered_at
heading: *delivered_at
api_title: *delivered_at
api_description: *delivered_at

status:
heading: Status
heading: &status Status
api_title: *status
api_description: *status

# 🚅 super scaffolding will insert new fields above this line.
created_at:
_: &created_at Issued At
label: *created_at
heading: *created_at
api_title: *created_at
api_description: *created_at
updated_at:
_: &updated_at Updated
label: *updated_at
heading: *updated_at
api_title: *updated_at
api_description: *updated_at
api:
endpoint_id: Absolutely Abstract Endpoint ID
collection_actions: "Collection Actions for Deliveries"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,44 +24,62 @@ en:
_: &id Delivery Attempt ID
label: *id
heading: *id
api_title: *id
api_description: *id

response_code:
_: &response_code Response Code
label: *response_code
heading: *response_code
api_title: *response_code
api_description: *response_code

response_body:
_: &response_body Response Body
label: *response_body
heading: *response_body
api_title: *response_body
api_description: *response_body

response_message:
_: &response_message Response Message
label: *response_message
heading: *response_message
api_title: *response_message
api_description: *response_message

error_message:
_: &error_message Error Message
label: *error_message
heading: *error_message
api_title: *error_message
api_description: *error_message

attempt_number:
_: &attempt_number Attempt Number
label: *attempt_number
heading: *attempt_number
api_title: *attempt_number
api_description: *attempt_number

status:
heading: Status
heading: &status Status
api_title: *status
api_description: *status

# 🚅 super scaffolding will insert new fields above this line.
created_at:
_: &created_at Attempted At
label: *created_at
heading: *created_at
api_title: *created_at
api_description: *created_at
updated_at:
_: &updated_at Updated
label: *updated_at
heading: *updated_at
api_title: *updated_at
api_description: *updated_at
api:
delivery_id: Absolutely Abstract Delivery ID
collection_actions: "Collection Actions for Delivery Attempts"
Expand Down
Loading

0 comments on commit f3eeddd

Please sign in to comment.