require_relative '../lib' class VueCreate def initialize @input = InputLoop.new @pwd = FileUtils.pwd @root = ::Rails.root @pack = @root.join('package.json') @src_dir = Pathname.new(__FILE__).dirname.join('..', '..', 'source') end def self.run! new.start end def start check_node! FileUtils.chdir @root begin package_manager? install_vue_cli run_vue_create? install_dev_deps delete_vue_src? copy_demo? copy_config generate_vue_yml puts 'vue:create finished!' ensure FileUtils.chdir @pwd end end private def check_node! @pm = VueCli::Rails::NodeEnv.new abort('Cannot find node.js') unless @pm.node? end def package_manager? yarn = @pm.yarn_version npm = @pm.npm_version abort('Cannot find npm or yarn') unless yarn || npm if yarn && npm input = @input.gets( 'Which package manager to use?', @root.join('package-lock.json').exist? ? 'yN' : 'Yn', y: 'yarn', n: 'npm', ) else input = npm ? 'n' : 'y' end @pm.use!(input == 'n' ? :npm : :yarn) puts "Using package manager: #{@pm.package_manager}" end def install_vue_cli return if @pm.vue? puts "@vue/cli haven't been installed" pm.global_add('@vue/cli') end def run_vue_create? input = 'y' if @pack.exist? puts 'Detected `package.json`!' input = @input.gets( ' Do you want `vue create?` to overwrite your package.json', 'ynAk', a: 'Auto', k: 'Keep', ) end return if input == 'n' src_json = JSON.parse(@pack.read) unless input == 'y' @pm.exec('vue create', '', "-n -m #{@pm.package_manager} .") dst_json = JSON.parse(@pack.read) unless input == 'y' return if input == 'y' || dst_json == src_json src_json, dst_json = [dst_json, src_json] if input == 'a' dst_json.deep_merge!(src_json) @pack.write(JSON.pretty_generate(dst_json)) @pm.install end def install_dev_deps package = JSON.parse(@pack.read) dev_deps = package['devDependencies'] dd = %w[webpack-assets-manifest js-yaml].find_all do |dep| !dev_deps.key?(dep) end @pm.add "-D #{dd.join(' ')}" if dd.any? end def delete_vue_src? src = @root.join('src') return unless src.exist? && src.directory? puts 'Detected `src` folder (should be generated by vue-cli)' FileUtils.rm_rf(src.to_s) if @input.gets(' Do you want to delete src folder?') == 'y' end def copy_demo? return unless @input.gets('Do you want to copy demo code?', 'yN') == 'y' FileUtils.cp_r(@src_dir.join('app'), @root) routes = @root.join('config', 'routes.rb') return unless routes.exist? route_lines = routes.read.split("\n") foo = false bar = false route_lines.each do |line| foo ||= line.include? 'vue#foo' bar ||= line.include? 'vue#bar' end return if foo && bar end_line = route_lines.rindex { |ln| ln =~ /^\s*end\b/ } return if end_line.blank? route_lines.insert(end_line, " get 'vue/bar' => 'vue#bar'") unless bar route_lines.insert(end_line, " get 'vue/foo' => 'vue#foo'") unless foo route_lines.insert(end_line, ' # Example of vue_cli-rails') routes.write(route_lines.join("\n")) end def copy_config puts 'Copying configuration files...' FileUtils.cp(@src_dir.join('vue.rails.js'), "#{@root}/") if @root.join('vue.config.js').exist? puts 'Detected `vue.config.js`!' return if @input.gets(' Do you want to overwrite vue.config.js?', 'yN') == 'n' end FileUtils.cp(@src_dir.join('vue.config.js'), "#{@root}/") end def generate_vue_yml yml_dest = @root.join('config', 'vue.yml') if yml_dest.exist? puts 'Detected `config/vue.yml`!' return if @input.gets(' Do you want to overwrite config/vue.yml?') == 'n' end yml = @src_dir.join('vue.yml').read yml = yml.sub('${PACKAGE_MANAGER}', pm.package_manager.to_s) yml_dest.write(yml) end end