chiark / gitweb /
Merge branch 'master' of gitorious.org:f-droid/fdroidserver
authorCiaran Gultnieks <ciaran@ciarang.com>
Thu, 16 Jan 2014 10:18:10 +0000 (10:18 +0000)
committerCiaran Gultnieks <ciaran@ciarang.com>
Thu, 16 Jan 2014 10:18:10 +0000 (10:18 +0000)
1  2 
fdroidserver/build.py
fdroidserver/common.py

diff --combined fdroidserver/build.py
index b657da4866d06d7c0a40dac0b807ce94846a60b9,d52a033d211d60fee965332e3d297566c92dccf4..a5daac5329a4e7cb7d6562ab438abdf2437d2f33
@@@ -326,7 -326,6 +326,7 @@@ def build_server(app, thisbuild, vcs, b
          # Execute the build script...
          print "Starting build..."
          chan = sshs.get_transport().open_session()
 +        chan.get_pty()
          cmdline = 'python build.py --on-server'
          if force:
              cmdline += ' --force --test'
          cmdline += " %s:%s" % (app['id'], thisbuild['vercode'])
          chan.exec_command('bash -c ". ~/.bsenv && ' + cmdline + '"')
          output = ''
 -        error = ''
          while not chan.exit_status_ready():
              while chan.recv_ready():
                  output += chan.recv(1024)
 -            while chan.recv_stderr_ready():
 -                error += chan.recv_stderr(1024)
              time.sleep(0.1)
          print "...getting exit status"
          returncode = chan.recv_exit_status()
              if len(get) == 0:
                  break
              output += get
 -        while True:
 -            get = chan.recv_stderr(1024)
 -            if len(get) == 0:
 -                break
 -            error += get
          if returncode != 0:
 -            raise BuildException("Build.py failed on server for %s:%s" % (app['id'], thisbuild['version']), output, error)
 +            raise BuildException("Build.py failed on server for %s:%s" % (app['id'], thisbuild['version']), output)
  
          # Retrieve the built files...
          print "Retrieving build output..."
              ftp.get(apkfile, os.path.join(output_dir, apkfile))
              ftp.get(tarball, os.path.join(output_dir, tarball))
          except:
 -            raise BuildException("Build failed for %s:%s - missing output files" % (app['id'], thisbuild['version']), output, error)
 +            raise BuildException("Build failed for %s:%s - missing output files" % (app['id'], thisbuild['version']), output)
          ftp.close()
  
      finally:
@@@ -405,6 -412,7 +405,7 @@@ def build_local(app, thisbuild, vcs, bu
          p = FDroidPopen(cmd, cwd=maven_dir)
  
      elif thisbuild['type'] == 'gradle':
          print "Cleaning Gradle project..."
          cmd = [config['gradle'], 'clean']
  
          else:
              gradle_dir = root_dir
  
+         adapt_gradle(gradle_dir)
+         for name, number, libpath in srclibpaths:
+             adapt_gradle(libpath)
          p = FDroidPopen(cmd, cwd=gradle_dir)
  
      elif thisbuild['type'] == 'kivy':
  
      if p is not None and p.returncode != 0:
          raise BuildException("Error cleaning %s:%s" %
 -                (app['id'], thisbuild['version']), p.stdout, p.stderr)
 +                (app['id'], thisbuild['version']), p.stdout)
  
      # Scan before building...
      print "Scanning source for common problems..."
  
          if p.returncode != 0:
              raise BuildException("Error running build command for %s:%s" %
 -                    (app['id'], thisbuild['version']), p.stdout, p.stderr)
 +                    (app['id'], thisbuild['version']), p.stdout)
  
      # Build native stuff if required...
      if thisbuild.get('buildjni') not in (None, 'no'):
                  del manifest_text
              p = FDroidPopen([ndkbuild], cwd=os.path.join(root_dir,d))
              if p.returncode != 0:
 -                raise BuildException("NDK build failed for %s:%s" % (app['id'], thisbuild['version']), p.stdout, p.stderr)
 +                raise BuildException("NDK build failed for %s:%s" % (app['id'], thisbuild['version']), p.stdout)
  
      p = None
      # Build the release...
      elif thisbuild['type'] == 'gradle':
          print "Building Gradle project..."
          if '@' in thisbuild['gradle']:
-             flavour = thisbuild['gradle'].split('@')[0]
+             flavours = thisbuild['gradle'].split('@')[0].split(',')
              gradle_dir = thisbuild['gradle'].split('@')[1]
              gradle_dir = os.path.join(root_dir, gradle_dir)
          else:
-             flavour = thisbuild['gradle']
+             flavours = thisbuild['gradle'].split(',')
              gradle_dir = root_dir
  
  
                          's@compileSdkVersion[ ]*[0-9]*@compileSdkVersion '+level+'@g',
                          'build.gradle'], cwd=gradle_dir)
  
-         adapt_gradle(gradle_dir)
-         for name, number, libpath in srclibpaths:
-             adapt_gradle(libpath)
-         if flavour in ['main', 'yes', '']:
-             flavour = ''
+         if len(flavours) == 1 and flavours[0] in ['main', 'yes', '']:
+             flavours[0] = ''
  
          commands = [config['gradle']]
          if 'preassemble' in thisbuild:
              for task in thisbuild['preassemble'].split():
                  commands.append(task)
-         commands += ['assemble'+flavour+'Release']
+         commands += ['assemble'+''.join(flavours)+'Release']
  
          p = FDroidPopen(commands, cwd=gradle_dir)
  
          bindir = os.path.join(root_dir, 'bin')
  
      if p.returncode != 0:
 -        raise BuildException("Build failed for %s:%s" % (app['id'], thisbuild['version']), p.stdout, p.stderr)
 +        raise BuildException("Build failed for %s:%s" % (app['id'], thisbuild['version']), p.stdout)
      print "Successfully built version " + thisbuild['version'] + ' of ' + app['id']
  
      # Find the apk name in the output...
          dd = build_dir
          if 'subdir' in thisbuild:
              dd = os.path.join(dd, thisbuild['subdir'])
-         if flavour in ['main', 'yes', '']:
+         if len(flavours) == 1 and flavours[0] == '':
              name = '-'.join([os.path.basename(dd), 'release', 'unsigned'])
          else:
-             name = '-'.join([os.path.basename(dd), flavour, 'release', 'unsigned'])
+             name = '-'.join([os.path.basename(dd), '-'.join(flavours), 'release', 'unsigned'])
          src = os.path.join(dd, 'build', 'apk', name+'.apk')
      else:
          stdout_apk = '\n'.join([
@@@ -958,7 -965,7 +958,7 @@@ def main()
                      if len(txt) > 8192:
                          txt = txt[-8192:]
                      txt = "Build completed at " + time.strftime("%Y-%m-%d %H:%M:%SZ", time.gmtime()) + "\n\n" + txt
 -                    newpage.save(wikilog, summary='Build log')
 +                    newpage.save(txt, summary='Build log')
                  except:
                      print "Error while attempting to publish build log"
  
diff --combined fdroidserver/common.py
index 449105a0a13f9cd2f7014049cc392752748c80ef,3477124ba03905a70214206475f24edf886d6bc5..f30c3c8897d693b3a84c6d2d7fb42e20d47159df
@@@ -749,23 -749,31 +749,23 @@@ def parse_androidmanifests(paths)
      return (max_version, max_vercode, max_package)
  
  class BuildException(Exception):
 -    def __init__(self, value, stdout = None, stderr = None):
 +    def __init__(self, value, detail = None):
          self.value = value
 -        self.stdout = stdout
 -        self.stderr = stderr
 +        self.detail = detail
  
      def get_wikitext(self):
          ret = repr(self.value) + "\n"
 -        if self.stdout:
 -            ret += "=stdout=\n"
 +        if self.detail:
 +            ret += "=detail=\n"
              ret += "<pre>\n"
 -            ret += str(self.stdout)
 -            ret += "</pre>\n"
 -        if self.stderr:
 -            ret += "=stderr=\n"
 -            ret += "<pre>\n"
 -            ret += str(self.stderr)
 +            ret += str(self.detail)
              ret += "</pre>\n"
          return ret
  
      def __str__(self):
          ret = repr(self.value)
 -        if self.stdout:
 -            ret += "\n==== stdout begin ====\n%s\n==== stdout end ====" % self.stdout.strip()
 -        if self.stderr:
 -            ret += "\n==== stderr begin ====\n%s\n==== stderr end ====" % self.stderr.strip()
 +        if self.detail:
 +            ret += "\n==== detail begin ====\n%s\n==== detail end ====" % self.detail.strip()
          return ret
  
  class VCSException(Exception):
@@@ -847,7 -855,7 +847,7 @@@ def getsrclib(spec, srclib_dir, srclibp
              p = FDroidPopen(['bash', '-x', '-c', cmd], cwd=libdir)
              if p.returncode != 0:
                  raise BuildException("Error running prepare command for srclib %s"
 -                        % name, p.stdout, p.stderr)
 +                        % name, p.stdout)
  
          if srclib["Update Project"] == "Yes":
              print "Updating srclib %s at path %s" % (name, libdir)
              # Check to see whether an error was returned without a proper exit
              # code (this is the case for the 'no target set or target invalid'
              # error)
 -            if p.returncode != 0 or (p.stderr != "" and
 -                    p.stderr.startswith("Error: ")):
 +            if p.returncode != 0 or p.stdout.startswith("Error: "):
                  raise BuildException("Failed to update srclib project {0}"
 -                        .format(name), p.stdout, p.stderr)
 +                        .format(name), p.stdout)
  
              remove_signing_keys(libdir)
  
@@@ -917,7 -926,7 +917,7 @@@ def prepare_source(vcs, app, build, bui
          p = FDroidPopen(['bash', '-x', '-c', cmd], cwd=root_dir)
          if p.returncode != 0:
              raise BuildException("Error running init command for %s:%s" %
 -                    (app['id'], build['version']), p.stdout, p.stderr)
 +                    (app['id'], build['version']), p.stdout)
  
      # Generate (or update) the ant build file, build.xml...
      updatemode = build.get('update', 'auto')
              # Check to see whether an error was returned without a proper exit
              # code (this is the case for the 'no target set or target invalid'
              # error)
 -            if p.returncode != 0 or (p.stderr != "" and
 -                    p.stderr.startswith("Error: ")):
 +            if p.returncode != 0 or p.stdout.startswith("Error: "):
                  raise BuildException("Failed to update project at %s" % d,
 -                        p.stdout, p.stderr)
 +                        p.stdout)
  
      # Update the local.properties file...
      localprops = [ os.path.join(build_dir, 'local.properties') ]
          p = FDroidPopen(['bash', '-x', '-c', cmd], cwd=root_dir)
          if p.returncode != 0:
              raise BuildException("Error running prebuild command for %s:%s" %
 -                    (app['id'], build['version']), p.stdout, p.stderr)
 +                    (app['id'], build['version']), p.stdout)
  
      return (root_dir, srclibpaths)
  
@@@ -1403,11 -1413,9 +1403,11 @@@ class PopenResult
  
  def FDroidPopen(commands, cwd=None):
      """
 -    Runs a command the FDroid way and returns return code and output
 +    Run a command and capture the output.
  
 -    :param commands and cwd like in subprocess.Popen
 +    :param commands: command and argument list like in subprocess.Popen
 +    :param cwd: optionally specifies a working directory
 +    :returns: A PopenResult.
      """
  
      if options.verbose:
  
      result = PopenResult()
      p = subprocess.Popen(commands, cwd=cwd,
 -            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 +            stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  
      stdout_queue = Queue.Queue()
      stdout_reader = AsynchronousFileReader(p.stdout, stdout_queue)
      stdout_reader.start()
 -    stderr_queue = Queue.Queue()
 -    stderr_reader = AsynchronousFileReader(p.stderr, stderr_queue)
 -    stderr_reader.start()
  
 -    # Check the queues for output (until there is no more to get)
 -    while not stdout_reader.eof() or not stderr_reader.eof():
 -        # Show what we received from standard output
 +    # Check the queue for output (until there is no more to get)
 +    while not stdout_reader.eof():
          while not stdout_queue.empty():
              line = stdout_queue.get()
              if options.verbose:
                  sys.stdout.flush()
              result.stdout += line
  
 -        # Show what we received from standard error
 -        while not stderr_queue.empty():
 -            line = stderr_queue.get()
 -            if options.verbose:
 -                # Output directly to console
 -                sys.stderr.write(line)
 -                sys.stderr.flush()
 -            result.stderr += line
          time.sleep(0.1)
  
      p.communicate()
      return result
  
  def remove_signing_keys(build_dir):
+     comment = re.compile(r'[ ]*//')
+     signing_configs = re.compile(r'[\t ]*signingConfigs[ \t]*{[ \t]*$')
+     r_open = re.compile(r'.*{[\t ]*$')
+     r_close = re.compile(r'.*}[\t ]*$')
      for root, dirs, files in os.walk(build_dir):
          if 'build.gradle' in files:
              path = os.path.join(root, 'build.gradle')
              opened = 0
              with open(path, "w") as o:
                  for line in lines:
-                     if 'signingConfigs ' in line:
+                     if comment.match(line):
+                         pass
+                     elif signing_configs.match(line):
                          opened = 1
                          changed = True
                      elif opened > 0:
-                         if '{' in line:
+                         if r_open.match(line):
                              opened += 1
-                         elif '}' in line:
-                             opened -=1
+                         elif r_close.match(line):
+                             opened -= 1
                      elif any(s in line for s in (
                              ' signingConfig ',
                              'android.signingConfigs.',