Class: Pantograph::Setup

Inherits:
Object
  • Object
show all
Defined in:
pantograph/lib/pantograph/setup/setup.rb

Direct Known Subclasses

SetupAngular, SetupGeneric, SetupGradle

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(project_path: nil, had_multiple_projects_to_choose_from: nil, preferred_setup_method: nil) ⇒ Setup

Returns a new instance of Setup.



74
75
76
77
78
# File 'pantograph/lib/pantograph/setup/setup.rb', line 74

def initialize(project_path: nil, had_multiple_projects_to_choose_from: nil, preferred_setup_method: nil)
  self.project_path = project_path
  self.had_multiple_projects_to_choose_from = had_multiple_projects_to_choose_from
  self.preferred_setup_method = preferred_setup_method
end

Instance Attribute Details

#had_multiple_projects_to_choose_fromObject

remember if there were multiple projects if so, we set it as part of the Pantfile



16
17
18
# File 'pantograph/lib/pantograph/setup/setup.rb', line 16

def had_multiple_projects_to_choose_from
  @had_multiple_projects_to_choose_from
end

#lane_to_mentionObject

This is the lane that we tell the user to run to try the new pantograph setup This needs to be setup by each setup



23
24
25
# File 'pantograph/lib/pantograph/setup/setup.rb', line 23

def lane_to_mention
  @lane_to_mention
end

#pantfile_contentObject

The current content of the generated Pantfile



19
20
21
# File 'pantograph/lib/pantograph/setup/setup.rb', line 19

def pantfile_content
  @pantfile_content
end

#platformObject

:maven, :gradle, or other



6
7
8
# File 'pantograph/lib/pantograph/setup/setup.rb', line 6

def platform
  @platform
end

#preferred_setup_methodObject

Used for :manual sometimes



12
13
14
# File 'pantograph/lib/pantograph/setup/setup.rb', line 12

def preferred_setup_method
  @preferred_setup_method
end

#project_pathObject

Path to the xcodeproj or xcworkspace



9
10
11
# File 'pantograph/lib/pantograph/setup/setup.rb', line 9

def project_path
  @project_path
end

Class Method Details

.startObject

Start the setup process



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
# File 'pantograph/lib/pantograph/setup/setup.rb', line 27

def self.start
  if PantographCore::PantographFolder.setup? && !Helper.test?
    require 'pantograph/lane_list'
    Pantograph::LaneList.output(PantographCore::PantographFolder.pantfile_path)
    UI.important("------------------")
    UI.important("pantograph is already set up at path `#{PantographCore::PantographFolder.path}`, see the available lanes above")
    UI.message("")

    setup_generic = self.new
    setup_generic.add_or_update_gemfile(update_gemfile_if_needed: false)
    setup_generic.suggest_next_steps
    return
  end

  # this is used by e.g. configuration.rb to not show warnings when running produce
  ENV["PANTOGRAPH_ONBOARDING_IN_PROCESS"] = 1.to_s

  spinner = TTY::Spinner.new('[:spinner] Looking for projects in current directory...', format: :dots)
  spinner.auto_spin

  maven_projects   = Dir["**/pom.xml"]
  gradle_projects  = Dir["**/*.gradle"] + Dir["**/*.gradle.kts"]
  angular_projects = Dir['**/package.json']
  spinner.success

  PantographCore::PantographFolder.create_folder!

  if maven_projects.count > 0
    UI.message('Detected an Maven project in the current directory...')
    SetupMaven.new.setup_maven
  elsif gradle_projects.count > 0
    UI.message('Detected an Gradle project in the current directory...')
    SetupGradle.new.setup_gradle
  elsif angular_projects.count > 0
    UI.message('Detected an Angular project in the current directory...')
    SetupAngular.new.setup_angular
  else
    UI.error('Unable to determin project type')
    UI.error('Make sure to `cd` into the directory containing your application')
    if UI.confirm('Alternatively, would you like to manually setup a GENERIC pantograph config in the current directory instead?')
      SetupGeneric.new.setup_generic
    else
      UI.user_error!('Make sure to `cd` into the directory containing your project and then use `pantograph init` again')
    end
  end
end

Instance Method Details

#add_or_update_gemfile(update_gemfile_if_needed: false) ⇒ Object

This method is responsible for ensuring there is a working Gemfile, and that ‘pantograph` is defined as a dependency while also having `rubygems` as a gem source



174
175
176
177
178
179
180
181
182
183
# File 'pantograph/lib/pantograph/setup/setup.rb', line 174

def add_or_update_gemfile(update_gemfile_if_needed: false)
  if gemfile_exists?
    ensure_gemfile_valid!(update_gemfile_if_needed: update_gemfile_if_needed)
  else
    if update_gemfile_if_needed || UI.confirm("It is recommended to run pantograph with a Gemfile set up, do you want pantograph to create one for you?")
      setup_gemfile!
    end
  end
  return gemfile_path
end

#append_lane(lane) ⇒ Object

Append a lane to the current Pantfile template we’re generating



88
89
90
91
92
93
94
95
# File 'pantograph/lib/pantograph/setup/setup.rb', line 88

def append_lane(lane)
  lane.compact! # remove nil values

  new_lines = "\n\n"
  new_lines = "" unless self.pantfile_content.include?("lane :") # the first lane we don't want new lines

  self.pantfile_content.gsub!("[[LANES]]", "#{new_lines}#{lane.join("\n")}[[LANES]]")
end

#continue_with_enterObject



211
212
213
# File 'pantograph/lib/pantograph/setup/setup.rb', line 211

def continue_with_enter
  UI.input("Continue by pressing Enter ⏎")
end

#ensure_gemfile_valid!(update_gemfile_if_needed: false) ⇒ Object



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'pantograph/lib/pantograph/setup/setup.rb', line 147

def ensure_gemfile_valid!(update_gemfile_if_needed: false)
  gemfile_content = File.read(gemfile_path)
  unless gemfile_content.include?("https://rubygems.org")
    UI.error("You have a local Gemfile, but RubyGems isn't defined as source")
    UI.error("Please update your Gemfile at path `#{gemfile_path}` to include")
    UI.important("")
    UI.important("source \"https://rubygems.org\"")
    UI.important("")
    UI.error("Update your Gemfile, and run `bundle update` afterwards")
  end

  unless gemfile_content.include?("pantograph")
    if update_gemfile_if_needed
      gemfile_content << "\n\ngem \"pantograph\""
      UI.message("Adding `pantograph` to your existing Gemfile at path '#{gemfile_path}'")

      File.write(gemfile_path, gemfile_content)
    else
      UI.error("You have a local Gemfile, but it doesn't include \"pantograph\" as a dependency")
      UI.error("Please add `gem \"pantograph\"` to your Gemfile")
    end
  end
end

#explain_conceptsObject



197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'pantograph/lib/pantograph/setup/setup.rb', line 197

def explain_concepts
  UI.header("pantograph lanes")
  UI.message("pantograph uses a " + "`Pantfile`".yellow + " to store the automation configuration")
  UI.message("Within that, you'll see different " + "lanes".yellow + ".")
  UI.message("Each is there to automate a different task, like testing, building, or pushing new releases")
  continue_with_enter

  UI.header("How to customize your Pantfile")
  UI.message("Use a text editor of your choice to open the newly created Pantfile and take a look")
  UI.message("You can now edit the available lanes and actions to customize the setup to fit your needs")
  UI.message("To get a list of all the available actions, open " + "https://urbanquakers.github.io/pantograph/".cyan)
  continue_with_enter
end

#finish_upObject



185
186
187
188
189
190
# File 'pantograph/lib/pantograph/setup/setup.rb', line 185

def finish_up
  write_pantfile!
  show_analytics_note
  explain_concepts
  suggest_next_steps
end

#gemfile_exists?Boolean

Gemfile related code:

Returns:



121
122
123
# File 'pantograph/lib/pantograph/setup/setup.rb', line 121

def gemfile_exists?
  return File.exist?(gemfile_path)
end

#gemfile_pathObject



116
117
118
# File 'pantograph/lib/pantograph/setup/setup.rb', line 116

def gemfile_path
  "Gemfile"
end

#pantfile_template_contentObject



192
193
194
195
# File 'pantograph/lib/pantograph/setup/setup.rb', line 192

def pantfile_template_content
  path = "#{Pantograph::ROOT}/lib/assets/DefaultPantfileTemplate"
  return File.read(path)
end

#setup_gemfile!Object



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'pantograph/lib/pantograph/setup/setup.rb', line 125

def setup_gemfile!
  # No Gemfile yet
  gemfile_content = []
  gemfile_content << "source \"https://rubygems.org\""
  gemfile_content << ""
  gemfile_content << 'gem "pantograph"'
  gemfile_content << ""
  File.write(gemfile_path, gemfile_content.join("\n"))

  UI.message("Installing dependencies for you...")
  PantographCore::CommandExecutor.execute(
    command: "bundle update",
    print_all: PantographCore::Globals.verbose?,
    print_command: true,
    error: proc do |error_output|
      UI.error("Something went wrong when running `bundle update` for you")
      UI.error("Please take a look at your Gemfile at path `#{gemfile_path}`")
      UI.error("and make sure you can run `bundle update` on your machine.")
    end
  )
end

#show_analytics_noteObject



231
232
233
234
# File 'pantograph/lib/pantograph/setup/setup.rb', line 231

def show_analytics_note
  UI.message("pantograph will collect the number of errors for each action to detect integration issues")
  UI.message("No sensitive/private information will be uploaded, more information: " + "https://urbanquakers.github.io/pantograph/#metrics".cyan)
end

#suggest_next_stepsObject



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'pantograph/lib/pantograph/setup/setup.rb', line 215

def suggest_next_steps
  UI.header("Where to go from here?")
  UI.message("📸  Learn more about Pantograph Official Actions")
  UI.message("\t\thttps://urbanquakers.github.io/pantograph/actions/".cyan)
  UI.message("👩‍✈️  Learn more about Pantograph Lane Features")
  UI.message("\t\thttps://urbanquakers.github.io/pantograph/advanced/lanes/".cyan)
  UI.message("🚀  Check out the entire documentation site for Pantograph")
  UI.message("\t\thttps://urbanquakers.github.io/pantograph/".cyan)

  # we crash here, so that this never happens when a new setup method is added
  return if self.lane_to_mention.to_s.length == 0
  UI.message("")
  UI.message("To try your new pantograph setup, just enter and run")
  UI.command("pantograph #{self.lane_to_mention}")
end

#welcome_to_pantographObject

Helpers



81
82
83
84
85
# File 'pantograph/lib/pantograph/setup/setup.rb', line 81

def welcome_to_pantograph
  UI.header("Welcome to pantograph 🚀")
  UI.message("pantograph can help you with all kinds of automation")
  UI.message("We recommend automating one task first, and then gradually automating more over time")
end

#write_pantfile!Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'pantograph/lib/pantograph/setup/setup.rb', line 97

def write_pantfile!
  # Write the Pantfile
  pantfile_file_name = "Pantfile"

  pantfile_path = File.join(PantographCore::PantographFolder.path, pantfile_file_name)
  self.pantfile_content.gsub!("[[LANES]]", "") # since we always keep it until writing out
  File.write(pantfile_path, self.pantfile_content) # remove trailing spaces before platform ends

  add_or_update_gemfile(update_gemfile_if_needed: true)

  UI.header("✅  Successfully generated pantograph configuration")
  UI.message("Generated Pantfile at path `#{pantfile_path}`")
  UI.message("Gemfile and Gemfile.lock at path `#{gemfile_path}`")

  UI.message("Please check the newly generated configuration files into git along with your project")
  UI.message("This way everyone in your team can benefit from your pantograph setup")
  continue_with_enter
end