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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2a5fae5e5027e6af704d0de853a7402c0011dbe9e4e9638bd8e05553a60d9f13
4
- data.tar.gz: 7b0446e1db678ae717d49176d415095820622e19b3f75812182090a9ff32aa89
3
+ metadata.gz: d61ea1f144cfaf69b20fa118160100a9398ebcc04240a39d445a2f7b7729e828
4
+ data.tar.gz: c08f57b24d2fbb5397fea80d0773335925706225aae2b5fb055060b8bfedbaa7
5
5
  SHA512:
6
- metadata.gz: 5b9c66d762054c1df3a9a40d1a0f98e29eb2428aa43dd048ad678ce85461f2f81f1486bd92e2e67b7b7c1d34ccfe2818a59bea4bfd02972a2948f9ee55f4597f
7
- data.tar.gz: 6df1da4eeaa3def9471469d100ed1dd8575129eb1ac959a2915d45a20da0f3e7f97f3d893d7ac46965207827ff0febd73a55732ac3538a0dd9156ccd30e4d7bf
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,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tayo
4
+ module Commands
5
+ class Base
6
+ private
7
+
8
+ def in_rails_project?
9
+ File.exist?('Gemfile') && File.exist?('config/application.rb')
10
+ end
11
+ end
12
+ end
13
+ end
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tayo
4
- VERSION = "0.1.12"
4
+ VERSION = "0.1.13"
5
5
  end
@@ -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.12
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: []