jatai 1.3.0 → 1.4.0
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/lib/jatai/commands/base.rb +18 -1
- data/lib/jatai/commands/init.rb +24 -5
- data/lib/jatai/commands/up.rb +26 -4
- data/lib/jatai/slug.rb +40 -0
- data/lib/jatai/version.rb +1 -1
- data/lib/jatai.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 648533180b943e80129355c3308d594f1867fde7946470361f3897ad3cdd06eb
|
|
4
|
+
data.tar.gz: 2cfe1d3481ef074b1c1e257f0cd2eea369193a6681694d5d2da6a8e6131f4c42
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 82d898f647e4109c8842d35d203fd818a170f013f174865ef91e5934a6afc93083e2dd4aa7dd305ef2922d7ab2897c0257f9dbd9fba8c763a021b4707851a7be
|
|
7
|
+
data.tar.gz: 444b6824a85488f361916f126e34bc68e574c7248bef66d35c51430cdaa9056ad0b18d6880a17ea856d2ef98ca1483f7df71ad991d08729c19630f6b053b99a8
|
data/lib/jatai/commands/base.rb
CHANGED
|
@@ -22,8 +22,25 @@ module Jatai
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
# SEMPRE slugifica o que veio do arquivo. Isso é o que dá
|
|
26
|
+
# retrocompatibilidade com os .jatai.yml gerados antes de `app:` passar a
|
|
27
|
+
# guardar o slug: lá dentro havia o nome de exibição cru ("Alves
|
|
28
|
+
# Barbearia"), que ia direto para a URL e estourava no URI antes mesmo de
|
|
29
|
+
# sair a requisição. Slugificar é idempotente, então arquivo novo — que já
|
|
30
|
+
# traz o slug — atravessa sem alteração.
|
|
25
31
|
def app_slug
|
|
26
|
-
project_config[:app]
|
|
32
|
+
raw = project_config[:app]
|
|
33
|
+
slug = Slug.from(raw)
|
|
34
|
+
return slug if slug
|
|
35
|
+
|
|
36
|
+
abort pastel.red("`app` inválido no .jatai.yml (#{raw.inspect}). " \
|
|
37
|
+
"Use letras, números e hífen, ou rode `jatai init` novamente.")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Nome legível. Arquivo novo traz `name:`; no antigo, o próprio `app:` era
|
|
41
|
+
# o nome de exibição.
|
|
42
|
+
def app_name
|
|
43
|
+
project_config[:name] || project_config[:app]
|
|
27
44
|
end
|
|
28
45
|
|
|
29
46
|
def require_auth!
|
data/lib/jatai/commands/init.rb
CHANGED
|
@@ -11,7 +11,8 @@ module Jatai
|
|
|
11
11
|
"pro" => "Pro — 2GB RAM, réplicas ilimitadas (R$ 69/mês)"
|
|
12
12
|
}.freeze
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
# Região única por enquanto (Sudeste). Quando houver multi-região, volta a ser um prompt.
|
|
15
|
+
DEFAULT_REGION = "br-se1".freeze
|
|
15
16
|
STACKS = {
|
|
16
17
|
"rails" => "Rails",
|
|
17
18
|
"node" => "Node.js",
|
|
@@ -43,30 +44,48 @@ module Jatai
|
|
|
43
44
|
stack = prompt.select("Stack:", STACKS.map { |k, v| { name: v, value: k } })
|
|
44
45
|
end
|
|
45
46
|
|
|
46
|
-
name = prompt
|
|
47
|
+
name, slug = ask_name_and_slug(prompt)
|
|
47
48
|
preset = prompt.select("Preset:", PRESETS.map { |k, v| { name: v, value: k } })
|
|
48
|
-
region = prompt.select("Região:", REGIONS.map { |k, v| { name: "#{v} (#{k})", value: k } })
|
|
49
49
|
# Sites estáticos não têm banco — não pergunta o tier.
|
|
50
50
|
db_tier = stack == "static" ? nil : prompt.select("Banco de dados:", DATABASE_TIERS.map { |k, v| { name: v, value: k } })
|
|
51
51
|
branch = detect_git_branch || "main"
|
|
52
52
|
|
|
53
|
+
# `app` é o IDENTIFICADOR (slug) usado nas URLs da API; `name` é o nome de
|
|
54
|
+
# exibição. Antes um único campo servia aos dois papéis, e um nome com
|
|
55
|
+
# espaço ("Alves Barbearia") ia direto para a URL e estourava no URI.
|
|
53
56
|
config = {
|
|
54
|
-
"app" =>
|
|
57
|
+
"app" => slug,
|
|
58
|
+
"name" => name,
|
|
55
59
|
"stack" => stack,
|
|
56
60
|
"preset" => preset,
|
|
57
|
-
"region" =>
|
|
61
|
+
"region" => DEFAULT_REGION,
|
|
58
62
|
"branch" => branch
|
|
59
63
|
}
|
|
60
64
|
config["database_tier"] = db_tier if db_tier
|
|
61
65
|
|
|
62
66
|
File.write(config_path, YAML.dump(config))
|
|
63
67
|
success("Arquivo .jatai.yml criado com sucesso!")
|
|
68
|
+
info("Identificador: #{slug}") if slug != name
|
|
64
69
|
info("Branch: #{branch}")
|
|
65
70
|
info("Execute `jatai up` para criar e fazer deploy do app.")
|
|
66
71
|
end
|
|
67
72
|
|
|
68
73
|
private
|
|
69
74
|
|
|
75
|
+
# O nome é livre; o slug sai dele. Repete a pergunta quando nada
|
|
76
|
+
# aproveitável sobra (nome só de emoji, por exemplo) em vez de gravar um
|
|
77
|
+
# `app` vazio que quebraria a primeira requisição.
|
|
78
|
+
def ask_name_and_slug(prompt)
|
|
79
|
+
loop do
|
|
80
|
+
name = prompt.ask("Nome do app:") { |q| q.required true }
|
|
81
|
+
slug = Slug.from(name)
|
|
82
|
+
return [ name, slug ] if slug
|
|
83
|
+
|
|
84
|
+
error("Não consegui gerar um identificador a partir de #{name.inspect}. " \
|
|
85
|
+
"Use letras ou números no nome.")
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
70
89
|
def detect_stack
|
|
71
90
|
if File.exist?(File.join(Dir.pwd, "Gemfile"))
|
|
72
91
|
gemfile = File.read(File.join(Dir.pwd, "Gemfile"))
|
data/lib/jatai/commands/up.rb
CHANGED
|
@@ -46,14 +46,36 @@ module Jatai
|
|
|
46
46
|
|
|
47
47
|
private
|
|
48
48
|
|
|
49
|
+
# O slug do .jatai.yml é só o PALPITE: o servidor pode ter desambiguado
|
|
50
|
+
# com sufixo (alves-barbearia-1) quando o nome já existia, e a partir daí
|
|
51
|
+
# o arquivo apontaria para sempre para um app que não é o do cliente.
|
|
52
|
+
# Depois de criar, grava de volta o slug que o servidor devolveu — daí em
|
|
53
|
+
# diante o arquivo carrega a verdade, não a dedução.
|
|
49
54
|
def find_or_create_app(config)
|
|
50
|
-
existing = api.get("/api/v1/apps/#{
|
|
55
|
+
existing = api.get("/api/v1/apps/#{app_slug}")
|
|
51
56
|
info("App #{existing["slug"]} encontrado (#{existing["status"]}).")
|
|
52
57
|
ensure_repo_url(existing["slug"])
|
|
53
58
|
existing
|
|
54
59
|
rescue Api::Client::NotFoundError
|
|
55
|
-
info("Criando app #{
|
|
56
|
-
create_app(config)
|
|
60
|
+
info("Criando app #{app_name}...")
|
|
61
|
+
created = create_app(config)
|
|
62
|
+
persist_server_slug(created["slug"])
|
|
63
|
+
created
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def persist_server_slug(server_slug)
|
|
67
|
+
return if server_slug.nil? || server_slug == project_config[:app]
|
|
68
|
+
|
|
69
|
+
path = Config.project_file_path
|
|
70
|
+
raw = YAML.safe_load(File.read(path))
|
|
71
|
+
raw["name"] ||= raw["app"] # arquivo antigo: `app` guardava o nome
|
|
72
|
+
raw["app"] = server_slug
|
|
73
|
+
File.write(path, YAML.dump(raw))
|
|
74
|
+
info("Identificador do app no .jatai.yml: #{server_slug}")
|
|
75
|
+
rescue StandardError => e
|
|
76
|
+
# Não derruba o deploy: o app foi criado e o deploy segue. Só o arquivo
|
|
77
|
+
# ficou desatualizado, e o próximo comando cai no palpite de novo.
|
|
78
|
+
warn(pastel.yellow(" Não foi possível gravar o slug no .jatai.yml: #{e.message}"))
|
|
57
79
|
end
|
|
58
80
|
|
|
59
81
|
def trigger_provision(slug)
|
|
@@ -70,7 +92,7 @@ module Jatai
|
|
|
70
92
|
|
|
71
93
|
def create_app(config)
|
|
72
94
|
app_params = {
|
|
73
|
-
name:
|
|
95
|
+
name: app_name, stack: config[:stack], preset: config[:preset],
|
|
74
96
|
region: config[:region], repo_url: detect_git_remote, repo_branch: config[:branch]
|
|
75
97
|
}
|
|
76
98
|
app_params[:database_tier] = config[:database_tier] if config[:database_tier]
|
data/lib/jatai/slug.rb
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Jatai
|
|
2
|
+
# Converte texto livre no identificador que o servidor usa na URL.
|
|
3
|
+
#
|
|
4
|
+
# O servidor gera o slug com `name.parameterize` (ActiveSupport) e o valida
|
|
5
|
+
# com /\A[a-z0-9]([a-z0-9\-]*[a-z0-9])?\z/. A CLI não depende de
|
|
6
|
+
# ActiveSupport — carregá-la inteira por uma função encareceria o boot — então
|
|
7
|
+
# a transliteração é feita à mão para o conjunto que os clientes de fato usam
|
|
8
|
+
# (português). Caracteres fora dessa tabela são descartados, e é por isso que
|
|
9
|
+
# esta conversão é só o PALPITE da primeira requisição: quem manda no slug é o
|
|
10
|
+
# servidor, e o `jatai up` grava de volta no .jatai.yml o slug que ele retorna.
|
|
11
|
+
#
|
|
12
|
+
# Idempotente: aplicar sobre um slug válido devolve o mesmo slug. É o que dá
|
|
13
|
+
# retrocompatibilidade com os .jatai.yml antigos, em que `app:` guardava o
|
|
14
|
+
# nome de exibição — "Alves Barbearia" vira "alves-barbearia", que é
|
|
15
|
+
# exatamente o slug que o servidor gerou na criação daquele app.
|
|
16
|
+
module Slug
|
|
17
|
+
TRANSLITERATIONS = {
|
|
18
|
+
"á" => "a", "à" => "a", "â" => "a", "ã" => "a", "ä" => "a", "å" => "a",
|
|
19
|
+
"é" => "e", "è" => "e", "ê" => "e", "ë" => "e",
|
|
20
|
+
"í" => "i", "ì" => "i", "î" => "i", "ï" => "i",
|
|
21
|
+
"ó" => "o", "ò" => "o", "ô" => "o", "õ" => "o", "ö" => "o",
|
|
22
|
+
"ú" => "u", "ù" => "u", "û" => "u", "ü" => "u",
|
|
23
|
+
"ç" => "c", "ñ" => "n", "ý" => "y"
|
|
24
|
+
}.freeze
|
|
25
|
+
|
|
26
|
+
module_function
|
|
27
|
+
|
|
28
|
+
# nil quando não sobra nada utilizável — quem chama decide o que dizer ao
|
|
29
|
+
# usuário. Devolver "" mandaria uma URL vazia para a API.
|
|
30
|
+
def from(text)
|
|
31
|
+
return nil if text.nil?
|
|
32
|
+
|
|
33
|
+
slug = text.to_s.downcase
|
|
34
|
+
slug = slug.gsub(/[^a-z0-9\-]/) { |char| TRANSLITERATIONS.fetch(char, "-") }
|
|
35
|
+
slug = slug.gsub(/-+/, "-").gsub(/\A-|-\z/, "")
|
|
36
|
+
|
|
37
|
+
slug.empty? ? nil : slug
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/lib/jatai/version.rb
CHANGED
data/lib/jatai.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: jatai
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jataí Cloud
|
|
@@ -181,6 +181,7 @@ files:
|
|
|
181
181
|
- lib/jatai/commands/status.rb
|
|
182
182
|
- lib/jatai/commands/up.rb
|
|
183
183
|
- lib/jatai/config.rb
|
|
184
|
+
- lib/jatai/slug.rb
|
|
184
185
|
- lib/jatai/source_packer.rb
|
|
185
186
|
- lib/jatai/version.rb
|
|
186
187
|
- lib/jatai/websocket/cable_client.rb
|