header - poner - ¿Herramienta para agregar encabezados de licencia a archivos de origen?
que es tags h1 y cursiva (12)
Estoy buscando una herramienta que, a granel, agregue un encabezado de licencia a algunos archivos fuente, algunos de los cuales ya tienen el encabezado. ¿Hay alguna herramienta que inserte un encabezado, si aún no está presente?
Editar: intencionalmente no estoy marcando una respuesta a esta pregunta, ya que las respuestas son básicamente todas específicas del entorno y subjetivas
Aquí hay un script de Bash que hará el truco, suponiendo que tiene el encabezado de la licencia en el archivo license.txt:
Archivo addlicense.sh:
#!/bin/bash
for x in $*; do
head -$LICENSELEN $x | diff license.txt - || ( ( cat license.txt; echo; cat $x) > /tmp/file;
mv /tmp/file $x )
done
Ahora ejecuta esto en tu directorio fuente:
export LICENSELEN=`wc -l license.txt | cut -f1 -d '' ''`
find . -type f /(-name /*.cpp -o -name /*.h /) -print0 | xargs -0 ./addlicense.sh
Aquí hay uno que rodé en PHP para modificar archivos PHP. También tuve que borrar la información de la licencia anterior, por lo que primero reemplaza el texto anterior, luego agrega el nuevo texto inmediatamente después de la apertura.
<?php
class Licenses
{
protected $paths = array();
protected $oldTxt = ''/**
* Old license to delete
*/'';
protected $newTxt = ''/**
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/'';
function licensesForDir($path)
{
foreach(glob($path.''/*'') as $eachPath)
{
if(is_dir($eachPath))
{
$this->licensesForDir($eachPath);
}
if(preg_match(''#/.php#'',$eachPath))
{
$this->paths[] = $eachPath;
}
}
}
function exec()
{
$this->licensesForDir(''.'');
foreach($this->paths as $path)
{
$this->handleFile($path);
}
}
function handleFile($path)
{
$source = file_get_contents($path);
$source = str_replace($this->oldTxt, '''', $source);
$source = preg_replace(''#/</?php#'',"<?php/n".$this->newTxt,$source,1);
file_put_contents($path,$source);
echo $path."/n";
}
}
$licenses = new Licenses;
$licenses->exec();
Editar: si usa eclipse, hay un complemento
Escribí un script de python simple basado en la respuesta del Silver Dragon. Necesitaba una solución más flexible, así que se me ocurrió esto. Le permite agregar un archivo de cabecera a todos los archivos en un directorio, recursivamente. Opcionalmente, puede agregar una expresión regular con la que coincidan los nombres de los archivos, y una expresión regular con la que coincidan los nombres de los directorios y una expresión regular que no coincida con la primera línea del archivo. Puede usar este último argumento para verificar si el encabezado ya está incluido.
Este script omitirá automáticamente la primera línea de un archivo si comienza con un shebang (#!). Esto para no romper otros scripts que dependen de esto. Si no desea este comportamiento, tendrá que comentar 3 líneas en el encabezado.
aquí está:
#!/usr/bin/python
"""
This script attempts to add a header to each file in the given directory
The header will be put the line after a Shebang (#!) if present.
If a line starting with a regular expression ''skip'' is present as first line or after the shebang it will ignore that file.
If filename is given only files matchign the filename regex will be considered for adding the license to,
by default this is ''*''
usage: python addheader.py headerfile directory [filenameregex [dirregex [skip regex]]]
easy example: add header to all files in this directory:
python addheader.py licenseheader.txt .
harder example adding someone as copyrightholder to all python files in a source directory,exept directories named ''includes'' where he isn''t added yet:
python addheader.py licenseheader.txt src/ ".*/.py" "^((?!includes).)*$" "#Copyright .* Jens Timmerman*"
where licenseheader.txt contains ''#Copyright 2012 Jens Timmerman''
"""
import os
import re
import sys
def writeheader(filename,header,skip=None):
"""
write a header to filename,
skip files where first line after optional shebang matches the skip regex
filename should be the name of the file to write to
header should be a list of strings
skip should be a regex
"""
f = open(filename,"r")
inpt =f.readlines()
f.close()
output = []
#comment out the next 3 lines if you don''t wish to preserve shebangs
if len(inpt) > 0 and inpt[0].startswith("#!"):
output.append(inpt[0])
inpt = inpt[1:]
if skip and skip.match(inpt[0]): #skip matches, so skip this file
return
output.extend(header) #add the header
for line in inpt:
output.append(line)
try:
f = open(filename,''w'')
f.writelines(output)
f.close()
print "added header to %s" %filename
except IOError,err:
print "something went wrong trying to add header to %s: %s" % (filename,err)
def addheader(directory,header,skipreg,filenamereg,dirregex):
"""
recursively adds a header to all files in a dir
arguments: see module docstring
"""
listing = os.listdir(directory)
print "listing: %s " %listing
#for each file/dir in this dir
for i in listing:
#get the full name, this way subsubdirs with the same name don''t get ignored
fullfn = os.path.join(directory,i)
if os.path.isdir(fullfn): #if dir, recursively go in
if (dirregex.match(fullfn)):
print "going into %s" % fullfn
addheader(fullfn, header,skipreg,filenamereg,dirregex)
else:
if (filenamereg.match(fullfn)): #if file matches file regex, write the header
writeheader(fullfn, header,skipreg)
def main(arguments=sys.argv):
"""
main function: parses arguments and calls addheader
"""
##argument parsing
if len(arguments) > 6 or len(arguments) < 3:
sys.stderr.write("Usage: %s headerfile directory [filenameregex [dirregex [skip regex]]]/n" /
"Hint: ''.*'' is a catch all regex/nHint:''^((?!regexp).)*$'' negates a regex/n"%sys.argv[0])
sys.exit(1)
skipreg = None
fileregex = ".*"
dirregex = ".*"
if len(arguments) > 5:
skipreg = re.compile(arguments[5])
if len(arguments) > 3:
fileregex = arguments[3]
if len(arguments) > 4:
dirregex = arguments[4]
#compile regex
fileregex = re.compile(fileregex)
dirregex = re.compile(dirregex)
#read in the headerfile just once
headerfile = open(arguments[1])
header = headerfile.readlines()
headerfile.close()
addheader(arguments[2],header,skipreg,fileregex,dirregex)
#call the main method
main()
Mira el copyright-header RubyGem. Admite archivos con extensiones que terminan en php, c, h, cpp, hpp, hh, rb, css, js, html. También puede agregar y eliminar encabezados.
Instálelo escribiendo " sudo gem install copyright-header
"
Después de eso, puede hacer algo como:
copyright-header --license GPL3 /
--add-path lib/ /
--copyright-holder ''Dude1 <[email protected]>'' /
--copyright-holder ''Dude2 <[email protected]>'' /
--copyright-software ''Super Duper'' /
--copyright-software-description "A program that makes life easier" /
--copyright-year 2012 /
--copyright-year 2012 /
--word-wrap 80 --output-dir ./
También admite archivos de licencia personalizados utilizando el argumento --license-file.
Ok aquí hay una herramienta de interfaz de usuario sencilla que busca todos los archivos del tipo especificado en una carpeta, deja el texto que desea en la parte superior (el texto de la licencia) y copia el resultado en otro directorio (evitando posibles problemas de sobrescritura) . También es gratis. Necesario .Net 4.0.
De hecho, soy el autor, así que no dude en solicitar soluciones o nuevas funciones ... sin embargo, no hay promesas en el cronograma de entregas. ;)
más información: Herramienta encabezado de licencia en Amazify.com
Para Java, http://code.google.com/p/maven-license-plugin/
Saludos cordiales
Si aún necesita uno, hay una pequeña herramienta que he escrito, llamada SrcHead . Puede encontrarlo en http://www.solvasoft.nl/downloads.html
Solución de Python, modifíquela para su propia necesidad
caracteristicas:
- maneja los encabezados UTF (importante para la mayoría de los IDEs)
- Actualiza recursivamente todos los archivos en el directorio de destino que pasan la máscara dada (modifique el parámetro .endswith para la máscara de archivo de su idioma (.c, .java, ..etc)
- capacidad de sobrescribir el texto de copyright anterior (proporcione el antiguo parámetro de derechos de autor para hacer esto)
- opcionalmente omite los directorios dados en la matriz excluida
-
# updates the copyright information for all .cs files
# usage: call recursive_traversal, with the following parameters
# parent directory, old copyright text content, new copyright text content
import os
excludedir = ["..//Lib"]
def update_source(filename, oldcopyright, copyright):
utfstr = chr(0xef)+chr(0xbb)+chr(0xbf)
fdata = file(filename,"r+").read()
isUTF = False
if (fdata.startswith(utfstr)):
isUTF = True
fdata = fdata[3:]
if (oldcopyright != None):
if (fdata.startswith(oldcopyright)):
fdata = fdata[len(oldcopyright):]
if not (fdata.startswith(copyright)):
print "updating "+filename
fdata = copyright + fdata
if (isUTF):
file(filename,"w").write(utfstr+fdata)
else:
file(filename,"w").write(fdata)
def recursive_traversal(dir, oldcopyright, copyright):
global excludedir
fns = os.listdir(dir)
print "listing "+dir
for fn in fns:
fullfn = os.path.join(dir,fn)
if (fullfn in excludedir):
continue
if (os.path.isdir(fullfn)):
recursive_traversal(fullfn, oldcopyright, copyright)
else:
if (fullfn.endswith(".cs")):
update_source(fullfn, oldcopyright, copyright)
oldcright = file("oldcr.txt","r+").read()
cright = file("copyrightText.txt","r+").read()
recursive_traversal("..", oldcright, cright)
exit()
Verifique el sumador de licencia. Admite múltiples archivos de código (incluso los personalizados) y maneja los encabezados existentes correctamente. Viene ya con plantillas para las licencias de código abierto más comunes.
si está utilizando sbt, hay https://github.com/Banno/sbt-license-plugin
Aquí hay uno que encontré en la lista de Apache. Está escrito en Ruby y parece bastante fácil de leer. Incluso deberías poder llamarlo desde el rastrillo para obtener una bondad extra especial. :)
#!/bin/bash
for i in *.cc # or whatever other pattern...
do
if ! grep -q Copyright $i
then
cat copyright.txt $i >$i.new && mv $i.new $i
fi
done