class InstrumentalComponents::Installer
def download_gem
def download_gem puts "Debug: Starting download_gem method..." # For local development, set INSTRUMENTAL_DOMAIN=http://localhost:3000 in .env # This allows testing against a local server while developing the gem puts "Debug: INSTRUMENTAL_DOMAIN = #{ENV['INSTRUMENTAL_DOMAIN'].inspect}" domain = ENV['INSTRUMENTAL_DOMAIN'] || 'https://instrumental.dev' unless 'https://instrumental.dev' == domain puts "Using domain: #{domain}" # Confirm that we're in local development mode end # This API endpoint on instrumental.dev will return the latest version of the gem and # save it in the root of the project under the filename, instrumental-components-library-latest.gem gem_url = "#{domain}/gem_downloads/instrumental-components-library-latest.gem?token=#{@license_key}&email=#{@email}" begin response = URI.open(gem_url) # Check if the response is JSON (indicating an error) content_type = response.content_type if content_type&.include?('application/json') error_data = JSON.parse(response.read) raise error_data['error'] || 'Authentication failed' end # If not JSON, it's the gem file - proceed with saving File.open('instrumental-components-library-latest.gem', 'wb') do |file| file.write(response.read) end rescue OpenURI::HTTPError => e if e.io.status[0] == '401' || e.io.status[0] == '403' || e.io.status[0] == '404' # Try to parse the error message from the response begin error_data = JSON.parse(e.io.read) raise error_data['error'] rescue JSON::ParserError raise "Server returned #{e.io.status[0]} status code" end else raise "Error downloading gem: #{e.message}" end rescue JSON::ParserError # If JSON parsing fails, it's likely the gem file - proceed with saving File.open('instrumental-components-library-latest.gem', 'wb') do |file| file.write(response.read) end end end
def initialize(license_key, email)
def initialize(license_key, email) @license_key = license_key @email = email end
def install
def install puts "📥 Downloading the latest version of Instrumental Components..." puts "Debug: Starting installation process..." begin # Load .env file if it exists (for local development only) if File.exist?('.env') puts "Debug: Loading local .env file..." Dotenv.load end puts "Debug: Environment variables - INSTRUMENTAL_DOMAIN = #{ENV['INSTRUMENTAL_DOMAIN'].inspect}" # Download the latest version of the gem download_gem puts "📦 Installing the gem on your system..." install_gem puts "📝 Updating Gemfile..." update_gemfile puts "" puts "Running 'bundle install'..." run_bundle_install puts "" puts "🚀 Running the Instrumental Components installer..." run_installer puts "" rescue => e # Display the error message sent by the logic in instrumental.dev's API puts "\n❌ #{e.message}" exit(1) end end
def install_gem
def install_gem system("gem install ./instrumental-components-library-latest.gem --silent --no-document") FileUtils.rm('instrumental-components-library-latest.gem') end
def run_bundle_install
def run_bundle_install system("bundle install") end
def run_installer
def run_installer system("rails g instrumental:install --license-key #{@license_key} --email #{@email}") end
def update_gemfile
def update_gemfile gemfile_path = 'Gemfile' return unless File.exist?(gemfile_path) gemfile_content = File.read(gemfile_path) unless gemfile_content.include?("gem 'instrumental-components-library'") if gemfile_content.include?("group :development") # Add to existing development group gemfile_content.gsub!(/group :development\s+do/) do |match| "#{match}\n gem 'instrumental-components-library'" end else # Create new development group gemfile_content += "\n\ngroup :development do\n gem 'instrumental-components-library'\nend\n" end File.write(gemfile_path, gemfile_content) puts "✅ gem 'instrumental-components-library' has been added to the development group in your Gemfile." else puts "✅ gem 'instrumental-components-library' is already in your Gemfile." end end