summaryrefslogblamecommitdiffstats
path: root/src/gns-deb-diff.py
blob: 173eaf197012f7535cd690bd12a72102f9c1c848 (plain) (tree)
1
2
3
4
5
6
7
8
9








                                                                   

                      
         
                          
                       

                   


                   
              
 





                            
                        





                                                  
                                            










                                              


                   
                               
       
                                                                       


                                  
                                                
 






                                                     
 







                                                                 
 


                                
       
                                                                       

                             


                                                                    
 
                    
       
                                                 
       
                                                      
 


                                                                           
 

                                   

                           

                                                       

                                                           





                                                                

                                         
         

                                                             



                                  
                       

                                                                    
 
                                      

                              
         

                                     
 









                                                              


                                                    
        
                                                 
                      
                                          






                                               






                                                                       






                                                                      



                     
                                








                                                          


                                                          


                    

                                




                                                                    
 

                                                                  

       
                                               





                                             

                                                           


                                     
                                    
 
 
                                    

                                                                         
 

       

                     
             

                                                                   

         

                                 
                                   






                                                                     











                                                       

                                                      



                         



                             
 

                  

                                   
                           

                                                        
                                    
 

                                                                  

          
# Copyright 2013 rsiddharth <rsiddharth@ninthfloor.org>
#
# This work is free. You can redistribute it and/or modify it under
# the terms of the Do What The Fuck You Want To Public License,
# Version 2, as published by Sam Hocevar. See the COPYING file or
# <http://www.wtfpl.net/> for more details.

import subprocess as child
import shlex
import os.path as path
import os
import re
from sys import exit, argv
import gns_wiki as wiki

# global variables.
bzr_base_url = None
local_dir = None
pkgs_file = None
src_dir = None

# list of recognized fields.
field_list = [
    "Change-Type",
    "Changed-From-Debian",
    ]

def get_packages_list():
    """
    Return a list of package names from pkgs_file.
    """
    global pkgs_file

    try:
        packages_file = open(pkgs_file, 'r')
    except IOError, e:
        print "Trouble opening %r" % pkgs_file
        print e
        return None

    packages = []
    for package in packages_file.readlines():
        packages.append(package.strip())

    packages_file.close()

    return packages


def mirror_bzr_branch(package):
    """
    Create/update a local bzr branch of the package from remote branch.
    """
    global bzr_base_url, local_dir

    local_pkg_dir = path.join(local_dir,package)

    if path.exists(local_pkg_dir):
        current_dir = os.getcwd()
        os.chdir(local_pkg_dir)

        command = "bzr pull %s/%s" % (bzr_base_url,
                                      package)
        returncode = child.call(shlex.split(command))

        # back to current dir
        os.chdir(current_dir)
    else:
        # package doesn't exists so locally create one.
        command = "bzr branch %s/%s %s" % (bzr_base_url, package,
                                              local_pkg_dir)

        returncode = child.call(shlex.split(command))

    return returncode

def get_packages(packages_list):
    """
    Create/update a local bzr branch for each package in packages list.
    """
    for pkg in packages_list:
        code = mirror_bzr_branch(pkg)

        assert code == 0, "bzr branch mirroring for %s FAILED" % pkg

def process_input():
    """
    Read relevant values from argv to start work.
    """
    global bzr_base_url, local_dir, pkgs_file, src_dir

    # defaults
    remote_bzr_url = "bzr://bzr.savannah.gnu.org/gnewsense/packages-parkes"
    local_packages_directory = "~/gnewsense/packages-parkes"

    src_dir = path.dirname(argv[0])

    try:
        pkgs_file = argv[1]
    except IndexError:
        print "format: python path/to/gns-deb-diff.py \
packages-list-file local-packages-directory remote-bzr-url\
\n\n`local-packages-directory' & 'remote-bzr-url' are \
optional\ndefault values:\n\tlocal-packages-directory: %s\n\t\
remote-bzr-url: %s" % (remote_bzr_url, local_packages_directory)
        exit(1)


    # check if the local-packages-directory is given
    if (len(argv) > 2):
        local_dir = path.abspath(argv[2])
    else:
        # stick with default directory
        local_dir = path.expanduser(local_packages_directory)

    if not path.isdir(local_dir):
        try:
            os.makedirs(local_dir)
        except OSError:
            print "ERROR: Unable to create %s directory" % local_dir
            exit(1)

    # check if remote_bzr_url is given
    if (len(argv) > 3):
        bzr_base_url = argv[3]
    else:
        # stick with default url
        bzr_base_url = remote_bzr_url


def read_gns_readme(package):
    """
    Reads & returns the README.gNewSense file for the package.

    If the README.gNewSense is not present, it returns None.
    """

    global local_dir

    readme_file_path = path.join(local_dir, package,
    "debian/README.gNewSense")

    try:
        readme_file = open(readme_file_path, 'r')
    except IOError, e:
        # README.gNewSense file not found.
        return None # give up!

    readme_content = readme_file.read().strip()
    readme_file.close()

    return readme_content

def generate_tuple(package, readme_content):
    """Generates a tuple of the diff table.

    Keyword arguments:
    package -- name of package
    readme_content -- content of the README.gNewSense for this package.


    Returns a dict of the form {'pkg': package_name, 'Change-Type':
    "Added/Removed/Modified", 'Changed-From-Debian': 'one line
    description'}

    The value for keys `Change-Type' & `Changed-Frome-Debian' is None,
    if values for those are not present in the README.gNewSense.
    """

    global field_list

    pkg_tuple = {"pkg": package}

    for field in field_list:
        pattern = r"%s:\s*(.+)" % field
        field_pattern = re.compile(pattern)
        field_match = field_pattern.search(readme_content)

        if not field_match is None:
            field_value = field_match.group(1)
            pkg_tuple[field] = field_value
        else:
            # This field is not present in the README, so:
            pkg_tuple[field] = None

    return pkg_tuple


def slurp_readmes(package_list):
    """Reads the README.gNewSense for each package in package_list \
and generates tuples for each package.

    Packages which doesn't have a README.gNewSense file is put in a
    seperate list.

    The function returns the tuple dict and a list of packages (if
    any), that doesn't have README.gNewSense file.
    """

    pkg_tuples = [] # will hold a list of dicts
    noreadme_pkgs = []

    for pkg in package_list:
        readme_content = read_gns_readme(pkg)

        if readme_content is not None:
            pkg_tuple = generate_tuple(pkg, readme_content)
            pkg_tuples.append(pkg_tuple)
        else:
            noreadme_pkgs.append(pkg)

    return pkg_tuples, noreadme_pkgs


def generate_diff_table(pkg_tuples):
    """Generates the gNewSense Debian Diff table in MoinMoin syntax and \
returns it as a string.

    """

    global field_list

    table = [
        "||'''Source Package'''||'''Change Type'''||'''Reason'''||\
'''More Info'''||",
        ]

    for pkg_tuple in pkg_tuples:
        # get package name first:
        pkg_name = pkg_tuple["pkg"]

        more_info_link = "http://bzr.savannah.gnu.org/lh/gnewsense/\
packages-parkes/%s/annotate/head:/debian/README.gNewSense" % pkg_name

        # start constructing a row for this package:
        row = "||%s" % pkg_name

        # add the `change type' & `reason' cells to row
        for field in field_list:
            field_value = pkg_tuple[field]

            if field_value is None:
                # insert a blank cell
                row += "|| "
            else:
                # insert the field value
                row += "||%s" % field_value

        # added `more info link' in another cell
        row += "||[[%s|more info]]||" % more_info_link

        table.append(row)

    return table

def do_magic():
    """
    Does what it has to do :)
    """

    global src_dir

    process_input()
    pkgs_list = get_packages_list()
    get_packages(pkgs_list)
    pkg_tuples, noreadme_pkgs = slurp_readmes(pkgs_list)
    diff_table = generate_diff_table(pkg_tuples)
    wiki.update(diff_table, src_dir)

    if(len(noreadme_pkgs) != 0):
        print "README.gNewSense not found for: %s" % noreadme_pkgs

do_magic()