Escriba un módulo Batch::Simple
que provee:
new
que recibe
'sort'
-n
, etc.
STDIN
STDOUT
STDERR
input
no se especifica se entenderá que es STDIN
.
Por ejemplo:
my $c = Batch::Simple->new(command => 'sort', stdin => $infile, options => $options);La llamada a
new
retorna un objeto de la clase Batch::Simple
.
Batch::Simple
disponen de un método run
que ejecutará el programa.
El método run
devuelve un objeto Batch::Simple::Result
que tiene los siguientes
atributos:
stdout
: La salida por STDOUT del programa
stderr
: La salida por STDERR del programa
status
: El contenido de $?
Escriba métodos de acceso a los atributos implicados.
Una posible implementación de run
consiste en redirigir los flujos de salida y de error durante
la ejecución a ficheros utilizando la metodología vista en la
sección Salvando Manejadores de Fichero 1.5.
Si no se especificaron valores para STDOUT
y STDERR
es posible usar ficheros temporales (veanse File::Temp
y File::Spec).
Para repasar la programación orientada a objetos en Perl puede repasar
el capítulo
Programación Orientada a Objetos
de los apuntes de LHP o mejor aún, usar Moose
y leer los siguientes artículos:
Para repasar la creación de módulos véase el capítulo Módulos de los apuntes de LHP.
Cree la estructura de directorios usando h2xs
o Module::Install
(Véase Module::Install::Philosophy):
pp2@nereida:~/src$ h2xs -X -A -n Batch::Simple Defaulting to backwards compatibility with perl 5.8.8 If you intend this module to be compatible with earlier perl versions, please specify a minimum perl version with the -b option. Writing Batch-Simple/lib/Batch/Simple.pm Writing Batch-Simple/Makefile.PL Writing Batch-Simple/README Writing Batch-Simple/t/Batch-Simple.t Writing Batch-Simple/Changes Writing Batch-Simple/MANIFESTAñada un directorio para el ejecutable e incluya su presencia dándolo de alta en el fichero
Batch-Simple/MANIFEST
y en la
entrada EXE_FILES
en la llamada a WriteMakefile
en el fichero Batch-Simple/Makefile.PL
:
pp2@nereida:~/src/Batch-Simple$ cat -n MANIFEST 1 Changes 2 Makefile.PL 3 MANIFEST 4 README 5 script/batch.pl 6 t/Batch-Simple.t 7 lib/Batch/Simple.pm pp2@nereida:~/src/Batch-Simple$ cat -n Makefile.PL 1 use ExtUtils::MakeMaker; 2 WriteMakefile( 3 NAME => 'Batch::Simple', 4 VERSION_FROM => 'lib/Batch/Simple.pm', # finds $VERSION 5 PREREQ_PM => {}, # e.g., Module::Name => 1.1 6 EXE_FILES => [ qw{script/batch.pl} ], 7 );Hay varias formas de garantizar que durante el periodo de desarrollo de una librería los ejecutables encuentran la librería. Uno es añadir
use blib
en el ejecutable:
pp2@nereida:~/src/Batch-Simple/script$ cat -n batch.pl 1 #!/usr/local/bin/perl -w 2 use strict; 3 use Carp; 4 use Getopt::Long; 5 use Pod::Usage; 6 use blib; 7 use Batch::Simple; . ....................el módulo blib busca por un directorio de tipo
blib
hasta 5 niveles por encima del actual. Observa que eso significa que trabajas
con la copia en blib
y no el original en lib
.
Por tanto deberás hacer make
para asegurarte la actualización de la copia.
Otra forma de garantizar que la librería se encuentra es incluirla en
la variable PERL5LIB
.
Puedes usar como ejemplo de aplicación
el tar.gz
que implementa un
producto de matrices en C en
la página asociada con estos apuntes
(fichero matrix.tar.gz)
You can think of every object in the repository as existing in a sort of two-dimensional coordinate system. The first coordinate is a particular revision tree, and the second coordinate is a path within that tree
Parece que en banot
esta instalado subversion.
Para crear un repositorio emita el comando svnadmin create
:
-bash-3.1$ uname -a Linux banot.etsii.ull.es 2.6.24.2 #3 SMP Fri Feb 15 10:39:28 WET 2008 i686 i686 i386 GNU/Linux -bash-3.1$ svnadmin create /home/loginname/repository/ -bash-3.1$ ls -l repository/ total 28 drwxr-xr-x 2 loginname apache 4096 feb 28 11:58 conf drwxr-xr-x 2 loginname apache 4096 feb 28 11:58 dav drwxr-sr-x 5 loginname apache 4096 feb 28 12:09 db -r--r--r-- 1 loginname apache 2 feb 28 11:58 format drwxr-xr-x 2 loginname apache 4096 feb 28 11:58 hooks drwxr-xr-x 2 loginname apache 4096 feb 28 11:58 locks -rw-r--r-- 1 loginname apache 229 feb 28 11:58 README.txt
Una alternativa a considerar es ubicar el repositorio en un dispositivo de almacenamiento portable (pendriver)
Ahora esta en condiciones de añadir proyectos
al repositorio creado usando svn import
:
[loginname@tonga]~/src/perl/> uname -a Linux tonga 2.6.24.2 #1 SMP Thu Feb 14 15:37:31 WET 2008 i686 i686 i386 GNU/Linux [loginname@tonga]~/src/perl/> pwd /home/loginname/src/perl [loginname@tonga]~/src/perl/> ls -ld /home/loginname/src/perl/Grammar-0.02 drwxr-xr-x 5 loginname Profesor 4096 feb 28 2008 /home/loginname/src/perl/Grammar-0.02 [loginname@tonga]~/src/perl/> svn import -m 'Grammar Extended Module' \ Grammar-0.02/ \ svn+ssh://banot/home/loginname/repository/Grammar Añadiendo Grammar-0.02/t Añadiendo Grammar-0.02/t/Grammar.t Añadiendo Grammar-0.02/lib Añadiendo Grammar-0.02/lib/Grammar.pm Añadiendo Grammar-0.02/MANIFEST Añadiendo Grammar-0.02/META.yml Añadiendo Grammar-0.02/Makefile.PL Añadiendo Grammar-0.02/scripts Añadiendo Grammar-0.02/scripts/grammar.pl Añadiendo Grammar-0.02/scripts/Precedencia.yp Añadiendo Grammar-0.02/scripts/Calc.yp Añadiendo Grammar-0.02/scripts/aSb.yp Añadiendo Grammar-0.02/scripts/g1.yp Añadiendo Grammar-0.02/Changes Añadiendo Grammar-0.02/README Commit de la revisión 2.
En general, los pasos para crear un nuevo proyecto son:
* mkdir /tmp/nombreProyecto * mkdir /tmp/nombreProyecto/branches * mkdir /tmp/nombreProyecto/tags * mkdir /tmp/nombreProyecto/trunk * svn mkdir file:///var/svn/nombreRepositorio/nombreProyecto -m 'Crear el proyecto nombreProyecto' * svn import /tmp/nombreProyecto \ file:///var/svn/nombreRepositorio/nombreProyecto \ -m "Primera versión del proyecto nombreProyecto"
La copia en Grammar-0.02
ha sido usada para la creación del proyecto,
pero no pertenece aún al proyecto. Es necesario descargar la copia del
proyecto que existe en el repositorio. Para ello usamos
svn checkout
:
[loginname@tonga]~/src/perl/> rm -fR Grammar-0.02 [loginname@tonga]~/src/perl/> svn checkout svn+ssh://banot/home/loginname/repository/Grammar Grammar A Grammar/t A Grammar/t/Grammar.t A Grammar/MANIFEST A Grammar/META.yml A Grammar/lib A Grammar/lib/Grammar.pm A Grammar/Makefile.PL A Grammar/scripts A Grammar/scripts/grammar.pl A Grammar/scripts/Calc.yp A Grammar/scripts/Precedencia.yp A Grammar/scripts/aSb.yp A Grammar/scripts/g1.yp A Grammar/Changes A Grammar/README Revisión obtenida: 2Ahora disponemos de una copia de trabajo del proyecto en nuestra máquina local:
[loginname@tonga]~/src/perl/> tree Grammar Grammar |-- Changes |-- MANIFEST |-- META.yml |-- Makefile.PL |-- README |-- lib | `-- Grammar.pm |-- scripts | |-- Calc.yp | |-- Precedencia.yp | |-- aSb.yp | |-- g1.yp | `-- grammar.pl `-- t `-- Grammar.t 3 directories, 12 files [loginname@tonga]~/src/perl/> [loginname@tonga]~/src/perl/> cd Grammar [loginname@tonga]~/src/perl/Grammar/> ls -la total 44 drwxr-xr-x 6 loginname Profesor 4096 feb 28 2008 . drwxr-xr-x 5 loginname Profesor 4096 feb 28 2008 .. -rw-r--r-- 1 loginname Profesor 150 feb 28 2008 Changes drwxr-xr-x 3 loginname Profesor 4096 feb 28 2008 lib -rw-r--r-- 1 loginname Profesor 614 feb 28 2008 Makefile.PL -rw-r--r-- 1 loginname Profesor 229 feb 28 2008 MANIFEST -rw-r--r-- 1 loginname Profesor 335 feb 28 2008 META.yml -rw-r--r-- 1 loginname Profesor 1196 feb 28 2008 README drwxr-xr-x 3 loginname Profesor 4096 feb 28 2008 scripts drwxr-xr-x 6 loginname Profesor 4096 feb 28 2008 .svn drwxr-xr-x 3 loginname Profesor 4096 feb 28 2008 tObserve la presencia de los subdirectorios de control
.svn
.
Ahora podemos modificar el proyecto y hacer públicos los cambios
mediante svn commit
:
loginname@tonga]~/src/perl/Grammar/> svn rm META.yml D META.yml [loginname@tonga]~/src/perl/Grammar/> ls -la total 40 drwxr-xr-x 6 loginname Profesor 4096 feb 28 2008 . drwxr-xr-x 5 loginname Profesor 4096 feb 28 12:34 .. -rw-r--r-- 1 loginname Profesor 150 feb 28 12:34 Changes drwxr-xr-x 3 loginname Profesor 4096 feb 28 12:34 lib -rw-r--r-- 1 loginname Profesor 614 feb 28 12:34 Makefile.PL -rw-r--r-- 1 loginname Profesor 229 feb 28 12:34 MANIFEST -rw-r--r-- 1 loginname Profesor 1196 feb 28 12:34 README drwxr-xr-x 3 loginname Profesor 4096 feb 28 12:34 scripts drwxr-xr-x 6 loginname Profesor 4096 feb 28 2008 .svn drwxr-xr-x 3 loginname Profesor 4096 feb 28 12:34 t [loginname@tonga]~/src/perl/Grammar/> echo "Modifico README" >> README [loginname@tonga]~/src/perl/Grammar/> svn commit -m 'Just testing ...' Eliminando META.yml Enviando README Transmitiendo contenido de archivos . Commit de la revisión 3.Observe que ya no es necesario especificar el lugar en el que se encuentra el repositorio: esa información esta guardada en los subdirectorios de administración de subversion
.svn
El servicio de subversion parece funcionar desde fuera de la red del centro. Véase la conexión desde una maquina exterior:
pp2@nereida:/tmp$ svn checkout svn+ssh://loginname@banot.etsii.ull.es/home/loginname/repository/Grammar Grammar loginname@banot.etsii.ull.es's password: loginname@banot.etsii.ull.es's password: A Grammar/t A Grammar/t/Grammar.t A Grammar/MANIFEST A Grammar/lib A Grammar/lib/Grammar.pm A Grammar/Makefile.PL A Grammar/scripts A Grammar/scripts/grammar.pl A Grammar/scripts/Calc.yp A Grammar/scripts/Precedencia.yp A Grammar/scripts/aSb.yp A Grammar/scripts/g1.yp A Grammar/Changes A Grammar/README Revisión obtenida: 3
svn add directorio_o_fichero svn remove directorio_o_fichero
svn commit -m "Nueva version"
svn update
Para evitar la solicitud de claves cada vez que se comunica con el repositorio establezca autentificación SSH automática. Para ver como hacerlo puede consultar las instrucciones en la sección 2.1.3 o en:
http://search.cpan.org/~casiano/GRID-Machine/lib/GRID/Machine.pod#INSTALLATION
Consulte también las páginas del manual Unix de
ssh
, ssh-key-gen
, ssh_config
, scp
, ssh-agent
, ssh-add
, sshd
Véase la sección Revision Specifiers en el libro de Subversion
Véase la sección Examining History en el libro de Subversion
Véase la sección Undoing Working Changes en el libro de Subversion
vim
sobre diff
gvim -d file1 file2
?
diffupdate
?
]c
?
[c
?
8]c
?
do
?
dp
?
:diffg
?
:12,20diffg
?
:buffers
?
:buffer 2
?
:diffg 3
?
:diffg batch.mine
?
:diffput
?
:12,20diffput
?
zo
?
zO
?
zc
?
zO
?
:vnew
?
CTRL-W v
?
:set foldmethod=manual
?
zf}
?
:diffthis
?
:diffsplit filename
?
:windo
?
vim
:
:1,5yank a :6,10yank b :tabedit | put a | vnew | put b :windo diffthis
svn
en su sección
Resolve Conflicts (Merging Others'
Changes)
vimdiff
patch
? ¿Cómo se crea un patch?
:diffpatch filename
? (Véase la sección Patches o Parches
en los apuntes de LHP)
:vert diffpatch filename
?
$ svn diff modulos.tex -r PREV:HEAD > patch $ vi :.!svn cat modulos.tex -r PREV :vert diffpatch patch
Side by side diffs are much more legible and useful than those in unified format or any other lineardiff
. By default, thesvn diff
command presents output in the unified format, though it has an option,--diff-cmd
, which allows you to specify the program that will perform thediff
. Passingvimdiff
as thediff
command doesn't work as the options passed bysvn diff
are a bit complicated:
Veamos que es así. Escribimos el siguiente programa de prueba:
generaciondecodigos@nereida:~/bin$ cat -n ./foo.pl 1 #!/usr/bin/perl 2 3 print "'$_' " for @ARGV; 4 print "\n";
Ejecución:
$ svn diff --diff-cmd=/home/generaciondecodigos/bin/foo.pl overloading.tex -rPREV Index: overloading.tex =================================================================== '-u' '-L' 'overloading.tex (revisión: 5112)' '-L' 'overloading.tex (copia de trabajo)' '.svn/tmp/tempfile.tmp' 'overloading.tex'El argumento
-u
indica que se debe usar unified format y el
argumento -L
especifica la etiqueta que describe la correspondiente
versión.
Es necesario escribir un wrapper que prescinda de esas opciones y que se quede con los nombres de los dos ficheros:
pp2@nereida:~$ cat -n bin/diffwrap.sh 1 #!/bin/sh 2 3 # Configure your favorite diff program here. 4 DIFF="/usr/bin/vimdiff" 5 6 # Subversion provides the paths we need as the sixth and seventh 7 # parameters. 8 LEFT=${6} 9 RIGHT=${7} 10 11 # Call the diff command (change the following line to make sense for 12 # your merge program). 13 $DIFF $LEFT $RIGHT 14 15 # Return an errorcode of 0 if no differences were detected, 1 if some were. 16 # Any other errorcode will be treated as fatal.Ahora podemos establecer que este programa sea nuestro comando
diff
para
svn
editando el fichero de configuración ~/.subversion/config
:
pp2@nereida:~/Lbook$ grep 'diff' ~/.subversion/config ### Set diff-cmd to the absolute path of your 'diff' program. ### Subversion's internal diff implementation. # diff-cmd = diff_program (diff, gdiff, etc.) ### Set diff3-cmd to the absolute path of your 'diff3' program. ### Subversion's internal diff3 implementation. # diff3-cmd = diff3_program (diff3, gdiff3, etc.) ### Set diff3-has-program-arg to 'true' or 'yes' if your 'diff3' ### program accepts the '--diff-program' option. # diff3-has-program-arg = [true | false] diff-cmd = /home/pp2/bin/diffwrap.sh
Véase la sección Keyword Substitution en el libro de Subversion
Subversion admite una variedad de protocolos de red para conectarse con el repositorio.
Con subversion viene el programa svnserve
que escucha por conexiones de red y soporta
un modo de autentificación simple. Sólo debe usarse si esta en una LAN privada. En el siguiente
ejemplo arranco el daemon svnserve
en banot
:
bash-3.2$ uname -a Linux banot.etsii.ull.es 2.6.18-128.1.16.el5 #1 SMP Tue Jun 30 06:10:28 EDT 2009 i686 i686 i386 GNU/Linux -bash-3.2$ svnserve --listen-port=4040 -d -r repository -bash-3.2$ ps -fA | grep svn casiano 11876 1 0 11:16 ? 00:00:00 svnserve --listen-port=4040 -d -r repository casiano 12036 11698 0 11:22 pts/0 00:00:00 grep svn
Ahora puedo acceder al proyecto vía svn
desde otra máquina:
casiano@tonga:~$ svn co svn://banot:4040/acme-svn/trunk chuchu A chuchu/t A chuchu/t/00.load.t A chuchu/t/perlcritic.t A chuchu/t/pod.t A chuchu/t/pod-coverage.t A chuchu/MANIFEST A chuchu/lib A chuchu/lib/Acme A chuchu/lib/Acme/SVN.pm A chuchu/Makefile.PL A chuchu/Changes A chuchu/Build.PL A chuchu/README Revisión obtenida: 6
Aunque no tengo permisos de ejecución:
casiano@tonga:~$ cd chuchu casiano@tonga:~/chuchu$ echo prueba > prueba.txt casiano@tonga:~/chuchu$ svn add prueba.txt A prueba.txt casiano@tonga:~/chuchu$ svn commit prueba.txt -m 'added prueba.txt' svn: Falló el commit (detalles a continuación): svn: falló la autorización
Habría que dar permisos de escritura al repositorio y crear usuarios (véase svnserve, a custom server y svnserve.conf para los detalles)
Consulte
En KDE puede instalar el cliente gráfico KDEsvn.
casiano@europa:/media/UDISK 2.0$ rsync -aue ssh banot:repository svnrepositories casiano@europa:/media/UDISK 2.0$ cd svnrepositories/ casiano@europa:/media/UDISK 2.0/svnrepositories$ ls -ltra total 24 drwxr-xr-x 7 casiano root 4096 2009-03-05 15:50 repository drwxr-xr-x 3 casiano root 4096 2009-03-18 13:11 . drwxr-xr-x 6 casiano root 16384 2009-03-18 13:12 .. casiano@europa:/media/UDISK 2.0/svnrepositories$ mv repository/ banotrepositoryIntente comunicarse con él usando el protocolo
file//
casiano@europa:/tmp$ svn ls file:///media/UDISK\ 2.0/svnrepositories/banotrepository acme-svn/ casiano@europa:/tmp$ svn ls file:///media/UDISK\ 2.0/svnrepositories/banotrepository/acme-svn branches/ trunk/