Set up the Galaxy frontend's stack (#433)

* Setup webpacker for typescript

* Typescript is working

* Add documentation to set up the Galaxy project and start contributing to it

* Add Storybook

* Add Jest

* Remove tuistenv from the .gitignore

* Run rubocop
This commit is contained in:
Pedro Piñera Buendía 2019-07-03 13:41:08 +02:00 committed by GitHub
parent 5657230a8f
commit f584917534
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 22037 additions and 403 deletions

View File

@ -144,6 +144,11 @@ jobs:
bundle exec rails db:schema:load
bundle exec rake test
- run:
name: Javascript tests
command: |
yarn test
galaxy-deploy:
docker:
- image: buildpack-deps:trusty

1
.gitignore vendored
View File

@ -98,7 +98,6 @@ Carthage/Checkouts
*.profraw
tuist.zip
build/
tuistenv
TODO
TODO.md
mkmf.log

View File

@ -15,7 +15,7 @@
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"files.exclude": {
"**/.git*": true,
"**/.git": true,
"**/node_modules": true,
"**/.DS_Store": true
}

View File

@ -0,0 +1,5 @@
import Foundation
import TuistEnvKit
var registry = CommandRegistry()
registry.run()

3
docs/.gitignore vendored
View File

@ -1,2 +1,3 @@
node_modules
.docz
.docz
yarn-error.log

View File

@ -0,0 +1,43 @@
---
name: Galaxy
menu: Contributors
---
# Galaxy
Galaxy is a [Rails](https://rubyonrails.org/) application that exposes a [GraphQL API](https://graphql.org/learn/) that is consumed by a [React](https://reactjs.org/) frontend that is bundled and served by Rails using [Webpacker](https://github.com/rails/webpacker).
## Set up for development
- Git clone the repository: `git clone git@github.com:tuist/tuist.git`.
- Install [Postgress](https://www.postgresql.org/download/macosx/).
- Choose the galaxy directory: `cd galaxy`.
- Install Bundler dependencies: `bundle install`.
- Install NPM dependencies: `yarn install`.
- Run: `rails start`.
## Running tests
- Rails unit tests: `rails test`.
- Frontend tests: `yarn test`.
## Storybook
The project has [Storybook](https://storybook.js.org/) configured, a Javascript tool to create a catalogue for the project components. The catalogue entries are called stories, and they are defined in the directory `stories/`.
To run the catalogue, just run the command `yarn storybook` in your terminal. That'll transpile the catalogue and open the browser with it.
## Useful commands
- `rails db:drop`: Deletes the database.
- `rails db:create`: Creates the database.
- `rails db:migrate`: Migrates the database structure.
## Useful resources
- [Rails](https://rubyonrails.org/)
- [Styled components](https://www.styled-components.com/)
- [Relay](https://relay.dev/)
- [GraphQL](https://graphql.org/learn/)
- [React](https://reactjs.org/)
- [Webpacker](https://github.com/rails/webpacker)

View File

@ -1,4 +1,4 @@
import doczPluginNetlify from "docz-plugin-netlify";
import doczPluginNetlify from 'docz-plugin-netlify'
export default {
title: 'Tuist Documentation',
@ -27,15 +27,15 @@ export default {
width: 100,
},
styles: {
"body": `
body: `
font-family: -apple-system, system-ui, "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif;
`,
code: `
font-size: 13px;
font-family: Menlo, Consolas, Monaco, "Courier New", monospace, serif;
background-color: white;
`
}
`,
},
},
public: './public',
htmlContext: {
@ -66,6 +66,7 @@ export default {
name: 'Contributors',
menu: [
'Getting started',
'Galaxy',
'Code of conduct',
'Changelog guidelines',
'Core team',

View File

@ -1,7 +1,5 @@
{
"devDependencies": {
"react-hot-loader": "^4.9.0"
},
"devDependencies": {},
"scripts": {
"docz:dev": "docz dev",
"docz:build": "docz build"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
import { configure } from '@storybook/react'
// automatically import all files ending in *.stories.tsx
console.log('yolo')
function loadStories() {
require('../stories')
}
configure(loadStories, module)

View File

@ -0,0 +1,27 @@
{
"compilerOptions": {
"outDir": "build/lib",
"module": "commonjs",
"target": "es5",
"lib": ["es5", "es6", "es7", "es2017", "dom"],
"sourceMap": true,
"allowJs": false,
"jsx": "react",
"moduleResolution": "node",
"rootDirs": ["../frontend", "../stories"],
"baseUrl": "src",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true,
"declaration": true,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
"include": ["../frontend/**/*"],
"exclude": ["../node_modules", "../build", "../public", "scripts"]
}

View File

@ -0,0 +1,20 @@
const path = require('path')
module.exports = ({ config }) => {
config.module.rules.push({
test: /\.(ts|tsx)$/,
use: [
{
loader: require.resolve('awesome-typescript-loader'),
options: {
configFileName: path.join(__dirname, 'tsconfig.json'),
},
},
{
loader: require.resolve('react-docgen-typescript-loader'),
},
],
})
config.resolve.extensions.push('.ts', '.tsx')
return config
}

View File

@ -5,64 +5,35 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby('2.6.3')
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem('rails', '~> 5.2.3')
# Use postgresql as the database for Active Record
gem('pg', '>= 0.18', '< 2.0')
# Use Puma as the app server
gem('puma', '~> 4.0')
# Use SCSS for stylesheets
gem('sass-rails', '~> 5.0')
# Use Uglifier as compressor for JavaScript assets
gem('uglifier', '>= 1.3.0')
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem('webpacker')
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'mini_racer', platforms: :ruby
# Use CoffeeScript for .coffee assets and views
gem("react-rails", "~> 2.5")
gem('coffee-rails', '~> 5.0')
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem('turbolinks', '~> 5')
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem('jbuilder', '~> 2.5')
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use ActiveStorage variant
# gem 'mini_magick', '~> 4.8'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
# Reduces boot times through caching; required in config/boot.rb
gem('bootsnap', '>= 1.1.0', require: false)
gem('tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby])
gem("sentry-raven")
gem("sidekiq", "~> 5.2")
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end
group :development do
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
gem "foreman", "~> 0.64.0"
end
group :test do
# Adds support for Capybara system testing and selenium driver
gem 'capybara', '>= 2.15'
gem 'selenium-webdriver'
# Easy installation and use of chromedriver to run system tests with Chrome
gem 'chromedriver-helper'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem('tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby])
gem("komponent", "~> 2.2")
gem "sentry-raven"

View File

@ -47,6 +47,10 @@ GEM
archive-zip (0.12.0)
io-like (~> 0.3.0)
arel (9.0.0)
babel-source (5.8.35)
babel-transpiler (0.7.0)
babel-source (>= 4.0, < 6)
execjs (~> 2.0)
bindex (0.7.0)
bootsnap (1.4.4)
msgpack (~> 1.0)
@ -73,12 +77,17 @@ GEM
execjs
coffee-script-source (1.12.2)
concurrent-ruby (1.1.5)
connection_pool (2.2.2)
crass (1.0.4)
dotenv (0.7.0)
erubi (1.8.0)
execjs (2.7.0)
faraday (0.15.4)
multipart-post (>= 1.2, < 3)
ffi (1.11.1)
foreman (0.64.0)
dotenv (~> 0.7.0)
thor (>= 0.13.6)
globalid (0.4.2)
activesupport (>= 4.2.0)
i18n (1.6.0)
@ -86,11 +95,6 @@ GEM
io-like (0.3.0)
jbuilder (2.9.1)
activesupport (>= 4.2.0)
komponent (2.2.0)
actionview (>= 4.2)
activesupport (>= 4.2)
railties (>= 4.2)
webpacker (>= 3.0.0)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
@ -117,6 +121,8 @@ GEM
puma (4.0.0)
nio4r (~> 2.0)
rack (2.0.7)
rack-protection (2.0.5)
rack
rack-proxy (0.6.5)
rack
rack-test (1.1.0)
@ -149,6 +155,13 @@ GEM
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
ffi (~> 1.0)
react-rails (2.5.0)
babel-transpiler (>= 0.7.0)
connection_pool
execjs
railties (>= 3.2)
tilt
redis (4.1.2)
regexp_parser (1.5.1)
ruby_dep (1.5.0)
rubyzip (1.2.3)
@ -168,6 +181,11 @@ GEM
rubyzip (~> 1.2, >= 1.2.2)
sentry-raven (2.9.0)
faraday (>= 0.7.6, < 1.0)
sidekiq (5.2.7)
connection_pool (~> 2.2, >= 2.2.2)
rack (>= 1.5.0)
rack-protection (>= 1.5.0)
redis (>= 3.3.5, < 5)
spring (2.1.0)
spring-watcher-listen (2.0.1)
listen (>= 2.7, < 4.0)
@ -213,15 +231,17 @@ DEPENDENCIES
capybara (>= 2.15)
chromedriver-helper
coffee-rails (~> 5.0)
foreman (~> 0.64.0)
jbuilder (~> 2.5)
komponent (~> 2.2)
listen (>= 3.0.5, < 3.2)
pg (>= 0.18, < 2.0)
puma (~> 4.0)
rails (~> 5.2.3)
react-rails (~> 2.5)
sass-rails (~> 5.0)
selenium-webdriver
sentry-raven
sidekiq (~> 5.2)
spring
spring-watcher-listen (~> 2.0.0)
turbolinks (~> 5)

View File

@ -5,4 +5,8 @@
require_relative 'config/application'
task :start do
system("bundle exec foreman start -f config/Procfile.dev") || abort
end
Rails.application.load_tasks

View File

@ -1,7 +0,0 @@
# frozen_string_literal: true
class GraphController < ApplicationController
def show
render("pages/graph")
end
end

View File

@ -0,0 +1,7 @@
# frozen_string_literal: true
class PagesController < ApplicationController
def index
render(component: "pages/home")
end
end

View File

@ -17,9 +17,6 @@
</head>
<body>
<div class="container-fluid">
<%= component("navbar") %>
<%= yield %>
</div>
<%= yield %>
</body>
</html>

View File

@ -1 +0,0 @@
<h1>this is a test</h1>

View File

View File

@ -1,4 +1,5 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
ENV["NODE_ENV"] ||= "development"

View File

@ -1,4 +1,5 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development"
ENV["NODE_ENV"] ||= "development"

View File

@ -0,0 +1,2 @@
web: bundle exec rails s
webpack: ../bin/webpack-dev-server

View File

@ -7,17 +7,17 @@
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
Rails.application.config.content_security_policy do |policy|
policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development?
policy.connect_src(:self, :https, "http://localhost:3035", "ws://localhost:3035") if Rails.env.development?
# policy.default_src :self, :https
# policy.font_src :self, :https, :data
# policy.img_src :self, :https, :data
# policy.object_src :none
# policy.script_src :self, :https
# policy.style_src :self, :https
# policy.default_src :self, :https
# policy.font_src :self, :https, :data
# policy.img_src :self, :https, :data
# policy.object_src :none
# policy.script_src :self, :https
# policy.style_src :self, :https
# # Specify URI for violation reports
# # policy.report_uri "/csp-violation-report-endpoint"
# # Specify URI for violation reports
# # policy.report_uri "/csp-violation-report-endpoint"
end
# If you are using UJS then enable automatic nonce generation

View File

@ -1,3 +1,5 @@
# frozen_string_literal: true
if ENV.key?("SENTRY_DSN")
Raven.configure do |config|
config.dsn = ENV["SENTRY_DSN"]

View File

@ -1,6 +1,5 @@
# frozen_string_literal: true
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
get "graph", to: "graph#show"
root to: 'pages#index'
end

View File

@ -1,14 +1,7 @@
const { environment } = require('@rails/webpacker')
const typescript = require('./loaders/typescript')
const webpack = require('webpack')
environment.plugins.append(
'Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Popper: ['popper.js', 'default'],
})
)
environment.loaders.prepend('typescript', typescript)
module.exports = environment

View File

@ -0,0 +1,11 @@
const PnpWebpackPlugin = require('pnp-webpack-plugin')
module.exports = {
test: /\.(ts|tsx)?(\.erb)?$/,
use: [
{
loader: 'ts-loader',
options: PnpWebpackPlugin.tsLoaderOptions()
}
]
}

View File

@ -34,6 +34,8 @@ default: &default
- .woff2
extensions:
- .tsx
- .ts
- .mjs
- .js
- .sass

View File

@ -1,2 +0,0 @@
import "components/button/button";
import "components/navbar/navbar";

View File

@ -1,29 +0,0 @@
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Tuist</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Features</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Pricing</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown link
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
</ul>
</div>
</nav>

View File

@ -1 +0,0 @@
.navbar {}

View File

@ -1 +0,0 @@
import "./navbar.css";

View File

@ -1,5 +0,0 @@
# frozen_string_literal: true
module NavbarComponent
extend ComponentHelper
end

View File

@ -0,0 +1,5 @@
describe('this is just a sample test', () => {
test('2 should be equal to 2', () => {
expect(2).toBe(2)
})
})

View File

@ -0,0 +1,9 @@
import * as React from 'react'
class HomePage extends React.Component {
render() {
return <>Hello world. How are you??</>
}
}
export default HomePage

View File

@ -1,3 +0,0 @@
/* eslint no-console:0 */
import 'bootstrap/dist/js/bootstrap'
import 'components'

View File

@ -1 +1,3 @@
@import '~bootstrap/scss/bootstrap';
.ola {
color: red;
}

View File

@ -0,0 +1,6 @@
/* eslint no-console:0 */
// Support component names relative to this directory:
var componentRequireContext = require.context('components', true)
var ReactRailsUJS = require('react_ujs')
ReactRailsUJS.useContext(componentRequireContext)

View File

@ -0,0 +1,5 @@
// By default, this pack is loaded for server-side rendering.
// It must expose react_ujs as `ReactRailsUJS` and prepare a require context.
var componentRequireContext = require.context("components", true);
var ReactRailsUJS = require("react_ujs");
ReactRailsUJS.useContext(componentRequireContext);

5
galaxy/jest.config.js Normal file
View File

@ -0,0 +1,5 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testRegex: 'frontend/.*\\.(test|spec)\\.[jt]sx?$',
}

13000
galaxy/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,30 @@
{
"name": "galaxy",
"private": true,
"scripts": {
"storybook": "start-storybook",
"test": "jest"
},
"dependencies": {
"@rails/webpacker": "^4.0.7",
"bootstrap": "4.0.0-beta",
"jquery": "^3.4.1",
"popper.js": "^1.15.0"
"@types/react": "^16.8.22",
"@types/react-dom": "^16.8.4",
"@types/webpack-env": "^1.13.9",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react_ujs": "^2.5.0",
"ts-loader": "^6.0.4",
"typescript": "^3.5.2"
},
"devDependencies": {
"@storybook/addon-info": "^5.1.9",
"@storybook/react": "^5.1.9",
"@types/jest": "^24.0.15",
"@types/storybook__react": "^4.0.2",
"awesome-typescript-loader": "^5.2.1",
"jest": "^24.8.0",
"react-docgen-typescript-loader": "^3.1.0",
"ts-jest": "^24.0.2",
"webpack-dev-server": "^3.7.2"
}
}

7
galaxy/stories/index.tsx Normal file
View File

@ -0,0 +1,7 @@
import * as React from 'react'
import { storiesOf } from '@storybook/react'
import HomePage from '../frontend/components/pages/home'
const stories = storiesOf('Components', module)
stories.add('Home', () => <HomePage />, { info: { inline: true } })

19
galaxy/tsconfig.json Normal file
View File

@ -0,0 +1,19 @@
{
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es6", "dom"],
"module": "es6",
"moduleResolution": "node",
"jsx": "react",
"baseUrl": ".",
"paths": {
"*": ["node_modules/*", "app/javascript/*"]
},
"sourceMap": true,
"target": "es5"
},
"exclude": ["**/*.spec.ts", "node_modules", "vendor", "public"],
"compileOnSave": false
}

File diff suppressed because it is too large Load Diff

View File

@ -14,26 +14,26 @@ TUIST_API_URL = "https://api.github.com/repos/#{TUIST_REPOSITORY}"
TUIST_RELEASES_URL = "#{TUIST_API_URL}/releases/latest"
module Tty
module_function
extend self
def blue
bold 34
bold(34)
end
def red
bold 31
bold(31)
end
def reset
escape 0
escape(0)
end
def bold(code = 39)
escape "1;#{code}"
escape("1;#{code}")
end
def underline
escape '4;39'
escape('4;39')
end
def escape(code)
@ -45,7 +45,7 @@ class Array
def shell_s
cp = dup
first = cp.shift
cp.map { |arg| arg.gsub ' ', '\\ ' }.unshift(first).join(' ')
cp.map { |arg| arg.gsub(' ', '\\ ') }.unshift(first).join(' ')
end
end
@ -58,24 +58,24 @@ def warn(warning)
end
def system(*args)
abort "Failed during: #{args.shell_s}" unless Kernel.system(*args)
abort("Failed during: #{args.shell_s}") unless Kernel.system(*args)
end
def sudo(*args)
args.unshift('-A') unless ENV['SUDO_ASKPASS'].nil?
ohai '/usr/bin/sudo', *args
system '/usr/bin/sudo', *args
ohai('/usr/bin/sudo', *args)
system('/usr/bin/sudo', *args)
end
def getc
system '/bin/stty raw -echo'
system('/bin/stty raw -echo')
if STDIN.respond_to?(:getbyte)
STDIN.getbyte
else
STDIN.getc
end
ensure
system '/bin/stty -raw echo'
system('/bin/stty -raw echo')
end
def wait_for_user
@ -104,11 +104,11 @@ def force_curl?
end
def macos_version
@macos_version ||= Version.new(`/usr/bin/sw_vers -productVersion`.chomp[/10\.\d+/])
@macos_version ||= Version.new(%x(/usr/bin/sw_vers -productVersion).chomp[/10\.\d+/])
end
def command_line_tools_path
path = (`/usr/bin/xcode-select --print-path`).strip
path = %x(/usr/bin/xcode-select --print-path).strip
path.empty? ? "/Library/Developer/CommandLineTools" : path
end
@ -120,41 +120,41 @@ def should_install_command_line_tools?
end
# Invalidate sudo timestamp before exiting (if it wasn't active before).
Kernel.system '/usr/bin/sudo -n -v 2>/dev/null'
at_exit { Kernel.system '/usr/bin/sudo', '-k' } unless $CHILD_STATUS.success?
Kernel.system('/usr/bin/sudo -n -v 2>/dev/null')
at_exit { Kernel.system('/usr/bin/sudo', '-k') } unless $CHILD_STATUS.success?
# The block form of Dir.chdir fails later if Dir.CWD doesn't exist which I
# guess is fair enough. Also sudo prints a warning message for no good reason
Dir.chdir '/usr'
Dir.chdir('/usr')
####################################################################### Script
abort 'Tuist is not available for Linux platforms' if RUBY_PLATFORM.to_s.downcase.include?('linux')
abort "Don't run this as root!" if Process.uid.zero?
abort('Tuist is not available for Linux platforms') if RUBY_PLATFORM.to_s.downcase.include?('linux')
abort("Don't run this as root!") if Process.uid.zero?
ohai 'Installing Tuist'
ohai('Installing Tuist')
if should_install_command_line_tools?
ohai 'Searching online for the Command Line Tools'
ohai('Searching online for the Command Line Tools')
# This temporary file prompts the 'softwareupdate' utility to list the Command Line Tools
clt_placeholder = '/tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress'
sudo '/usr/bin/touch', clt_placeholder
clt_label = `/usr/sbin/softwareupdate -l | grep -B 1 -E "Command Line (Developer|Tools)" | awk -F"*" '/^ +\\*/ {print $2}' | sed 's/^ *//' | tail -n1`.chomp
ohai "Installing #{clt_label}"
sudo '/usr/sbin/softwareupdate', '-i', clt_label
sudo '/bin/rm', '-f', clt_placeholder
sudo '/usr/bin/xcode-select', '--switch', command_line_tools_path
sudo('/usr/bin/touch', clt_placeholder)
clt_label = %x(/usr/sbin/softwareupdate -l | grep -B 1 -E "Command Line (Developer|Tools)" | awk -F"*" '/^ +\\*/ {print $2}' | sed 's/^ *//' | tail -n1).chomp
ohai("Installing #{clt_label}")
sudo('/usr/sbin/softwareupdate', '-i', clt_label)
sudo('/bin/rm', '-f', clt_placeholder)
sudo('/usr/bin/xcode-select', '--switch', command_line_tools_path)
end
# Headless install may have failed, so fallback to original 'xcode-select' method
if should_install_command_line_tools? && STDIN.tty?
ohai 'Installing the Command Line Tools (expect a GUI popup):'
sudo '/usr/bin/xcode-select', '--install'
ohai('Installing the Command Line Tools (expect a GUI popup):')
sudo('/usr/bin/xcode-select', '--install')
puts 'Press any key when the installation has completed.'
getc
sudo '/usr/bin/xcode-select', '--switch', command_line_tools_path
sudo('/usr/bin/xcode-select', '--switch', command_line_tools_path)
end
abort <<~EOABORT if `/usr/bin/xcrun clang 2>&1` =~ /license/ && !$CHILD_STATUS.success?
abort(<<~EOABORT) if %x(/usr/bin/xcrun clang 2>&1) =~ /license/ && !$CHILD_STATUS.success?
You have not agreed to the Xcode license.
Before running the installer again please agree to the license by opening
Xcode.app or running:
@ -172,16 +172,16 @@ begin
uncompressed_path = File.join(tmp_dir, 'tuistenv')
installation_path = File.join('/usr', 'local', 'bin', 'tuist')
system 'curl', '-LSs', '--output', download_path, download_url
system "unzip -o #{download_path} -d #{uncompressed_path} > /dev/null"
system 'mv', File.join(uncompressed_path, 'tuistenv'), installation_path
system 'chmod', '+x', installation_path
system('curl', '-LSs', '--output', download_path, download_url)
system("unzip -o #{download_path} -d #{uncompressed_path} > /dev/null")
system('mv', File.join(uncompressed_path, 'tuistenv'), installation_path)
system('chmod', '+x', installation_path)
ensure
# remove the directory.
FileUtils.remove_entry tmp_dir
FileUtils.remove_entry(tmp_dir)
end
ohai 'Tuist installed 🎉'
ohai('Tuist installed 🎉')
puts '- Run `tuist --help` to get started'
puts '- Further documentation: '

View File

@ -9,22 +9,22 @@ require 'pathname'
@failed = false
module Tty
module_function
extend self
def blue
bold 34
bold(34)
end
def red
bold 31
bold(31)
end
def reset
escape 0
escape(0)
end
def bold(code = 39)
escape "1;#{code}"
escape("1;#{code}")
end
def escape(code)
@ -36,7 +36,7 @@ class Array
def shell_s
cp = dup
first = cp.shift
cp.map { |arg| arg.gsub ' ', '\\ ' }.unshift(first).join(' ')
cp.map { |arg| arg.gsub(' ', '\\ ') }.unshift(first).join(' ')
end
end
@ -71,12 +71,12 @@ end
def system(*args)
return if Kernel.system(*args)
warn "Failed during: #{args.shell_s}"
warn("Failed during: #{args.shell_s}")
@failed = true
end
ohai 'Uninstalling Tuist'
system 'rm', '-rf', '/usr/local/bin/tuist'
system 'rm', '-rf', File.join(Dir.home, '.tuist')
ohai('Uninstalling Tuist')
system('rm', '-rf', '/usr/local/bin/tuist')
system('rm', '-rf', File.join(Dir.home, '.tuist'))
ohai 'Tuist uninstalled'
ohai('Tuist uninstalled')