Class: Xcodeci::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/xcodeci/command.rb

Class Method Summary collapse

Class Method Details

.execute_in_repo_folder(repository_url, &block) ⇒ Object



25
26
27
28
29
30
# File 'lib/xcodeci/command.rb', line 25

def self.execute_in_repo_folder (repository_url, &block)
  Dir.chdir "#{Xcodeci::HOME}/#{repository_name repository_url}"
  result = block.call
  Dir.chdir "#{Xcodeci::HOME}"
  result
end

.execute_in_workspace_folder(repository_url, workspace, &block) ⇒ Object



14
15
16
17
18
19
# File 'lib/xcodeci/command.rb', line 14

def self.execute_in_workspace_folder (repository_url, workspace ,&block)
  Dir.chdir workspace_folder repository_url, workspace
  result = block.call
  Dir.chdir "#{Xcodeci::HOME}"
  result
end

.repository_name(repo_url) ⇒ Object



21
22
23
# File 'lib/xcodeci/command.rb', line 21

def self.repository_name repo_url
  repo_url[repo_url.rindex('/') + 1..-1].sub('.git', '')
end

.root_output_folderObject



3
4
5
# File 'lib/xcodeci/command.rb', line 3

def self.root_output_folder
  File.join(@@dropbox_folder, "xcodeci")
end

.runObject



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
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
102
103
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
132
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
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/xcodeci/command.rb', line 33

def self.run
  # Create the folder for storing all the projects
  unless File.exists?(Xcodeci::HOME)
    Dir.mkdir File.join(Xcodeci::HOME) 
    FileUtils.cp_r File.join(Xcodeci::TEMPLATE, "xcodeci.conf.yaml"), File.join(Xcodeci::HOME, "xcodeci.conf.yaml") , :verbose => false
    puts "A sample configuration file was created on your ~/.xcodeci folder.".red
    exit 0
  end

  configuration = Configuration.new ( File.join(Xcodeci::HOME, "xcodeci.conf.yaml") )
  unless configuration.is_ok? 
    puts "Your configuration file is doesn't contain any project.".red
    exit(1)
  end

  @@dropbox_folder  = configuration.app_config[:DROPBOX_FOLDER]
  @@dropbox_user_id = configuration.app_config[:DROPBOX_USER_ID]


  database      = Database.new ( File.join(Xcodeci::HOME, "data.yaml") )
  gitUtils      = GitUtils.new
  buildUtils    = BuildUtils.new
  archiveUtils  = ArchiveUtils.new
  l             = Logger.new

  

  #TODO check if the configuration is ok
  puts "=== Start Loop ==="

  configuration.each_project do | project |
    puts "=== Start #{project[:APP_NAME]} ==="
    
    # Create the dropbox shared folder
    output_folder = File.join(root_output_folder, project[:APP_NAME])
    FileUtils.mkdir_p(output_folder) unless File.exists?(output_folder)

    # Cloning the repository
    puts "> Cloning the repository #{project[:REPO_URL]}"
    clone_result = gitUtils.cloning_repo project[:REPO_URL]
    puts l.log_result clone_result, "Repository clone"

    # Checkout, fetch and pull
    puts "> Updating the repository"

    last_commits = []
    execute_in_repo_folder(project[:REPO_URL]) {
      #Fetch the new commits
      fetch_result = gitUtils.fetch_repo
      puts l.log_result fetch_result, "Repository fetch"

      # Checkout the target branch
      checkout_result = gitUtils.checkout_repo project[:TARGET_BRANCH]
      puts l.log_result checkout_result, "Repository checkout"

      # Pull the repository
      pull_result = gitUtils.pull_repo
      puts l.log_result pull_result, "Repository pull"
    
      # Get list of the five most recent commits
      puts "> Getting list of commits"
      last_commits = gitUtils.get_commit_lists
      puts l.log_result true, "Found #{last_commits.length} commit(s)"
    }
    

    # Iterate on each commit to build
    last_commits.each do |commit_line|
      commit, email = commit_line.split(' ')

      puts "> Commit #{commit}"
      unless database.should_build_commit( project[:APP_NAME], commit)
        puts l.log_result false, "Commit #{commit} skipped"
        next
      end

      # Checkout del repository al commit specifico
      puts "> Rollaback repo to #{commit}"
      execute_in_repo_folder(project[:REPO_URL]) {
        rollback_result = gitUtils.rollback_repo commit
        puts l.log_result rollback_result, "Rollback"
      }
      

      # Run "Pod install" on the repository
      puts "> Updating dependencies"
      execute_in_workspace_folder(project[:REPO_URL], project[:WORKSPACE] ) {
        pod_result = buildUtils.install_pod
        puts l.log_result pod_result, "Pod installed"
      }
      



      # BUILD
      puts "> Build"
      build_result = false
      execute_in_workspace_folder(project[:REPO_URL], project[:WORKSPACE] ) {
        build_result = buildUtils.run_build(project[:REPO_URL], project[:WORKSPACE], project[:SCHEME])
        puts l.log_result build_result, "Build"
      }
      

      unless build_result
        test_result   = false
        puts l.log_result false, "Unit tests skipped"

        ipa_result    = false
        puts l.log_result false, "IPA build skipped"

        dsym_result   = false
        puts l.log_result false, "dSym copy skipped"

      else
        # Create the folder for storing the ipa files and the dSym file.
        output_folder = File.join(root_output_folder , project[:APP_NAME], commit)
        FileUtils.mkdir_p(output_folder) unless File.exists?(output_folder)

        # Run unit test
        puts "> Test"
        execute_in_workspace_folder(project[:REPO_URL], project[:WORKSPACE] ) {
          test_result = buildUtils.run_test(project[:REPO_URL], project[:WORKSPACE], project[:SCHEME])
          puts l.log_result test_result, "Unit Test"
        }

        # Create ipa file
        puts "> Archiving"
        execute_in_workspace_folder(project[:REPO_URL], project[:WORKSPACE] ) {
          ipa_result = archiveUtils.archive_ipa(project[:WORKSPACE], project[:SCHEME], "#{output_folder}/app.ipa")
          puts l.log_result ipa_result, "Create Ipa"
        }
        

        # Copy dSym frile from the "derivedata" folder.
        execute_in_workspace_folder(project[:REPO_URL], project[:WORKSPACE] ) {
          dsym_result = archiveUtils.save_dsym(project[:WORKSPACE], project[:SCHEME], "#{output_folder}/")
          puts l.log_result dsym_result, "Copy dSym"
        }
        

        # Extract info from the ipa file
        ipa_file = IpaReader::IpaFile.new("#{output_folder}/app.ipa")
        bundle_identifier = ipa_file.bundle_identifier
        bundle_version     = ipa_file.version

        # Copy the manifest
        manifest_template_path = File.join(Xcodeci::TEMPLATE, 'manifest.plist')
        manifest_template = File.open(manifest_template_path, 'rb') { |f| f.read }
        link = URI::encode("https://dl.dropboxusercontent.com/u/#{@@dropbox_user_id}/xcodeci/#{project[:APP_NAME]}/#{commit}/app.ipa")
        manifest_template.gsub!('__IPA_URL_PLACEHOLDER__', link)
        manifest_template.gsub!('__BUNDLE_IDENTIFIER_PLACEHOLDER__', bundle_identifier)
        manifest_template.gsub!('__VERSION_PLACEHOLDER__', bundle_version)
        manifest_template.gsub!("__APP_NAME_PLACEHOLDER__", project[:APP_NAME])


        output = File.join(root_output_folder, project[:APP_NAME],commit,'manifest.plist')
        File.open(output, 'w') { |file| file.write(manifest_template) }

      end
      commit_report = {
        build: build_result,
        test: test_result,
        ipa: ipa_result,
        dSym: dsym_result,
        author: email,
        date: Time.now
      }

      database.store_result project[:APP_NAME], commit, commit_report

    end # <- end loop commit
    puts "=== End #{project[:APP_NAME]} ==="
  end # <- End single project
  puts "=== End Loop ==="
  if (File.exists?(File.join(Xcodeci::HOME, "data.yaml")))
      # Create html report
      reporter = HtmlReporter.new File.join(Xcodeci::HOME, "data.yaml") , @@dropbox_user_id
      output = File.join(root_output_folder, 'index.html')
      File.open(output, 'w') { |file| file.write(reporter.html_report) }
      puts "You report it's available at: https://dl.dropboxusercontent.com/u/#{@@dropbox_user_id}/xcodeci/index.html"
      %x(open -a Safari #{output})
  end
  
end

.workspace_folder(repo_url, prj_workspace) ⇒ Object



7
8
9
10
11
12
# File 'lib/xcodeci/command.rb', line 7

def self.workspace_folder repo_url, prj_workspace
  folder_name = repo_url[repo_url.rindex('/') + 1..-1].sub('.git', '')
  folder_name = File.join(Xcodeci::HOME, folder_name)
  path = Dir.glob("#{folder_name}/**/#{prj_workspace}").first
  File.dirname(path)
end