rosette 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +2 -0
- data/app/controllers/rosette/application_controller.rb +2 -0
- data/app/controllers/rosette/translations_controller.rb +15 -13
- data/app/helpers/rosette/application_helper.rb +2 -0
- data/app/models/rosette/application_record.rb +4 -0
- data/bin/rails +2 -0
- data/bin/rosette +5 -6
- data/config/routes.rb +2 -0
- data/lib/rosette/cli.rb +55 -42
- data/lib/rosette/controller.rb +9 -7
- data/lib/rosette/engine.rb +3 -1
- data/lib/rosette/manager.rb +49 -47
- data/lib/rosette/version.rb +5 -1
- data/lib/rosette.rb +2 -0
- data/lib/tasks/rosette_tasks.rake +1 -0
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d06214ac63c9666ca0fd74730175cc9eb308dbd16bd83e3fca8e9336d7123dc
|
4
|
+
data.tar.gz: d7521ae037801fa8c83d74dd2a22f6aa11f3269f90e60fc117746429b238564b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2118244884e6269ae5b3ef2146037ca7086fe32bad51f4bc4be5ab9ba3a12c262cb9244ef48d564537f3223185b3f4f563787b1b14bbc4439a078e2a0dff6267
|
7
|
+
data.tar.gz: 62c3f6715880adb58917f3a69544673b4110c8b47f0f1e7192e4858919104e2679925f86bba89370410c049379f56de7c72818fe67f6752789617651c85828fe
|
data/Rakefile
CHANGED
@@ -2,12 +2,13 @@
|
|
2
2
|
|
3
3
|
module Rosette
|
4
4
|
class TranslationsController < ApplicationController
|
5
|
+
|
5
6
|
def create
|
6
7
|
available_locales.each { |locale, translation| Manager.create(locale, key, translation) }
|
7
8
|
|
8
9
|
Manager.normalize!
|
9
10
|
|
10
|
-
redirect_to redirect_path, notice:
|
11
|
+
redirect_to redirect_path, notice: "Translation(s) added"
|
11
12
|
rescue StandardError => e
|
12
13
|
@error_message = e.message
|
13
14
|
render_rosette_new(key, redirect_path)
|
@@ -15,20 +16,21 @@ module Rosette
|
|
15
16
|
|
16
17
|
private
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
def translations_params
|
20
|
+
params.require(:translations).permit(:key, :redirect_path, available_locales: {})
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
def available_locales
|
24
|
+
translations_params[:available_locales]
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
def key
|
28
|
+
translations_params[:key]
|
29
|
+
end
|
30
|
+
|
31
|
+
def redirect_path
|
32
|
+
URI.parse(translations_params[:redirect_path]).to_s
|
33
|
+
end
|
29
34
|
|
30
|
-
def redirect_path
|
31
|
-
URI.parse(translations_params[:redirect_path]).to_s
|
32
|
-
end
|
33
35
|
end
|
34
36
|
end
|
data/bin/rails
CHANGED
data/bin/rosette
CHANGED
@@ -2,21 +2,20 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
begin
|
5
|
-
require File.join(Dir.pwd,
|
5
|
+
require File.join(Dir.pwd, "config/environment")
|
6
6
|
rescue LoadError
|
7
7
|
puts <<~ERR
|
8
|
+
|
8
9
|
Could not load your Rails app
|
9
10
|
=============================
|
10
11
|
Rosette assumes you have a config/environment.rb file it can load. If this is the case, please
|
11
12
|
make sure you are using Rosette CLI from the root of your Rails application. Do not hesitate to
|
12
13
|
raise an issue if you need further assistance.
|
14
|
+
|
13
15
|
ERR
|
14
16
|
exit 1
|
15
17
|
end
|
16
18
|
|
17
|
-
require
|
18
|
-
|
19
|
-
command = ARGV.shift
|
20
|
-
ARGV.clear
|
19
|
+
require "rosette"
|
21
20
|
|
22
|
-
Rosette::CLI.run
|
21
|
+
Rosette::CLI.run
|
data/config/routes.rb
CHANGED
data/lib/rosette/cli.rb
CHANGED
@@ -1,71 +1,84 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "tty-prompt"
|
4
|
+
|
3
5
|
module Rosette
|
4
6
|
class CLI
|
5
|
-
COMMANDS = %w[add remove read].freeze
|
6
7
|
|
7
8
|
class << self
|
8
|
-
def run(command:)
|
9
|
-
return display_help unless command.in?(COMMANDS)
|
10
9
|
|
11
|
-
|
12
|
-
|
10
|
+
attr_reader :prompt, :command
|
11
|
+
|
12
|
+
delegate :select, :ask, to: :@prompt
|
13
|
+
|
14
|
+
def run
|
15
|
+
ask_for_command
|
16
|
+
|
17
|
+
return help if command == "help"
|
18
|
+
|
19
|
+
ask_for_key
|
20
|
+
send command
|
13
21
|
end
|
14
22
|
|
15
23
|
private
|
16
24
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
25
|
+
def ask_for_command
|
26
|
+
@prompt = TTY::Prompt.new
|
27
|
+
@command = select("What do you want to achieve?") do |menu|
|
28
|
+
menu.choice("Read a translation", "read")
|
29
|
+
menu.choice("Add a translation", "add")
|
30
|
+
menu.choice("Remove a translation", "remove")
|
31
|
+
menu.choice("Display help", "help")
|
32
|
+
end
|
21
33
|
end
|
22
|
-
end
|
23
34
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
Manager.create(locale, @key, gets.chomp)
|
35
|
+
def ask_for_key
|
36
|
+
@key = ask "Please provide the key to translation:"
|
37
|
+
normalize_key!
|
28
38
|
end
|
29
|
-
end
|
30
39
|
|
31
|
-
|
32
|
-
|
33
|
-
|
40
|
+
def normalize_key!
|
41
|
+
Rosette.available_locales.each do |locale|
|
42
|
+
@key = @key.delete_prefix("#{locale}.")
|
43
|
+
end
|
34
44
|
end
|
35
|
-
end
|
36
45
|
|
37
|
-
|
38
|
-
puts 'Please provide the key to translation:'
|
39
|
-
@key = gets.chomp
|
46
|
+
# COMMANDS
|
40
47
|
|
41
|
-
|
42
|
-
|
48
|
+
def read
|
49
|
+
Rosette.available_locales.each do |locale|
|
50
|
+
translation = Manager.read(locale, @key)
|
51
|
+
puts "Translation for #{locale} is: #{translation}"
|
52
|
+
end
|
53
|
+
end
|
43
54
|
|
44
|
-
|
45
|
-
|
46
|
-
|
55
|
+
def add
|
56
|
+
Rosette.available_locales.each do |locale|
|
57
|
+
translation = ask "Please enter #{locale} translation:"
|
58
|
+
Manager.create(locale, @key, translation)
|
59
|
+
end
|
47
60
|
end
|
48
|
-
end
|
49
61
|
|
50
|
-
|
51
|
-
|
52
|
-
|
62
|
+
def remove
|
63
|
+
Rosette.available_locales.each do |locale|
|
64
|
+
Manager.delete(locale, @key)
|
65
|
+
end
|
66
|
+
end
|
53
67
|
|
54
|
-
|
68
|
+
def help
|
69
|
+
puts <<~HELP
|
55
70
|
|
56
|
-
|
57
|
-
|
58
|
-
remove remove translation from available locales
|
71
|
+
For each command you must provide a key pointing to the translation.
|
72
|
+
It can begin with or without the locale. These are all valid keys:
|
59
73
|
|
60
|
-
|
61
|
-
|
74
|
+
fr.activemodel.errors.blank
|
75
|
+
en.activemodel.errors.blank
|
76
|
+
activemodel.errors.blank
|
62
77
|
|
63
|
-
|
64
|
-
|
65
|
-
activemodel.errors.blank
|
78
|
+
HELP
|
79
|
+
end
|
66
80
|
|
67
|
-
HELP
|
68
|
-
end
|
69
81
|
end
|
82
|
+
|
70
83
|
end
|
71
84
|
end
|
data/lib/rosette/controller.rb
CHANGED
@@ -2,20 +2,22 @@
|
|
2
2
|
|
3
3
|
module Rosette
|
4
4
|
module Controller
|
5
|
+
|
5
6
|
extend ActiveSupport::Concern
|
6
7
|
|
7
8
|
included { rescue_from I18n::MissingTranslationData, with: :add_missing_translation_data }
|
8
9
|
|
9
10
|
private
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
def add_missing_translation_data(exception)
|
13
|
+
key = exception.message.sub(/translation missing:.+?\./, "")
|
14
|
+
|
15
|
+
render_rosette_new(key, request.fullpath)
|
16
|
+
end
|
13
17
|
|
14
|
-
render_rosette_new(key,
|
15
|
-
|
18
|
+
def render_rosette_new(key, redirect_path)
|
19
|
+
render "rosette/new", layout: "rosette/application", locals: { key: key, redirect_path: redirect_path }
|
20
|
+
end
|
16
21
|
|
17
|
-
def render_rosette_new(key, redirect_path)
|
18
|
-
render 'rosette/new', layout: 'rosette/application', locals: { key: key, redirect_path: redirect_path }
|
19
|
-
end
|
20
22
|
end
|
21
23
|
end
|
data/lib/rosette/engine.rb
CHANGED
@@ -2,16 +2,18 @@
|
|
2
2
|
|
3
3
|
module Rosette
|
4
4
|
class Engine < ::Rails::Engine
|
5
|
+
|
5
6
|
isolate_namespace Rosette
|
6
7
|
|
7
8
|
config.after_initialize do |app|
|
8
9
|
app.routes.prepend do
|
9
|
-
mount Rosette::Engine, at:
|
10
|
+
mount Rosette::Engine, at: "/rosette"
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
13
14
|
ActiveSupport.on_load(:action_controller_base) do
|
14
15
|
include Rosette::Controller
|
15
16
|
end
|
17
|
+
|
16
18
|
end
|
17
19
|
end
|
data/lib/rosette/manager.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Manager
|
4
|
-
|
4
|
+
|
5
|
+
["create", "read", "delete"].each do |verb|
|
5
6
|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
6
7
|
def self.#{verb}(*args)
|
7
8
|
new(*args).send('#{verb}')
|
@@ -11,63 +12,64 @@ class Manager
|
|
11
12
|
|
12
13
|
private
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
def read
|
21
|
-
stored_translations.dig(*@keys)
|
22
|
-
end
|
15
|
+
def initialize(locale, key, translation = nil)
|
16
|
+
@file_path = Rails.root.join("config/locales/#{locale}.yml")
|
17
|
+
@keys = normalize "#{locale}.#{key}"
|
18
|
+
@translation = translation
|
19
|
+
end
|
23
20
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
persist(updated_translations)
|
28
|
-
|
29
|
-
Manager.normalize!
|
30
|
-
end
|
21
|
+
def read
|
22
|
+
stored_translations.dig(*@keys)
|
23
|
+
end
|
31
24
|
|
32
|
-
|
33
|
-
|
34
|
-
|
25
|
+
def create
|
26
|
+
new_translation = @keys.reverse.inject(@translation) { |v, k| { k => v } }
|
27
|
+
updated_translations = deep_merge(stored_translations, new_translation)
|
28
|
+
persist(updated_translations)
|
35
29
|
|
36
|
-
|
37
|
-
|
30
|
+
Manager.normalize!
|
31
|
+
end
|
38
32
|
|
39
|
-
|
40
|
-
|
33
|
+
def delete
|
34
|
+
updated_translations = delete_translation(stored_translations, @keys)
|
35
|
+
persist(updated_translations)
|
41
36
|
|
42
|
-
|
43
|
-
|
37
|
+
Manager.normalize!
|
38
|
+
end
|
44
39
|
|
45
|
-
translations
|
46
|
-
|
40
|
+
def delete_translation(translations, keys)
|
41
|
+
return translations.delete(keys.first) if keys.length == 1
|
47
42
|
|
48
|
-
|
49
|
-
|
50
|
-
end
|
43
|
+
head, *tail = keys
|
44
|
+
delete_translation(translations[head], tail)
|
51
45
|
|
52
|
-
|
53
|
-
|
54
|
-
|
46
|
+
translations
|
47
|
+
end
|
48
|
+
|
49
|
+
def persist(translations)
|
50
|
+
File.write(@file_path, translations.deep_stringify_keys.to_yaml)
|
51
|
+
end
|
55
52
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
53
|
+
def stored_translations
|
54
|
+
YAML.safe_load(File.read(@file_path), symbolize_names: true)
|
55
|
+
end
|
56
|
+
|
57
|
+
def deep_merge(hash, other_hash)
|
58
|
+
hash.merge(other_hash) do |_key, this_val, other_val|
|
59
|
+
if this_val.is_a?(Hash) && other_val.is_a?(Hash)
|
60
|
+
deep_merge(this_val, other_val)
|
61
|
+
else
|
62
|
+
other_val
|
63
|
+
end
|
62
64
|
end
|
63
65
|
end
|
64
|
-
end
|
65
66
|
|
66
|
-
|
67
|
-
|
68
|
-
|
67
|
+
def normalize(key)
|
68
|
+
key.split(".").map(&:to_sym)
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.normalize!
|
72
|
+
I18n::Tasks::CLI.start(["normalize"]) if Rosette.normalize
|
73
|
+
end
|
69
74
|
|
70
|
-
def self.normalize!
|
71
|
-
I18n::Tasks::CLI.start(['normalize']) if Rosette.normalize
|
72
|
-
end
|
73
75
|
end
|
data/lib/rosette/version.rb
CHANGED
data/lib/rosette.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rosette
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexandre Platteeuw
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-04-
|
11
|
+
date: 2023-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n-tasks
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 7.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: tty-prompt
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.23.1
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.23.1
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rspec-rails
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|