moirai 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/workflows/test.yml +56 -0
  4. data/.gitignore +18 -0
  5. data/Appraisals +15 -0
  6. data/CHANGELOG.md +9 -0
  7. data/Gemfile +17 -0
  8. data/README.md +180 -0
  9. data/Rakefile +17 -0
  10. data/app/assets/config/moirai_manifest.js +2 -0
  11. data/app/assets/images/moirai/.keep +0 -0
  12. data/app/assets/javascripts/moirai/application.js +2 -0
  13. data/app/assets/javascripts/moirai/controllers/moirai_translation_controller.js +27 -0
  14. data/app/assets/javascripts/moirai/stimulus/init.js +5 -0
  15. data/app/assets/stylesheets/moirai/application.css +15 -0
  16. data/app/controllers/concerns/.keep +0 -0
  17. data/app/controllers/moirai/application_controller.rb +21 -0
  18. data/app/controllers/moirai/translation_files_controller.rb +93 -0
  19. data/app/helpers/moirai/application_helper.rb +9 -0
  20. data/app/jobs/moirai/application_job.rb +6 -0
  21. data/app/models/concerns/.keep +0 -0
  22. data/app/models/moirai/application_record.rb +7 -0
  23. data/app/models/moirai/translation.rb +14 -0
  24. data/app/models/moirai/translation_dumper.rb +43 -0
  25. data/app/models/moirai/translation_file_handler.rb +56 -0
  26. data/app/views/layouts/moirai/application.html.erb +26 -0
  27. data/app/views/moirai/translation_files/_form.html.erb +9 -0
  28. data/app/views/moirai/translation_files/index.html.erb +19 -0
  29. data/app/views/moirai/translation_files/show.html.erb +38 -0
  30. data/bin/check +4 -0
  31. data/bin/console +15 -0
  32. data/bin/fastcheck +17 -0
  33. data/bin/rails +16 -0
  34. data/bin/setup +8 -0
  35. data/config/routes.rb +9 -0
  36. data/lib/generators/moirai/install_generator.rb +19 -0
  37. data/lib/generators/moirai/migration_generator.rb +24 -0
  38. data/lib/generators/moirai/templates/migration.rb.erb +11 -0
  39. data/lib/i18n/backend/moirai.rb +65 -0
  40. data/lib/moirai/engine.rb +49 -0
  41. data/lib/moirai/pull_request_creator.rb +83 -0
  42. data/lib/moirai/version.rb +5 -0
  43. data/lib/moirai.rb +10 -0
  44. data/moirai.gemspec +36 -0
  45. metadata +181 -0
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Moirai</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "moirai/application", media: "all" %>
9
+ <%= javascript_include_tag "moirai/application", "data-turoblinks-track": "reload", type: "module" %>
10
+ <link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">
11
+ <link rel="icon" href="data:image/png;base64,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">
12
+ </head>
13
+ <body>
14
+
15
+ <% if notice.present? %>
16
+ <p class="notice"><%= notice %></p>
17
+ <% end %>
18
+
19
+ <% if alert.present? %>
20
+ <p class="notice">⚠️ <%= alert %></p>
21
+ <% end %>
22
+
23
+ <%= yield %>
24
+
25
+ </body>
26
+ </html>
@@ -0,0 +1,9 @@
1
+ <span
2
+ contenteditable
3
+ data-action="blur->moirai-translation#submit click->moirai-translation#click"
4
+ style="border: 1px dashed #1d9f74; min-width: 30px; display: inline-block;"
5
+ data-key="<%= key %>"
6
+ data-file-path="<%= file_path %>"
7
+ data-controller="moirai-translation">
8
+ <%= value %>
9
+ </span>
@@ -0,0 +1,19 @@
1
+ <main>
2
+ <h1>Translation files</h1>
3
+
4
+ <% if Moirai::PullRequestCreator.available? %>
5
+ <%= button_to "Create or update PR", moirai_open_pr_path %>
6
+ <% else %>
7
+ <p>PR creation is not available. Add the gem octokit to your gemfile to enable this feature</p>
8
+ <% end %>
9
+
10
+ <% @files.each do |file| %>
11
+ <article>
12
+ <bold><%= link_to (file[:name]), moirai_translation_file_path(file[:id]) %></bold>
13
+
14
+ <hr>
15
+
16
+ <%= shorten_path file[:path] %>
17
+ </article>
18
+ <% end %>
19
+ </main>
@@ -0,0 +1,38 @@
1
+ <main>
2
+ <h1>Update translations</h1>
3
+
4
+ <code><%= shorten_path @file_path %></code><br>
5
+ <p><%= link_to 'Back', moirai_translation_files_path %></p>
6
+
7
+ <table>
8
+ <thead>
9
+ <tr>
10
+ <th>Key</th>
11
+ <th>Value</th>
12
+ </tr>
13
+ </thead>
14
+ <tbody>
15
+ <% @translation_keys.each do |key, value| %>
16
+ <% translation = Moirai::Translation.find_by(key: key, file_path: @decoded_path) %>
17
+
18
+ <tr>
19
+ <td>
20
+ <% if translation.present? %>
21
+ <mark title="<%= value %>"><%= key %></mark>
22
+ <% else %>
23
+ <%= key %>
24
+ <% end %>
25
+ </td>
26
+ <td>
27
+ <%= form_for Moirai::Translation.new, url: moirai_create_or_update_translation_path do |f| %>
28
+ <%= f.hidden_field :key, value: key %>
29
+ <%= f.hidden_field :file_path, value: @decoded_path %>
30
+ <%= f.text_field :value, value: translation&.value || value %>
31
+ <%= f.submit 'Update', style: 'display: none;' %>
32
+ <% end %>
33
+ </td>
34
+ </tr>
35
+ <% end %>
36
+ </tbody>
37
+ </table>
38
+ </main>
data/bin/check ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bash
2
+
3
+ bundle exec rails test
4
+ #bundle exec rails test:system
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'moirai'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
data/bin/fastcheck ADDED
@@ -0,0 +1,17 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ if ! bundle exec standardrb
6
+ then
7
+ echo '\n Standard detected issues! Attempting to fix...'
8
+
9
+ if ! bundle exec standardrb --fix
10
+ then
11
+ echo '\n Tried to auto correct the issues, but some must be reviewed manually. Commit aborted.'
12
+ exit 1
13
+ fi
14
+
15
+ echo '\n Auto-corrected issues, but you should review changes before committing.'
16
+ exit 1
17
+ fi
data/bin/rails ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # This command will automatically be run when you run "rails" with Rails gems
5
+ # installed from the root of your application.
6
+
7
+ ENGINE_ROOT = File.expand_path('..', __dir__)
8
+ ENGINE_PATH = File.expand_path('../lib/moirai/engine', __dir__)
9
+ APP_PATH = File.expand_path('../test/dummy/config/application', __dir__)
10
+
11
+ # Set up gems listed in the Gemfile.
12
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
13
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
14
+
15
+ require 'rails/all'
16
+ require 'rails/engine/commands'
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/config/routes.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ Moirai::Engine.routes.draw do
4
+ root to: "translation_files#index"
5
+
6
+ resources :translation_files, only: %i[index show], as: "moirai_translation_files"
7
+ post "/translation_files/open_pr", to: "translation_files#open_pr", as: "moirai_open_pr"
8
+ post "/translation_files", to: "translation_files#create_or_update", as: "moirai_create_or_update_translation"
9
+ end
@@ -0,0 +1,19 @@
1
+ require "rails/generators"
2
+ require "rails/generators/migration"
3
+
4
+ module Moirai
5
+ module Generators
6
+ class InstallGenerator < Rails::Generators::Base
7
+ source_root File.expand_path("templates", __dir__)
8
+
9
+ def copy_migration
10
+ invoke "moirai:migration"
11
+ end
12
+
13
+ def mount_engine
14
+ route 'mount Moirai::Engine => "/moirai", as: "moirai"
15
+ '
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+ require "rails/generators/active_record"
5
+
6
+ module Moirai
7
+ module Generators
8
+ class MigrationGenerator < Rails::Generators::Base
9
+ include ActiveRecord::Generators::Migration
10
+
11
+ source_root File.expand_path("templates", __dir__)
12
+
13
+ def create_migration_file
14
+ migration_template "migration.rb.erb", "db/migrate/create_moirai_translations.rb", migration_version: migration_version
15
+ end
16
+
17
+ private
18
+
19
+ def migration_version
20
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,11 @@
1
+ class CreateMoiraiTranslations < ActiveRecord::Migration<%= migration_version %>
2
+ def change
3
+ create_table :moirai_translations do |t|
4
+ t.string :locale, null: false
5
+ t.string :key, null: false
6
+ t.string :file_path, null: false
7
+ t.text :value
8
+ t.timestamps
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,65 @@
1
+ module I18n
2
+ module Backend
3
+ class Moirai < I18n::Backend::Simple # TODO: no need to extend the simple one. It does too much
4
+ # TODO: mega inefficient. we don't want to perform a SQL query for each key!
5
+ def translate(locale, key, options = EMPTY_HASH)
6
+ overridden_translation = ::Moirai::Translation.find_by(locale: locale, key: key)
7
+ if overridden_translation.present?
8
+ overridden_translation.value
9
+ end
10
+ end
11
+
12
+ def store_moirai_translations(filename, locale, data, options)
13
+ moirai_translations[locale] ||= Concurrent::Hash.new
14
+ flatten_data = flatten_hash(filename, data)
15
+ flatten_data = Utils.deep_symbolize_keys(flatten_data) unless options.fetch(:skip_symbolize_keys, false)
16
+ Utils.deep_merge!(moirai_translations[locale], flatten_data)
17
+ end
18
+
19
+ def moirai_translations(do_init: false)
20
+ @moirai_translations ||= Concurrent::Hash.new do |h, k|
21
+ MUTEX.synchronize do
22
+ h[k] = Concurrent::Hash.new
23
+ end
24
+ end
25
+ end
26
+
27
+ def flatten_hash(filename, hash, parent_key = "", result = {})
28
+ hash.each do |key, value|
29
+ new_key = parent_key.empty? ? key.to_s : "#{parent_key}.#{key}"
30
+ case value
31
+ when Hash
32
+ flatten_hash(filename, value, new_key, result)
33
+ when Array
34
+ value.each_with_index do |item, index|
35
+ array_key = "#{new_key}.#{index}"
36
+ if item.is_a?(Hash)
37
+ flatten_hash(filename, item, array_key, result)
38
+ else
39
+ result[array_key] = filename
40
+ end
41
+ end
42
+ else
43
+ result[new_key] = filename
44
+ end
45
+ end
46
+ result
47
+ end
48
+
49
+ def load_file(filename)
50
+ type = File.extname(filename).tr(".", "").downcase
51
+ raise UnknownFileType.new(type, filename) unless respond_to?(:"load_#{type}", true)
52
+ data, keys_symbolized = send(:"load_#{type}", filename)
53
+ unless data.is_a?(Hash)
54
+ raise InvalidLocaleData.new(filename, "expects it to return a hash, but does not")
55
+ end
56
+ data.each do |locale, d|
57
+ store_translations(locale, d || {}, skip_symbolize_keys: keys_symbolized)
58
+ store_moirai_translations(filename, locale, d || {}, skip_symbolize_keys: keys_symbolized)
59
+ end
60
+
61
+ data
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Moirai
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace Moirai
6
+
7
+ config.generators do |generator|
8
+ generator.orm :active_record
9
+ end
10
+
11
+ config.after_initialize do
12
+ moirai_backend = I18n::Backend::Moirai.new
13
+ moirai_backend.eager_load!
14
+ I18n.backend = I18n::Backend::Chain.new(moirai_backend, I18n.backend)
15
+ end
16
+
17
+ # TODO: how to do this without rewriting the entire method?
18
+ # https://github.com/rails/rails/blob/main/actionview/lib/action_view/helpers/translation_helper.rb#L122
19
+ initializer "moirai.override_translation_helper" do
20
+ ActiveSupport.on_load(:action_view) do
21
+ module ActionView::Helpers::TranslationHelper # rubocop:disable Lint/ConstantDefinitionInBlock
22
+ alias_method :original_translate, :translate
23
+
24
+ def translate(key, **options)
25
+ value = original_translate(key, **options)
26
+
27
+ if moirai_edit_enabled?
28
+ moirai_translations = I18n.backend.backends.find { |b| b.respond_to?(:moirai_translations) }.moirai_translations
29
+ file_path = moirai_translations[I18n.locale][scope_key_by_partial(key)]
30
+
31
+ render(partial: "moirai/translation_files/form",
32
+ locals: {key: scope_key_by_partial(key),
33
+ file_path: file_path,
34
+ value: value})
35
+ else
36
+ value
37
+ end
38
+ end
39
+
40
+ alias_method :t, :translate
41
+
42
+ def moirai_edit_enabled?
43
+ params[:moirai] == "true"
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,83 @@
1
+ class Moirai::PullRequestCreator
2
+ BRANCH_NAME = "moirai-translations"
3
+
4
+ def self.available?
5
+ defined?(Octokit)
6
+ end
7
+
8
+ def initialize
9
+ @github_repo_name = ENV["MOIRAI_GITHUB_REPO_NAME"] || Rails.application.credentials.dig(:moirai, :github_repo_name)
10
+ @github_access_token = ENV["MOIRAI_GITHUB_ACCESS_TOKEN"] || Rails.application.credentials.dig(:moirai, :github_access_token)
11
+ @client = Octokit::Client.new(
12
+ access_token: @github_access_token
13
+ )
14
+ end
15
+
16
+ def create_pull_request(translations_array)
17
+ repo = @client.repo(@github_repo_name)
18
+ default_branch = repo.default_branch
19
+
20
+ if branch_exists?
21
+ puts "Branch #{BRANCH_NAME} already exists - the branch will be updated with the new changes"
22
+ else
23
+ puts "Branch #{BRANCH_NAME} does not exist - creating branch"
24
+ default_branch_ref = @client.ref(@github_repo_name, "heads/#{default_branch}")
25
+ latest_commit_sha = default_branch_ref.object.sha
26
+
27
+ @client.create_ref(@github_repo_name, "heads/#{BRANCH_NAME}", latest_commit_sha)
28
+ end
29
+
30
+ translations_array.each do |translation_hash|
31
+ update_file(translation_hash[:file_path], translation_hash[:content])
32
+ end
33
+
34
+ unless pull_request_exists?
35
+ pull_request = @client.create_pull_request(
36
+ @github_repo_name,
37
+ default_branch,
38
+ BRANCH_NAME,
39
+ "Adding new content by Moirai",
40
+ "BODY - This is a pull request created by Moirai"
41
+ )
42
+
43
+ puts "Pull request created: #{pull_request.html_url}"
44
+ end
45
+ end
46
+
47
+ def branch_exists?
48
+ @client.ref(@github_repo_name, "heads/#{BRANCH_NAME}")
49
+ true
50
+ rescue Octokit::NotFound
51
+ false
52
+ end
53
+
54
+ def update_file(path, content)
55
+ # TODO: check what happens if branch exists
56
+
57
+ file = @client.contents(@github_repo_name, path: path, ref: BRANCH_NAME)
58
+ file_sha = file.sha
59
+
60
+ @client.update_contents(
61
+ @github_repo_name,
62
+ path,
63
+ "Updating translations for #{path} by Moirai",
64
+ file_sha,
65
+ content,
66
+ branch: BRANCH_NAME
67
+ )
68
+ rescue Octokit::NotFound
69
+ @client.create_contents(
70
+ @github_repo_name,
71
+ path,
72
+ "Creating translations for #{path} by Moirai",
73
+ content,
74
+ branch: BRANCH_NAME
75
+ )
76
+ end
77
+
78
+ def pull_request_exists?
79
+ @client.pull_requests(@github_repo_name).any? do |pull_request|
80
+ pull_request.head.ref == BRANCH_NAME
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Moirai
4
+ VERSION = "0.1.0"
5
+ end
data/lib/moirai.rb ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "moirai/version"
4
+ require "moirai/engine"
5
+ require "moirai/pull_request_creator"
6
+ require "i18n/backend/moirai"
7
+
8
+ module Moirai
9
+ # Your code goes here...
10
+ end
data/moirai.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "moirai"
5
+ spec.version = "0.1.0"
6
+ spec.authors = ["Alessandro Rodi", "Oliver Anthony", "Daniel Bengl"]
7
+ spec.email = %w[alessandro.rodi@renuo.ch oliver.anthony@renuo.ch daniel.bengl@renuo.ch]
8
+
9
+ spec.summary = "Manage translation strings in real time"
10
+ spec.description = 'This gem allows you to manage translation strings in real time,
11
+ viewing the live changes in the browser, with the changes then converted to a PR opened on the repository.'
12
+ spec.homepage = "https://github.com/renuo/moirai"
13
+
14
+ spec.metadata["homepage_uri"] = spec.homepage
15
+ spec.metadata["source_code_uri"] = "https://github.com/renuo/moirai"
16
+ spec.metadata["changelog_uri"] = "https://github.com/renuo/moirai/CHANGELOG.md"
17
+ spec.metadata["steep_types"] = "sig"
18
+
19
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
20
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|docs)/}) || f.end_with?(".gem") }
21
+ end
22
+ spec.bindir = "exe"
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.required_ruby_version = ">= 2.7.0"
27
+ spec.add_dependency "rails", ">= 6.1"
28
+ spec.add_development_dependency "octokit", ">= 4.0"
29
+ spec.add_development_dependency "capybara"
30
+ spec.add_development_dependency "selenium-webdriver"
31
+ spec.add_development_dependency "rails", "~> 7.2.0"
32
+ spec.add_development_dependency "dotenv"
33
+
34
+ spec.license = "MIT"
35
+ spec.metadata["rubygems_mfa_required"] = "true"
36
+ end
metadata ADDED
@@ -0,0 +1,181 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: moirai
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alessandro Rodi
8
+ - Oliver Anthony
9
+ - Daniel Bengl
10
+ autorequire:
11
+ bindir: exe
12
+ cert_chain: []
13
+ date: 2024-10-23 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rails
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ">="
20
+ - !ruby/object:Gem::Version
21
+ version: '6.1'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '6.1'
29
+ - !ruby/object:Gem::Dependency
30
+ name: octokit
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: '4.0'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: '4.0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: capybara
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ - !ruby/object:Gem::Dependency
58
+ name: selenium-webdriver
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ - !ruby/object:Gem::Dependency
72
+ name: rails
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: 7.2.0
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - "~>"
83
+ - !ruby/object:Gem::Version
84
+ version: 7.2.0
85
+ - !ruby/object:Gem::Dependency
86
+ name: dotenv
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ type: :development
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ description: |-
100
+ This gem allows you to manage translation strings in real time,
101
+ viewing the live changes in the browser, with the changes then converted to a PR opened on the repository.
102
+ email:
103
+ - alessandro.rodi@renuo.ch
104
+ - oliver.anthony@renuo.ch
105
+ - daniel.bengl@renuo.ch
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files: []
109
+ files:
110
+ - ".github/CODEOWNERS"
111
+ - ".github/workflows/test.yml"
112
+ - ".gitignore"
113
+ - Appraisals
114
+ - CHANGELOG.md
115
+ - Gemfile
116
+ - README.md
117
+ - Rakefile
118
+ - app/assets/config/moirai_manifest.js
119
+ - app/assets/images/moirai/.keep
120
+ - app/assets/javascripts/moirai/application.js
121
+ - app/assets/javascripts/moirai/controllers/moirai_translation_controller.js
122
+ - app/assets/javascripts/moirai/stimulus/init.js
123
+ - app/assets/stylesheets/moirai/application.css
124
+ - app/controllers/concerns/.keep
125
+ - app/controllers/moirai/application_controller.rb
126
+ - app/controllers/moirai/translation_files_controller.rb
127
+ - app/helpers/moirai/application_helper.rb
128
+ - app/jobs/moirai/application_job.rb
129
+ - app/models/concerns/.keep
130
+ - app/models/moirai/application_record.rb
131
+ - app/models/moirai/translation.rb
132
+ - app/models/moirai/translation_dumper.rb
133
+ - app/models/moirai/translation_file_handler.rb
134
+ - app/views/layouts/moirai/application.html.erb
135
+ - app/views/moirai/translation_files/_form.html.erb
136
+ - app/views/moirai/translation_files/index.html.erb
137
+ - app/views/moirai/translation_files/show.html.erb
138
+ - bin/check
139
+ - bin/console
140
+ - bin/fastcheck
141
+ - bin/rails
142
+ - bin/setup
143
+ - config/routes.rb
144
+ - lib/generators/moirai/install_generator.rb
145
+ - lib/generators/moirai/migration_generator.rb
146
+ - lib/generators/moirai/templates/migration.rb.erb
147
+ - lib/i18n/backend/moirai.rb
148
+ - lib/moirai.rb
149
+ - lib/moirai/engine.rb
150
+ - lib/moirai/pull_request_creator.rb
151
+ - lib/moirai/version.rb
152
+ - moirai.gemspec
153
+ homepage: https://github.com/renuo/moirai
154
+ licenses:
155
+ - MIT
156
+ metadata:
157
+ homepage_uri: https://github.com/renuo/moirai
158
+ source_code_uri: https://github.com/renuo/moirai
159
+ changelog_uri: https://github.com/renuo/moirai/CHANGELOG.md
160
+ steep_types: sig
161
+ rubygems_mfa_required: 'true'
162
+ post_install_message:
163
+ rdoc_options: []
164
+ require_paths:
165
+ - lib
166
+ required_ruby_version: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ version: 2.7.0
171
+ required_rubygems_version: !ruby/object:Gem::Requirement
172
+ requirements:
173
+ - - ">="
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ requirements: []
177
+ rubygems_version: 3.4.20
178
+ signing_key:
179
+ specification_version: 4
180
+ summary: Manage translation strings in real time
181
+ test_files: []