Formatter du code¶
Il est important de pouvoir suivre des règles dans l’écriture de code. Cela permet notamment une lecture (ou relecture) de code plus simple et de pouvoir partager avec d’autres développeur le travail réalisé. Il me parait indispensable lors d’une revue de code d’avoir un code formatté.
Heureusement il existe de nombreux outils qui facilite ce travail.
Note
Il est possible de réaliser le “format” de notre code via notre éditeur préféré vim, puisque ce dernier permet de lancer des commandes depuis son interface
Nous allons traiter les principaux languages que j’utilise
XML¶
Il existe un utilitaire pour traiter du code xml xmllint. Il existe une version windows (non testé) sur le site http://code.google.com/p/xmllint/
Pour debian son installation est simple
apt-get install libxml2-utils
Concernant son utilisation, nous avons un fichier nommé toto.xml contenant
<tutu><a>a</a><b>b</b></tutu>
on traite le fichier par xmllin
xmllint --format toto.xml --output toto.xml
et on obtient un fichier xml contenant
<?xml version="1.0"?>
<tutu>
<a>a</a>
<b>b</b>
</tutu>
Note
xmllint fait beaucoup plus, il peut utiliser un xpath pour faire de la recherche dans les fichiers xml
xmllint --xpath "/bookstore/book/price" books.xml
Java¶
Il existe une librairie java externe qui réalise cette tâche: jalopy.
Il est hebergé sur sourceforge et il existe sous forme de plugin pour eclipse par exemple.
son installation
wget http://sourceforge.net/projects/jalopy/files/plugin%20console/0.1-1.5rc3/jalopy-console-0.1-1.5rc3.zip/download
mv download jalopy-1.5.zip
unzip jalopy-1.5.zip
cd jalopy-console-0.1-1.5rc3
On peut obtenir le manuel de jalopy sur http://jalopy.sourceforge.net/existing/manual.html
On trouve deux fichier pour lancer jalopy :
- un fichier sh pour linux
- un fichier bat pour windows
mais cela revien à faire
java -cp lib/jalopy.jar:lib/jalopy-console.jar:lib/log4j.jar:lib/getopt.jar de.hunsicker.jalopy.plugin.console.ConsolePlugin -v
Note
on peut faire plus simple concernant cette ligne de commande
java -classpath lib/* de.hunsicker.jalopy.plugin.console.ConsolePlugin -v
Prenons l’exemple du fichier test/Test.java contenant le code
public class Test {
private String x = "hello ";
public String getText(String name) {
string s = x + name;return s;}}
Note
ce code est valide, java ne gère pas d’indentation
Nous allons traiter ce fichier par jalopy
java -cp lib/jalopy.jar:lib/jalopy-console.jar:lib/log4j.jar:lib/getopt.jar de.hunsicker.jalopy.plugin.console.ConsolePlugin test/Test.java
et nous obtenons
public class Test {
private String x = "hello ";
public String getText(String name) {
string s = x + name;
return s;
}
}
On peut traiter un répertoire entier via l’argument
jalopy -r myDir
On peut aussi faire que le traitement n’écrase pas les originaux
jalopy -d /otherDir
Afin de rendre l’utilisation plus simple de jalopy on peut:
- placer le soft dans /opt
- ajouter un alias dans son .bashrc
alias jalopy="java -cp /opt/jalopy/lib/jalopy.jar:/opt/jalopy/lib/jalopy-console.jar:/opt/jalopy/lib/log4j.jar:/opt/jalopy/lib/getopt.jar de.hunsicker.jalopy.plugin.console.ConsolePlugin"
SQL¶
Pour sql on va utiliser un module python nommer sqlparse. Il fonctionne avec toutes versions de Python supérieur à 2.5
apt-get install python-pip
pip install sqlparse
Son utilisation est assez simple
import sqlparse
code="SELECT tutu,titi from toto"
r = sqlparse.format(code, reindent=True, keyword_case='upper')
print(r)
Python¶
Python possède son propre outil de contrôle qui valide le code python par rapport à la norme identifié dans le pep8 de python.
pip install pep8
pip install autopep8
Son utilisation est assez simple
import pep8
import autopep8
r = autopep8.fix_code(code)
print(r)
Pour la gestion de fichier en Python, XML et SQL sans passer par une console python, on peut utiliser le code suivant, placé dans le fichier prettycode.py
import sys
import locale
from optparse import OptionParser
VERSION="0.2"
PROG="prettycode"
DESCRIPTION="""format code"""
AUTHOR="Frederic Aoustin"
PARAMS_PARSER = {
'sql' : "'reindent' : True, 'keyword_case' : 'upper'",
'python' : "",
'xml' : ""
}
is_Windows = sys.platform.startswith('win')
if is_Windows:
import ctypes
strcpy = ctypes.cdll.msvcrt.strcpy
ocb = ctypes.windll.user32.OpenClipboard #Basic Clipboard functions
ecb = ctypes.windll.user32.EmptyClipboard
gcd = ctypes.windll.user32.GetClipboardData
scd = ctypes.windll.user32.SetClipboardData
ccb = ctypes.windll.user32.CloseClipboard
ga = ctypes.windll.kernel32.GlobalAlloc # Global Memory allocation
gl = ctypes.windll.kernel32.GlobalLock # Global Memory Locking
gul = ctypes.windll.kernel32.GlobalUnlock
GMEM_DDESHARE = 0x2000
if sys.version_info < (3, 0):
str = unicode
import sqlparse
else:
import sqlparse3 as sqlparse
import pep8
import autopep8
import xml.dom.minidom
if __name__ == '__main__':
parser = OptionParser(version="%s %s" % (PROG,VERSION))
parser.description= DESCRIPTION
parser.epilog = AUTHOR
parser.add_option("-i", "--file-in",
dest = "ifile",
help = "file format",
default = None,
type = "string")
parser.add_option("-o", "--file-out",
dest = "ofile",
help = "file formatting",
default = None ,
type = "string")
parser.add_option("-s", "--syntax",
dest = "syntax",
choices = ['sql','python','xml'],
help ="syntax format",
default = "sql",
type = "choice")
parser.add_option("-e", "--encoding",
dest = "encoding",
help = "encoding data (default: %s)" % locale.getdefaultlocale()[1],
default = locale.getdefaultlocale()[1],
type = "string")
parser.add_option("-p", "--other-parameter",
dest = "args",
help = "add parameter for parser (%s)" % ('; '.join([i+' => '+ PARAMS_PARSER[i] for i in PARAMS_PARSER.keys()])) ,
default = None,
type = "string")
try:
(options, args) = parser.parse_args()
if options.args == None:
options.args = PARAMS_PARSER[options.syntax]
exec("args = {%s}" % options.args)
if options.ifile == None:
if is_Windows:
ocb(None)
p_contents = gcd(1)
code = str(ctypes.c_char_p(p_contents).value, options.encoding)
ccb()
else:
raise AttributeError("file in is unknown")
else:
f = open(options.ifile,'r')
code = ''.join(f.readlines())
f.close()
if options.syntax == 'sql':
result_parser = sqlparse.format(code, **args)
if options.syntax == 'python':
result_parser = autopep8.fix_code(code, **args)
if options.syntax == 'xml':
xml = xml.dom.minidom.parseString(code)
result_parser = xml.toprettyxml()
if options.ofile != None:
f = open(options.ofile,'w')#, encoding='utf-8')
f.write(result_parser)
f.close()
else:
print(result_parser)
except Exception as e:
print(parser.error(e))
parser.print_help()
sys.exit(1)
L’utilisation de ce programme est assez simple
python prettycode -i tutu.py -o tutu.py -s python