openSUSE:OSC plugins

Μετάβαση σε: πλοήγηση, αναζήτηση
Αυτό το έγγραφο δείχνει πώς να γράψετε πρόσθετα (plugins) για το osc, και πώς να χρησιμοποιήσετε το άρθρωμα osc από εξωτερικά σενάρια python.


Είναι πιθανότατα καλύτερο να δοθεί μέσω παραδειγμάτων.

Έστω, ότι θέλετε να γράψετε ένα σενάριο το οποίο ψάχνει στο έργο openSUSE:Tools και δείχνει μετά-δεδομένα από όλα τα πακέτα εντός του έργου.

Μπορείτε να το κάνετε κάπως έτσι:

#!/usr/bin/python

import os

project = 'openSUSE:Tools'

def run(command):
    input, output = os.popen2(command)
    lines = output.readlines()
    return lines

lines = run('osc ls ' + project)
for line in lines:
    package = line.rstrip('\n')
    meta = run('osc meta pkg ' + project + ' ' + package)
    for line in meta:
        print line

Αλλά με αυτόν τον τρόπο, καλείτε το osc μόνο ως εξωτερική διεργασία. Αυτό σημαίνει ότι το osc αρχικοποιείται κάθε φορά και ότι δεν μπορείτε να προσπελάσετε εσωτερικές δυνατότητες του osc.

Αντί αυτού, θα μπορούσατε να γράψετε ένα σενάριο το οποίο κάνει import το άρθρωμα osc, και το χρησιμοποιεί:

#!/usr/bin/python

import os
import osc.conf
import osc.core

project = 'openSUSE:Tools'

# initialize osc configuration
osc.conf.get_config()
packages = osc.core.meta_get_packagelist(osc.conf.config['apiurl'], 
                                       project)
για πακέτο σε πακέτα:

    m = osc.core.show_package_meta(osc.conf.config['apiurl'], project, package)
    print ''.join(m)

Αυτό είναι ευκολότερο.

Τώρα, ας πούμε ότι γράψατε κάτι το οποίο θα μπορούσε να είναι πιο χρήσιμο γενικά. Θα είχε νόημα να ενσωματώσετε τη λειτουργικότητα ως νέα εντολή του osc; Αν ναι, είναι εύκολο να το κάνετε. Προσαρμοσμένες εντολές μπορούν να πεταχτούν στο ~/.osc-plugins ή στο /var/lib/osc-plugins, και θα φορτώνονται από το osc από εκεί. Το παραπάνω απόσπασμα θα μπορούσε να δείχνει κάπως έτσι:

def do_show_packages(self, subcmd, opts, project):
    """${cmd_name}: Show metadata of all packages in an project

    This command shows metadata of all packages in a given project.
    
    ${cmd_usage}
    ${cmd_option_list}
    """

    packages = meta_get_packagelist(conf.config['apiurl'], 
                                        project)

    for package in packages:
        m = show_package_meta(conf.config['apiurl'], project, package)
        print ''.join(m)

Το όνομα του αρχείου είναι σημαντικό: πρέπει να τελειώνει σε .py. Εκτός αυτού, δεν υπάρχουν περιορισμοί στο πως ονομάζεται, αν και είναι πιο σοφό το όνομα του αρχείου να ταιριάζει με το όνομα της εντολής που υλοποιεί.

Όταν γράφετε και αποσφαλματώνετε πρόσθετα για το osc, και κάτι δεν δουλεύει, βοηθάει το να ξέρετε που ακριβώς έγινε το λάθος. Το osc έχει μια επιλογή "--trace" (μπορείτε επίσης να προσθέσετε το "traceback=1" στο δικό σας ~/.oscrc για να το ενεργοποιήσετε μόνιμα). Επιπλέον μπορεί να βρείτε τις επιλογές "--debugger" και "--post-mortem" χρήσιμες.

Η υλοποιημένη μέθοδος πρέπει να ξεκινά με "do_". Υπάρχει κάτι άλλο που συμβαίνει. Ένα άρθρωμα python που ονομάζεται cmdln (δείτε στο pydoc osc.cmdln για περισσότερες πληροφορίες) και αυτόματα αναλαμβάνει την τεκμηρίωση, τον έλεγχο των ορισμάτων και άλλα. Μετά την εγκατάσταση του πρόσθετου, αν καλέσετε 'osc help', θα παρατηρήσετε μια νέα εντολή στο μακρινάρι της βοήθειας που εμφανίζεται:

   show_packages     Show metadata of all packages in an project

Η εντολή αυτόματα τεκμηριώνεται:

% osc help show_packages     
show_packages: Show metadata of all packages in an project

This command shows metadata of all packages in a given project.

usage:
    osc show_packages PROJECT

και μπορεί να κληθεί ως "osc show_packages <prj>".

Υπάρχουν κι άλλα. Είναι εύκολο να προσθέσετε επιλογές στην εντολή σας μέσω της γραμμής εντολών χρησιμοποιώντας decorators συναρτήσεων python. Αυτό γίνεται καλύτερα αναθεωρώντας υπάρχοντα κώδικα του osc με παρόμοια λειτουργικότητα. Περιηγηθείτε στο αρχείο "osc/commandline.py" που βρίσκεται στην tar αρχειοθήκη του πηγαίου κώδικα ή στο αποθετήριο του osc στο git.

Για να πάρετε μια γεύση των εσωτερικών συναρτήσεων του osc δείτε τα

pydoc osc.commandline
pydoc osc.core

για υψηλότερου και χαμηλότερου επιπέδου συναρτήσεις.

Εδώ είναι ένα πιο περίπλοκο παράδειγμα, το οποίο επίσης δείχνει πράγματα για τη γραμμή εντολών:

@cmdln.option('-q', '--quiet', action='store_true',
              help='do not show downloading progress')
@cmdln.option('--package', metavar='PACKAGE',
              help='only binaries of this package')
@cmdln.option('-d', '--destdir', default='.', metavar='DIR',
              help='destination directory')
def do_mirror_binaries(self, subcmd, opts, project, repository, architecture):
    """${cmd_name}: Mirror binaries of a project to local directory

    It does download directly from the api server. 
    
    Packages don't need to be "published" to be downloaded.

    ${cmd_usage}
    ${cmd_option_list}
    """

    # Get package list
    filenames = get_binarylist(conf.config['apiurl'],
                               project, repository, architecture,
                               package=opts.package)

    if not os.path.isdir(opts.destdir):
        print "Creating %s" % opts.destdir
        os.makedirs(opts.destdir, 0755)

    for filename in filenames:

        if os.path.exists('%s/%s' % (opts.destdir, filename)):
            continue

        target_filename = '%s/%s' % (opts.destdir, filename)

        get_binary_file(conf.config['apiurl'],
                        project, repository, architecture,
                        filename,
                        target_filename=target_filename,
                        package=opts.package,
                        progress_meter = not opts.quiet)

Η έξοδος της βοήθειας θα δείχνει κάπως έτσι:

% osc help mirror_binaries
mirror_binaries: Mirror binaries of a project to local directory

It does download directly from the api server.

Packages don't need to be "published" to be downloaded.

usage:
    osc mirror_binaries PROJECT REPOSITORY ARCHITECTURE 

options:
    -h, --help          show this help message and exit
    -d DIR, --destdir=DIR
                        destination directory
    --package=PACKAGE   only binaries of this package
    -q, --quiet         do not show downloading progress

Πολλά άλλα παραδείγματα μπορούν να βρεθούν ψάχνοντας μέσα στο <python-libdir>/osc/command.py.

Αυτή η μέθοδος είναι η αρμόζουσα για να παρακάμψετε, ή να βελτιώσετε οποιαδήποτε υπάρχουσα εντολή του osc. Αν δεν είστε ευχαριστημένοι από την εντολή ls, απλά γράψτε τη δική σας. Ή αν έχετε μια ιδέα για το πως να βελτιώσετε ή να προσθέσετε ένα νέο χαρακτηριστικό, αντιγράψτε και επικολλήστε την εντολή από το osc.command.py στο δικό σας κατάλογο προσθέτων του osc και αρχίστε να παίζετε πάνω της.

Υπάρχει μια διαφορά να σημειώσουμε μεταξύ μιας εντολής στο osc.command.py και μιας εντολής που έχει προστεθεί. Καθώς η μορφοποίηση έχει σημασία στην Python, χρειάζεται να προσθέσετε στην αρχή 4 κενά αν τα αντιγράψετε στο osc.command.py, ή να αφαιρέσετε 4 κενά στην αντίστροφη διαδικασία. Πέραν αυτού, απλή αντιγραφή και επικόλληση θα είναι εντάξει.

Και αν υλοποιήσατε μια πολύ καλή εντολή, που θα θέλατε να τη δείτε να ενσωματώνεται στο upstream του osc, γράψτε στη λίστα ηλεκτρονικού ταχυδρομείου του buildservice τώρα!

Το GNOME/OscGnome μπορεί να χρησιμοποιηθεί ως επιπλέον παράδειγμα: περιγράφει ένα πιο περίπλοκο σύστημα βασισμένο σε πρόσθετα για το osc plugins.

Συνεισφέροντας

Για να συνεισφέρετε στο osc:

  • Δημοσιεύστε σχετικά με το patch/ιδέα/διόρθωσή σας στη λίστα ηλεκτρονικού ταχυδρομείου του buildservice (opensuse-buildservice_AT_opensuse.org).
  • Επικοινωνήστε με τον adrian_AT_suse.de για να πάρετε πρόσβαση για υποβολές (commit). Αυτός επίσης θα τακτοποιήσει για τα μηνύματα υποβολών.