tayo 0.1.12 → 0.1.13
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/CHANGELOG.md +18 -0
- data/README.md +29 -0
- data/lib/tayo/cli.rb +6 -0
- data/lib/tayo/commands/base.rb +13 -0
- data/lib/tayo/commands/sqlite.rb +413 -0
- data/lib/tayo/version.rb +1 -1
- data/scripts/setup_rubygems_key.sh +60 -0
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d61ea1f144cfaf69b20fa118160100a9398ebcc04240a39d445a2f7b7729e828
|
4
|
+
data.tar.gz: c08f57b24d2fbb5397fea80d0773335925706225aae2b5fb055060b8bfedbaa7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b51cc3c508a857449b7ec7a88d6f0e9fb822ee3fdd0f42ce40b088a0eb0bec9eaa31c69789ca65cf22e1214d72fee707da9c2078dcfce9054b666ac787ec39d0
|
7
|
+
data.tar.gz: 413c144d1c28b9f6ca125bb0d43b5580ab2eb5aa421e89afd09afa289b66f06a1c2dfd173b0c942cb1a09dcc1a0e244869a5700ffd79c46243a416cf6b4e6557
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,23 @@
|
|
1
1
|
# 변경 기록 (Changelog)
|
2
2
|
|
3
|
+
## [0.1.13] - 2025-06-30
|
4
|
+
|
5
|
+
### 🚀 새로운 기능
|
6
|
+
- **SQLite 프로덕션 최적화 명령 추가** (`tayo sqlite`):
|
7
|
+
- Rails 8 SQLite 프로덕션 환경 최적화 설정 자동 적용
|
8
|
+
- WAL 모드와 IMMEDIATE 트랜잭션으로 동시성 문제 해결
|
9
|
+
- busy_timeout 5초 설정으로 SQLITE_BUSY 에러 방지
|
10
|
+
- 캐시 및 메모리 최적화로 성능 향상
|
11
|
+
- 모든 데이터베이스(primary, cache, queue, cable)에 적용
|
12
|
+
- **SQLite 설정 검증 도구**:
|
13
|
+
- `rails db:sqlite_check` - 모든 pragma 설정 검증
|
14
|
+
- `rails db:sqlite_stats` - 데이터베이스 성능 통계 확인
|
15
|
+
- **SQLite 가이드 문서 자동 생성**: 상세한 프로덕션 가이드 포함
|
16
|
+
|
17
|
+
### 🛠️ 개선사항
|
18
|
+
- 공통 Base 클래스 추가로 코드 중복 제거
|
19
|
+
- 테스트 커버리지 확대
|
20
|
+
|
3
21
|
## [0.1.12] - 2025-01-20
|
4
22
|
|
5
23
|
### 🚀 새로운 기능
|
data/README.md
CHANGED
@@ -91,6 +91,33 @@ tayo cf
|
|
91
91
|
- 서버 정보 및 SSH 사용자 설정
|
92
92
|
- **Git 커밋**: DNS 설정 변경사항을 자동으로 커밋합니다
|
93
93
|
|
94
|
+
### 4. `tayo sqlite` - SQLite 프로덕션 최적화 설정
|
95
|
+
|
96
|
+
Rails 8의 SQLite를 프로덕션 환경에서 안정적으로 사용하기 위한 최적화 설정을 적용합니다.
|
97
|
+
|
98
|
+
```bash
|
99
|
+
tayo sqlite
|
100
|
+
```
|
101
|
+
|
102
|
+
이 명령어는 다음 작업들을 수행합니다:
|
103
|
+
|
104
|
+
- **database.yml 업데이트**:
|
105
|
+
- WAL (Write-Ahead Logging) 모드 활성화
|
106
|
+
- IMMEDIATE 트랜잭션 모드 설정
|
107
|
+
- busy_timeout 5초 설정으로 "database is locked" 에러 방지
|
108
|
+
- 캐시 및 메모리 최적화 설정
|
109
|
+
- 모든 데이터베이스(primary, cache, queue, cable)에 적용
|
110
|
+
- **SQLite pragma 초기화 파일 생성**:
|
111
|
+
- `config/initializers/sqlite3_pragmas.rb` 생성
|
112
|
+
- 런타임 시 추가 최적화 및 설정 검증
|
113
|
+
- 주기적인 PRAGMA optimize 실행
|
114
|
+
- **설정 검증 도구 생성**:
|
115
|
+
- `rails db:sqlite_check` - SQLite 설정 검증
|
116
|
+
- `rails db:sqlite_stats` - SQLite 성능 통계 확인
|
117
|
+
- **가이드 문서 생성**:
|
118
|
+
- `sqlite_guide.md` - 상세한 SQLite 프로덕션 가이드
|
119
|
+
- **Git 커밋**: 모든 변경사항을 자동으로 커밋합니다
|
120
|
+
|
94
121
|
## 전체 워크플로우
|
95
122
|
|
96
123
|
```bash
|
@@ -102,6 +129,7 @@ cd myapp
|
|
102
129
|
tayo init # Rails 프로젝트 초기화
|
103
130
|
tayo gh # GitHub 저장소 및 Container Registry 설정
|
104
131
|
tayo cf # Cloudflare DNS 설정
|
132
|
+
tayo sqlite # SQLite 프로덕션 최적화 (선택사항)
|
105
133
|
|
106
134
|
# 3. Kamal로 배포
|
107
135
|
bin/kamal setup
|
@@ -112,6 +140,7 @@ bin/kamal setup
|
|
112
140
|
- **🚀 원스톱 배포 설정**: 3개의 명령어로 배포 준비 완료
|
113
141
|
- **🐳 Docker 기반**: OrbStack과 GitHub Container Registry 활용
|
114
142
|
- **🌐 Cloudflare 통합**: 자동 DNS 설정 및 CDN 지원
|
143
|
+
- **🗄️ SQLite 최적화**: Rails 8 SQLite 프로덕션 환경 완벽 지원
|
115
144
|
- **🔒 보안**: 토큰과 환경 변수를 안전하게 관리
|
116
145
|
- **🎯 한국어 UI**: 모든 메시지가 한국어로 제공
|
117
146
|
- **🛡️ 오류 처리**: 각 단계별 검증과 친절한 오류 메시지
|
data/lib/tayo/cli.rb
CHANGED
@@ -5,6 +5,7 @@ require "colorize"
|
|
5
5
|
require_relative "commands/init"
|
6
6
|
require_relative "commands/gh"
|
7
7
|
require_relative "commands/cf"
|
8
|
+
require_relative "commands/sqlite"
|
8
9
|
|
9
10
|
module Tayo
|
10
11
|
class CLI < Thor
|
@@ -23,6 +24,11 @@ module Tayo
|
|
23
24
|
Commands::Cf.new.execute
|
24
25
|
end
|
25
26
|
|
27
|
+
desc "sqlite", "SQLite 프로덕션 최적화 설정을 적용합니다"
|
28
|
+
def sqlite
|
29
|
+
Commands::Sqlite.new.execute
|
30
|
+
end
|
31
|
+
|
26
32
|
desc "version", "Tayo 버전을 표시합니다"
|
27
33
|
def version
|
28
34
|
puts "Tayo #{VERSION}"
|
@@ -0,0 +1,413 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tayo/commands/base'
|
4
|
+
require 'git'
|
5
|
+
require 'colorize'
|
6
|
+
require 'tty-prompt'
|
7
|
+
|
8
|
+
module Tayo
|
9
|
+
module Commands
|
10
|
+
class Sqlite < Base
|
11
|
+
def execute
|
12
|
+
puts "\n🗄️ SQLite 프로덕션 최적화 설정을 시작합니다...".colorize(:yellow)
|
13
|
+
puts "Tayo #{Tayo::VERSION}".colorize(:light_black)
|
14
|
+
|
15
|
+
unless in_rails_project?
|
16
|
+
puts "❌ Rails 프로젝트가 아닙니다. Rails 프로젝트 루트에서 실행해주세요.".colorize(:red)
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
puts "\n이 명령은 다음 작업을 수행합니다:".colorize(:light_black)
|
21
|
+
puts " • database.yml에 SQLite 프로덕션 최적화 설정 추가"
|
22
|
+
puts " • SQLite pragma 초기화 파일 생성"
|
23
|
+
puts " • SQLite 설정 검증 rake task 생성"
|
24
|
+
puts " • SQLite 프로덕션 가이드 문서 생성"
|
25
|
+
|
26
|
+
prompt = TTY::Prompt.new
|
27
|
+
continue = prompt.yes?("\n계속하시겠습니까?")
|
28
|
+
|
29
|
+
unless continue
|
30
|
+
puts "취소되었습니다.".colorize(:yellow)
|
31
|
+
exit 0
|
32
|
+
end
|
33
|
+
|
34
|
+
# Git 상태 체크
|
35
|
+
git = Git.open('.')
|
36
|
+
unless git.status.changed.empty? && git.status.added.empty? && git.status.deleted.empty?
|
37
|
+
puts "\n⚠️ 커밋되지 않은 변경사항이 있습니다.".colorize(:yellow)
|
38
|
+
puts "SQLite 설정을 적용하기 전에 현재 상태를 커밋하는 것을 권장합니다.".colorize(:light_black)
|
39
|
+
|
40
|
+
commit_now = prompt.yes?("\n지금 커밋하시겠습니까?")
|
41
|
+
if commit_now
|
42
|
+
git.add(all: true)
|
43
|
+
git.commit("현재 상태 저장 (tayo sqlite 실행 전)")
|
44
|
+
puts "✓ 현재 상태를 커밋했습니다.".colorize(:green)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# database.yml 업데이트
|
49
|
+
update_database_yml
|
50
|
+
|
51
|
+
# SQLite pragma 초기화 파일 생성
|
52
|
+
create_sqlite_pragma_initializer
|
53
|
+
|
54
|
+
# SQLite 검증 rake task 생성
|
55
|
+
create_sqlite_check_rake_task
|
56
|
+
|
57
|
+
# SQLite 가이드 문서 생성
|
58
|
+
create_sqlite_guide
|
59
|
+
|
60
|
+
# Git 커밋
|
61
|
+
begin
|
62
|
+
git.add('config/database.yml')
|
63
|
+
git.add('config/initializers/sqlite3_pragmas.rb')
|
64
|
+
git.add('lib/tasks/sqlite_check.rake')
|
65
|
+
git.add('sqlite_guide.md')
|
66
|
+
|
67
|
+
commit_message = <<~MSG
|
68
|
+
SQLite 프로덕션 최적화 설정 추가
|
69
|
+
|
70
|
+
- WAL 모드와 IMMEDIATE 트랜잭션으로 동시성 문제 해결
|
71
|
+
- busy_timeout 5초 설정으로 SQLITE_BUSY 에러 방지
|
72
|
+
- 캐시 및 메모리 최적화로 성능 향상
|
73
|
+
- 설정 검증을 위한 rake task 추가
|
74
|
+
- 상세 가이드 문서 포함
|
75
|
+
MSG
|
76
|
+
|
77
|
+
git.commit(commit_message)
|
78
|
+
puts "\n✓ 변경사항을 Git에 커밋했습니다.".colorize(:green)
|
79
|
+
rescue => e
|
80
|
+
puts "\n⚠️ Git 커밋 실패: #{e.message}".colorize(:yellow)
|
81
|
+
puts "수동으로 커밋해주세요.".colorize(:light_black)
|
82
|
+
end
|
83
|
+
|
84
|
+
puts "\n✅ SQLite 프로덕션 최적화 설정이 완료되었습니다!".colorize(:green)
|
85
|
+
puts "\n다음 명령으로 설정을 검증할 수 있습니다:".colorize(:light_black)
|
86
|
+
puts " rails db:sqlite_check".colorize(:cyan)
|
87
|
+
puts " rails db:sqlite_stats".colorize(:cyan)
|
88
|
+
puts "\n자세한 내용은 sqlite_guide.md 파일을 참고하세요.".colorize(:light_black)
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def update_database_yml
|
94
|
+
puts "\n📝 database.yml 업데이트 중...".colorize(:blue)
|
95
|
+
|
96
|
+
database_yml_path = 'config/database.yml'
|
97
|
+
unless File.exist?(database_yml_path)
|
98
|
+
puts "❌ config/database.yml 파일을 찾을 수 없습니다.".colorize(:red)
|
99
|
+
exit 1
|
100
|
+
end
|
101
|
+
|
102
|
+
# 백업 생성
|
103
|
+
backup_path = "#{database_yml_path}.backup"
|
104
|
+
FileUtils.cp(database_yml_path, backup_path)
|
105
|
+
puts " 백업 생성: #{backup_path}".colorize(:light_black)
|
106
|
+
|
107
|
+
content = File.read(database_yml_path)
|
108
|
+
|
109
|
+
# SQLite 최적화 설정 추가
|
110
|
+
optimized_content = add_sqlite_optimizations(content)
|
111
|
+
|
112
|
+
File.write(database_yml_path, optimized_content)
|
113
|
+
puts "✓ database.yml이 업데이트되었습니다.".colorize(:green)
|
114
|
+
end
|
115
|
+
|
116
|
+
def add_sqlite_optimizations(content)
|
117
|
+
# 이미 최적화 설정이 있는지 확인
|
118
|
+
if content.include?('transaction_mode: IMMEDIATE')
|
119
|
+
puts " 이미 SQLite 최적화 설정이 적용되어 있습니다.".colorize(:yellow)
|
120
|
+
return content
|
121
|
+
end
|
122
|
+
|
123
|
+
# production 섹션 찾기
|
124
|
+
if content =~ /^production:\s*$/
|
125
|
+
# 기존 production 설정이 단순한 경우
|
126
|
+
if content =~ /^production:\s*\n\s+<<:\s*\*default/
|
127
|
+
# 새로운 production 설정으로 교체
|
128
|
+
new_production = <<~YAML
|
129
|
+
production:
|
130
|
+
primary:
|
131
|
+
<<: *default
|
132
|
+
database: storage/production.sqlite3
|
133
|
+
transaction_mode: IMMEDIATE
|
134
|
+
pragmas:
|
135
|
+
journal_mode: WAL
|
136
|
+
synchronous: NORMAL
|
137
|
+
cache_size: 2000
|
138
|
+
journal_size_limit: 27103364
|
139
|
+
foreign_keys: ON
|
140
|
+
mmap_size: 134217728
|
141
|
+
busy_timeout: 5000
|
142
|
+
cache:
|
143
|
+
<<: *default
|
144
|
+
database: storage/production_cache.sqlite3
|
145
|
+
migrations_paths: db/cache_migrate
|
146
|
+
transaction_mode: IMMEDIATE
|
147
|
+
pragmas:
|
148
|
+
journal_mode: WAL
|
149
|
+
synchronous: NORMAL
|
150
|
+
cache_size: 2000
|
151
|
+
journal_size_limit: 27103364
|
152
|
+
foreign_keys: ON
|
153
|
+
mmap_size: 134217728
|
154
|
+
busy_timeout: 5000
|
155
|
+
queue:
|
156
|
+
<<: *default
|
157
|
+
database: storage/production_queue.sqlite3
|
158
|
+
migrations_paths: db/queue_migrate
|
159
|
+
transaction_mode: IMMEDIATE
|
160
|
+
pragmas:
|
161
|
+
journal_mode: WAL
|
162
|
+
synchronous: NORMAL
|
163
|
+
cache_size: 2000
|
164
|
+
journal_size_limit: 27103364
|
165
|
+
foreign_keys: ON
|
166
|
+
mmap_size: 134217728
|
167
|
+
busy_timeout: 5000
|
168
|
+
cable:
|
169
|
+
<<: *default
|
170
|
+
database: storage/production_cable.sqlite3
|
171
|
+
migrations_paths: db/cable_migrate
|
172
|
+
transaction_mode: IMMEDIATE
|
173
|
+
pragmas:
|
174
|
+
journal_mode: WAL
|
175
|
+
synchronous: NORMAL
|
176
|
+
cache_size: 2000
|
177
|
+
journal_size_limit: 27103364
|
178
|
+
foreign_keys: ON
|
179
|
+
mmap_size: 134217728
|
180
|
+
busy_timeout: 5000
|
181
|
+
YAML
|
182
|
+
|
183
|
+
content.sub!(/^production:\s*\n\s+<<:\s*\*default\s*\n\s+database:\s+storage\/production\.sqlite3/, new_production.chomp)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# default 섹션에 busy_timeout 추가
|
188
|
+
unless content.include?('pragmas:')
|
189
|
+
content.sub!(/^(\s+timeout:\s+5000)/, "\\1\n pragmas:\n busy_timeout: 5000")
|
190
|
+
end
|
191
|
+
|
192
|
+
content
|
193
|
+
end
|
194
|
+
|
195
|
+
def create_sqlite_pragma_initializer
|
196
|
+
puts "\n📝 SQLite pragma 초기화 파일 생성 중...".colorize(:blue)
|
197
|
+
|
198
|
+
initializer_path = 'config/initializers/sqlite3_pragmas.rb'
|
199
|
+
|
200
|
+
# consulteam의 sqlite3_pragmas.rb 내용
|
201
|
+
initializer_content = <<~RUBY
|
202
|
+
# SQLite3 프로덕션 최적화 설정
|
203
|
+
# database.yml의 pragma 설정을 보완하는 추가 설정
|
204
|
+
|
205
|
+
# ActiveRecord가 연결을 설정할 때마다 실행되도록 설정
|
206
|
+
ActiveSupport.on_load(:active_record) do
|
207
|
+
if defined?(ActiveRecord::ConnectionAdapters::SQLite3Adapter)
|
208
|
+
# SQLite3Adapter의 configure_connection 메서드 오버라이드
|
209
|
+
module SQLite3BusyTimeoutPatch
|
210
|
+
def configure_connection
|
211
|
+
super
|
212
|
+
# busy_timeout을 확실하게 설정 (밀리초 단위)
|
213
|
+
if @raw_connection.respond_to?(:busy_timeout)
|
214
|
+
@raw_connection.busy_timeout(5000)
|
215
|
+
end
|
216
|
+
raw_execute("PRAGMA busy_timeout = 5000", "SCHEMA")
|
217
|
+
raw_execute("PRAGMA journal_size_limit = 27103364", "SCHEMA")
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
ActiveRecord::ConnectionAdapters::SQLite3Adapter.prepend(SQLite3BusyTimeoutPatch)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
Rails.application.config.after_initialize do
|
226
|
+
ActiveRecord::Base.connection_pool.with_connection do |connection|
|
227
|
+
if connection.adapter_name == 'SQLite'
|
228
|
+
# 개발 환경에서도 중요한 설정은 적용
|
229
|
+
# SQLite3 gem의 busy_timeout 메서드를 직접 호출
|
230
|
+
if connection.raw_connection.respond_to?(:busy_timeout)
|
231
|
+
connection.raw_connection.busy_timeout(5000)
|
232
|
+
else
|
233
|
+
connection.execute("PRAGMA busy_timeout = 5000")
|
234
|
+
end
|
235
|
+
connection.execute("PRAGMA journal_size_limit = 27103364")
|
236
|
+
|
237
|
+
if Rails.env.production?
|
238
|
+
# WAL 모드 확인 (database.yml에서 이미 설정되어 있어야 함)
|
239
|
+
result = connection.execute("PRAGMA journal_mode")
|
240
|
+
journal_mode = result.first["journal_mode"] rescue result.first.values.first
|
241
|
+
|
242
|
+
unless journal_mode.upcase == "WAL"
|
243
|
+
Rails.logger.warn "WARNING: SQLite is not in WAL mode. Production performance may be severely impacted."
|
244
|
+
end
|
245
|
+
|
246
|
+
# busy_timeout 확인
|
247
|
+
result = connection.execute("PRAGMA busy_timeout")
|
248
|
+
busy_timeout = result.first["busy_timeout"] rescue result.first.values.first
|
249
|
+
|
250
|
+
if busy_timeout.to_i < 5000
|
251
|
+
Rails.logger.warn "WARNING: SQLite busy_timeout is less than 5000ms. This may cause SQLITE_BUSY errors under load."
|
252
|
+
end
|
253
|
+
|
254
|
+
# 추가 최적화 설정
|
255
|
+
connection.execute("PRAGMA temp_store = MEMORY")
|
256
|
+
connection.execute("PRAGMA optimize")
|
257
|
+
|
258
|
+
Rails.logger.info "SQLite production optimizations applied successfully"
|
259
|
+
Rails.logger.info "Journal mode: \#{journal_mode}, Busy timeout: \#{busy_timeout}ms"
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
# 주기적인 최적화 실행 (선택사항)
|
266
|
+
if Rails.env.production? && defined?(ActiveRecord::Base)
|
267
|
+
Thread.new do
|
268
|
+
loop do
|
269
|
+
sleep(4.hours)
|
270
|
+
begin
|
271
|
+
ActiveRecord::Base.connection_pool.with_connection do |connection|
|
272
|
+
if connection.adapter_name == 'SQLite'
|
273
|
+
connection.execute("PRAGMA optimize")
|
274
|
+
Rails.logger.info "SQLite PRAGMA optimize executed"
|
275
|
+
end
|
276
|
+
end
|
277
|
+
rescue => e
|
278
|
+
Rails.logger.error "Failed to run SQLite optimization: \#{e.message}"
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
RUBY
|
284
|
+
|
285
|
+
File.write(initializer_path, initializer_content)
|
286
|
+
puts "✓ #{initializer_path} 파일이 생성되었습니다.".colorize(:green)
|
287
|
+
end
|
288
|
+
|
289
|
+
def create_sqlite_check_rake_task
|
290
|
+
puts "\n📝 SQLite 검증 rake task 생성 중...".colorize(:blue)
|
291
|
+
|
292
|
+
# lib/tasks 디렉토리 생성
|
293
|
+
FileUtils.mkdir_p('lib/tasks')
|
294
|
+
|
295
|
+
rake_task_path = 'lib/tasks/sqlite_check.rake'
|
296
|
+
|
297
|
+
# consulteam의 sqlite_check.rake 내용
|
298
|
+
rake_task_content = <<~RUBY
|
299
|
+
namespace :db do
|
300
|
+
desc "SQLite 프로덕션 설정 검증"
|
301
|
+
task sqlite_check: :environment do
|
302
|
+
if ActiveRecord::Base.connection.adapter_name == 'SQLite'
|
303
|
+
puts "\\n=== SQLite 프로덕션 설정 검증 ==="
|
304
|
+
|
305
|
+
connection = ActiveRecord::Base.connection
|
306
|
+
|
307
|
+
# 각 pragma 설정 확인
|
308
|
+
pragmas = {
|
309
|
+
'journal_mode' => 'WAL',
|
310
|
+
'synchronous' => 'NORMAL',
|
311
|
+
'cache_size' => '2000',
|
312
|
+
'journal_size_limit' => '27103364',
|
313
|
+
'foreign_keys' => '1',
|
314
|
+
'mmap_size' => '134217728',
|
315
|
+
'busy_timeout' => '5000'
|
316
|
+
}
|
317
|
+
|
318
|
+
all_good = true
|
319
|
+
|
320
|
+
pragmas.each do |pragma, expected|
|
321
|
+
result = connection.execute("PRAGMA \#{pragma}")
|
322
|
+
actual = result.first[pragma] rescue result.first.values.first
|
323
|
+
|
324
|
+
if pragma == 'foreign_keys'
|
325
|
+
status = actual.to_s == expected ? "✓" : "✗"
|
326
|
+
elsif pragma == 'journal_mode'
|
327
|
+
status = actual.to_s.upcase == expected ? "✓" : "✗"
|
328
|
+
elsif pragma == 'synchronous'
|
329
|
+
# NORMAL = 1 in SQLite
|
330
|
+
status = (actual.to_s == '1' || actual.to_s.upcase == expected) ? "✓" : "✗"
|
331
|
+
else
|
332
|
+
status = actual.to_s == expected ? "✓" : "✗"
|
333
|
+
end
|
334
|
+
|
335
|
+
puts "\#{status} \#{pragma.ljust(20)}: \#{actual} \#{status == '✗' ? "(예상값: \#{expected})" : ""}"
|
336
|
+
all_good = false if status == "✗"
|
337
|
+
end
|
338
|
+
|
339
|
+
# transaction_mode 확인 (Rails 로그에서만 확인 가능)
|
340
|
+
puts "\\n참고: transaction_mode=IMMEDIATE 설정은 런타임에서만 확인 가능합니다."
|
341
|
+
|
342
|
+
if all_good
|
343
|
+
puts "\\n✅ 모든 SQLite 프로덕션 설정이 올바르게 구성되었습니다!"
|
344
|
+
else
|
345
|
+
puts "\\n⚠️ 일부 설정이 권장값과 다릅니다. database.yml을 확인하세요."
|
346
|
+
end
|
347
|
+
else
|
348
|
+
puts "이 태스크는 SQLite 데이터베이스에서만 사용 가능합니다."
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
desc "SQLite 성능 통계 확인"
|
353
|
+
task sqlite_stats: :environment do
|
354
|
+
if ActiveRecord::Base.connection.adapter_name == 'SQLite'
|
355
|
+
puts "\\n=== SQLite 성능 통계 ==="
|
356
|
+
|
357
|
+
connection = ActiveRecord::Base.connection
|
358
|
+
|
359
|
+
# 데이터베이스 파일 크기
|
360
|
+
db_path = connection.instance_variable_get(:@config)[:database]
|
361
|
+
if File.exist?(db_path)
|
362
|
+
size_mb = File.size(db_path) / 1024.0 / 1024.0
|
363
|
+
puts "데이터베이스 크기: \#{'%.2f' % size_mb} MB"
|
364
|
+
|
365
|
+
# WAL 파일 크기 확인
|
366
|
+
wal_path = "\#{db_path}-wal"
|
367
|
+
if File.exist?(wal_path)
|
368
|
+
wal_size_mb = File.size(wal_path) / 1024.0 / 1024.0
|
369
|
+
puts "WAL 파일 크기: \#{'%.2f' % wal_size_mb} MB"
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
# 페이지 정보
|
374
|
+
result = connection.execute("PRAGMA page_count")
|
375
|
+
page_count = result.first.values.first
|
376
|
+
|
377
|
+
result = connection.execute("PRAGMA page_size")
|
378
|
+
page_size = result.first.values.first
|
379
|
+
|
380
|
+
puts "페이지 수: \#{page_count}"
|
381
|
+
puts "페이지 크기: \#{page_size} bytes"
|
382
|
+
|
383
|
+
# 캐시 히트율 (대략적인 추정)
|
384
|
+
result = connection.execute("PRAGMA cache_size")
|
385
|
+
cache_size = result.first.values.first
|
386
|
+
puts "캐시 크기: \#{cache_size} pages"
|
387
|
+
|
388
|
+
puts "\\n실시간 성능 모니터링을 위해서는 애플리케이션 로그를 확인하세요."
|
389
|
+
else
|
390
|
+
puts "이 태스크는 SQLite 데이터베이스에서만 사용 가능합니다."
|
391
|
+
end
|
392
|
+
end
|
393
|
+
end
|
394
|
+
RUBY
|
395
|
+
|
396
|
+
File.write(rake_task_path, rake_task_content)
|
397
|
+
puts "✓ #{rake_task_path} 파일이 생성되었습니다.".colorize(:green)
|
398
|
+
end
|
399
|
+
|
400
|
+
def create_sqlite_guide
|
401
|
+
puts "\n📝 SQLite 가이드 문서 생성 중...".colorize(:blue)
|
402
|
+
|
403
|
+
guide_path = 'sqlite_guide.md'
|
404
|
+
|
405
|
+
# consulteam의 sqlite_guide.md 내용
|
406
|
+
guide_content = File.read('/Users/alfonso/projects/consulteam/sqlite_guide.md')
|
407
|
+
|
408
|
+
File.write(guide_path, guide_content)
|
409
|
+
puts "✓ #{guide_path} 파일이 생성되었습니다.".colorize(:green)
|
410
|
+
end
|
411
|
+
end
|
412
|
+
end
|
413
|
+
end
|
data/lib/tayo/version.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# RubyGems API 키 설정 스크립트
|
4
|
+
|
5
|
+
echo "🔑 RubyGems API 키 설정 도우미"
|
6
|
+
echo "================================"
|
7
|
+
echo ""
|
8
|
+
echo "이 스크립트는 RubyGems API 키를 안전하게 저장합니다."
|
9
|
+
echo ""
|
10
|
+
|
11
|
+
# 옵션 선택
|
12
|
+
echo "저장 방법을 선택하세요:"
|
13
|
+
echo "1) ~/.gem/credentials (표준 방법)"
|
14
|
+
echo "2) macOS Keychain (가장 안전)"
|
15
|
+
echo "3) 둘 다"
|
16
|
+
echo ""
|
17
|
+
read -p "선택 (1-3): " choice
|
18
|
+
|
19
|
+
# API 키 입력
|
20
|
+
echo ""
|
21
|
+
read -s -p "RubyGems API 키를 입력하세요: " api_key
|
22
|
+
echo ""
|
23
|
+
|
24
|
+
case $choice in
|
25
|
+
1)
|
26
|
+
# credentials 파일에 저장
|
27
|
+
mkdir -p ~/.gem
|
28
|
+
echo "---" > ~/.gem/credentials
|
29
|
+
echo ":rubygems_api_key: $api_key" >> ~/.gem/credentials
|
30
|
+
chmod 0600 ~/.gem/credentials
|
31
|
+
echo "✅ ~/.gem/credentials에 저장되었습니다."
|
32
|
+
;;
|
33
|
+
2)
|
34
|
+
# Keychain에 저장
|
35
|
+
security add-generic-password -a "$USER" -s "rubygems-api-key" -w "$api_key" -U
|
36
|
+
echo "✅ macOS Keychain에 저장되었습니다."
|
37
|
+
;;
|
38
|
+
3)
|
39
|
+
# 둘 다
|
40
|
+
mkdir -p ~/.gem
|
41
|
+
echo "---" > ~/.gem/credentials
|
42
|
+
echo ":rubygems_api_key: $api_key" >> ~/.gem/credentials
|
43
|
+
chmod 0600 ~/.gem/credentials
|
44
|
+
security add-generic-password -a "$USER" -s "rubygems-api-key" -w "$api_key" -U
|
45
|
+
echo "✅ 두 곳 모두에 저장되었습니다."
|
46
|
+
;;
|
47
|
+
*)
|
48
|
+
echo "❌ 잘못된 선택입니다."
|
49
|
+
exit 1
|
50
|
+
;;
|
51
|
+
esac
|
52
|
+
|
53
|
+
echo ""
|
54
|
+
echo "🎉 설정이 완료되었습니다!"
|
55
|
+
echo ""
|
56
|
+
echo "이제 다음 명령으로 gem을 배포할 수 있습니다:"
|
57
|
+
echo " rake release"
|
58
|
+
echo ""
|
59
|
+
echo "또는 Keychain에서 키를 사용하려면:"
|
60
|
+
echo " GEM_HOST_API_KEY=\$(security find-generic-password -a \"$USER\" -s \"rubygems-api-key\" -w) rake release"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tayo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 이원섭wonsup Lee/Alfonso
|
@@ -82,13 +82,16 @@ files:
|
|
82
82
|
- exe/tayo
|
83
83
|
- lib/tayo.rb
|
84
84
|
- lib/tayo/cli.rb
|
85
|
+
- lib/tayo/commands/base.rb
|
85
86
|
- lib/tayo/commands/cf.rb
|
86
87
|
- lib/tayo/commands/gh.rb
|
87
88
|
- lib/tayo/commands/init.rb
|
89
|
+
- lib/tayo/commands/sqlite.rb
|
88
90
|
- lib/tayo/dockerfile_modifier.rb
|
89
91
|
- lib/tayo/version.rb
|
90
92
|
- pkg/homebody-0.1.0.gem
|
91
93
|
- repomix-output.xml
|
94
|
+
- scripts/setup_rubygems_key.sh
|
92
95
|
- sig/tayo.rbs
|
93
96
|
homepage: https://github.com/TeamMilestone/tayo
|
94
97
|
licenses: []
|