Module: Vivlio::Starter::CLI::NewCommands
Constant Summary collapse
- SCAFFOLD_SOURCE =
‘lib/project_scaffold/` への絶対パス(`cli/new.rb` 基準)
File.('../../../project_scaffold', __dir__).freeze
- GEM_ROOT =
File.('../../../..', __dir__).freeze
- VALID_NAME_PATTERN =
/\A[a-zA-Z0-9_-]+\z/- DEFAULT_ANSWERS =
{ main_title: '新しい本', subtitle: '', author: '', publisher: '' }.freeze
Instance Method Summary collapse
-
#execute_new(name, options = {}) ⇒ Object
旧来のオプション付き新規作成(内部・テスト用).
-
#run(name) ⇒ Object
Scaffolder ベースのプロジェクト作成(README 同梱・book.yml 対話更新・vivliostyle 同期).
-
#run_from_command(cmd) ⇒ Object
Samovar ‘NewCommand` から呼び出すメイン処理(終了コードを返す).
- #update_book_config_interactively(config_path) ⇒ Object
Instance Method Details
#execute_new(name, options = {}) ⇒ Object
旧来のオプション付き新規作成(内部・テスト用)
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/vivlio/starter/cli/new.rb', line 46 def execute_new(name, = {}) ENV['VERBOSE'] = '1' if [:verbose] name = name&.strip if name.nil? || name.empty? Common.log_error('Error: プロジェクト名を指定してください。例: vs new mybook') exit(1) end dest = File.(name) if File.exist?(dest) Common.log_error("Error: '#{name}' は既に存在します。別名を指定してください。") exit(1) end Common.log_action("[vivlio-starter] Creating new project: #{name}") result = Vivlio::Starter::Scaffolder.scaffold_project( name: name, dest: dest, gem_root: GEM_ROOT, copy_styles_mode: :all, include_ci_workflow: true, include_viv_config_update: true ) Common.log_success("[vivlio-starter] Done. cd #{name} で移動し、執筆を開始できます。") Common.log_info('例: vivliostyle preview などのコマンドを実行') begin Dir.chdir(result.dest) do if [:manual_install] Common.log_always('doctor の自動実行をスキップします (--manual-install)') elsif [:auto_install] Common.log_always('必要ツールの自動インストールを有効にして doctor を実行します (--auto-install)') opts = { fix: true } opts[:yes] = true unless [:interactive] DoctorCommands.execute_doctor({ options: opts }) else proceed = false if $stdin.tty? $stdout.print('qpdf / pdfinfo の診断を実行しますか? [y/N]: ') ans = $stdin.gets proceed = ans && ans.strip.downcase == 'y' end if proceed DoctorCommands.execute_doctor({}) else Common.log_always('後で実行する場合: vs doctor もしくは vs doctor --fix (macOS)') end end end rescue StandardError => e Common.log_warn("doctor 実行フローでエラーが発生しました: #{e}") end end |
#run(name) ⇒ Object
Scaffolder ベースのプロジェクト作成(README 同梱・book.yml 対話更新・vivliostyle 同期)
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/vivlio/starter/cli/new.rb', line 104 def run(name) name = (name || '').strip abort 'Error: プロジェクト名を指定してください。例: vs new mybook' if name.empty? dest = File.(name) abort "Error: '#{name}' は既に存在します。別名を指定してください。" if File.exist?(dest) puts "[vivlio-starter] Creating new project: #{name}" result = Vivlio::Starter::Scaffolder.scaffold_project( name: name, dest: dest, gem_root: GEM_ROOT, include_post_replace: true, include_readme: true, readme_content: default_readme_content(name), include_viv_config_update: true ) do |event, ctx| update_book_config_interactively(ctx[:config_path]) if event == :after_config end run_vs_config(result.dest) synchronize_viv_config(result.vivliostyle_config_path, result.config_path) Common.log_always "[vivlio-starter] 完了しました。cd #{name} で移動し、執筆を開始できます。" Common.log_always '例: vivlio-starter build で執筆した書籍をPDFで作成できます。' 0 end |
#run_from_command(cmd) ⇒ Object
Samovar ‘NewCommand` から呼び出すメイン処理(終了コードを返す)
32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/vivlio/starter/cli/new.rb', line 32 def run_from_command(cmd) return cmd.print_usage if cmd.[:help] project_name = validated_project_name!(cmd) check_existing_directory!(cmd, project_name) answers = collect_answers(cmd, project_name) (cmd, project_name, answers) run_doctor(cmd, project_name) print_success(project_name) 0 end |
#update_book_config_interactively(config_path) ⇒ Object
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/vivlio/starter/cli/new.rb', line 133 def update_book_config_interactively(config_path) return unless $stdin.tty? cfg = YAML.load_file(config_path) cfg = {} unless cfg.is_a?(Hash) book_cfg = cfg['book'] || {} puts "\n[vivlio-starter] 書籍情報を入力してください(未入力は現状の値を維持)" current_title = book_cfg['main_title'].to_s current_sub = book_cfg['subtitle'].to_s current_auth = book_cfg['author'].to_s new_title = prompt_with_default('書籍名(main_title)', current_title) new_sub = prompt_with_default('副題(subtitle)', current_sub) new_auth = prompt_with_default('著者名(author)', current_auth) text = File.read(config_path, encoding: 'utf-8') lines = text.lines book_idx = lines.index { |l| l =~ /^\s*book:\s*$/ } keys = { 'main_title' => new_title, 'subtitle' => new_sub, 'author' => new_auth } if book_idx end_idx = lines.length ((book_idx + 1)...lines.length).each do |i| if lines[i] =~ /^\S/ && lines[i] !~ /^\s{2}/ end_idx = i break end end present = { 'main_title' => false, 'subtitle' => false, 'author' => false } ((book_idx + 1)...end_idx).each do |i| line = lines[i] next unless line =~ /^(\s{2})(main_title|subtitle|author):\s*([^#\n]*)(\s*#.*)?$/ indent = ::Regexp.last_match(1) key = ::Regexp.last_match(2) comment = ::Regexp.last_match(4).to_s value = keys[key] lines[i] = "#{indent}#{key}: '#{value}'#{comment}\n" present[key] = true end insert_pos = book_idx + 1 %w[main_title subtitle author].each do |key| next if present[key] lines.insert(insert_pos, " #{key}: '#{keys[key]}'\n") insert_pos += 1 end File.write(config_path, lines.join, encoding: 'utf-8') Common.log_success("[vivlio-starter] book.yml を更新しました。") else File.open(config_path, 'a:utf-8') do |f| f.puts f.puts 'book:' f.puts " main_title: '#{new_title}'" f.puts " subtitle: '#{new_sub}'" f.puts " author: '#{new_auth}'" end Common.log_success("[vivlio-starter] book.yml に book セクションを追記しました。") end rescue StandardError => e Common.log_warn("[vivlio-starter] book.yml の対話入力に失敗しました: #{e}") end |