openSUSE:OSC plugins
Είναι πιθανότατα καλύτερο να δοθεί μέσω παραδειγμάτων.
Έστω, ότι θέλετε να γράψετε ένα σενάριο το οποίο ψάχνει στο έργο 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). Αυτός επίσης θα τακτοποιήσει για τα μηνύματα υποβολών.