web-dev-qa-db-fra.com

Outil pour ajouter des en-têtes de licence aux fichiers source?

Je cherche un outil permettant d'ajouter en bloc un en-tête de licence à certains fichiers source, dont certains ont déjà l'en-tête. Existe-t-il un outil permettant d'insérer un en-tête s'il n'est pas déjà présent?

Edit: je ne marque pas intentionnellement de réponse à cette question, car les réponses sont fondamentalement toutes spécifiques à l'environnement et subjectives  

80
Alex Lyman
#!/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
55
Tim

Découvrez le copyright-header RubyGem. Il supporte les fichiers avec les extensions se terminant par php, c, h, cpp, hpp, hh, rb, css, js, html. Il peut également ajouter et supprimer des en-têtes.

Installez-le en tapant "Sudo gem install copyright-header"

Après cela, peut faire quelque chose comme:

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 ./

Il prend également en charge les fichiers de licence personnalisés à l'aide de l'argument --license-file. 

15
Erik Osterman

Solution Python, modifiez-la pour répondre à vos besoins

Caractéristiques:

  • gère les en-têtes UTF (important pour la plupart des IDE)
  • met à jour de manière récursive tous les fichiers du répertoire cible en passant le masque donné (modifiez le paramètre .endswith pour le masque de fichier de votre langue (.c, .Java, ..etc)
  • possibilité d'écraser le texte de copyright précédent (fournir l'ancien paramètre de copyright pour le faire)
  • omet éventuellement les répertoires donnés dans le tableau exclusir

-

# 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()
15
Silver Dragon

Voici un script Bash qui fera l'affaire, en supposant que vous avez l'en-tête de licence dans le fichier license.txt:

Fichier 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  

Maintenant, lancez ceci dans votre répertoire source: 

export LICENSELEN=`wc -l license.txt | cut -f1 -d ' '`  
find . -type f \(-name \*.cpp -o -name \*.h \) -print0 | xargs -0 ./addlicense.sh  
14
Adam Rosenfield

Edit: Si vous utilisez Eclipse, il y a un plugin

J'ai écrit un script python simple basé sur la réponse de Silver Dragon… .. J'avais besoin d'une solution plus flexible, alors j'ai trouvé ceci… .. Il vous permet d'ajouter un fichier d'en-tête à tous les fichiers d'un répertoire, de manière récursive… ... Vous pouvez éventuellement ajouter une expression rationnelle à laquelle les noms de fichiers doivent correspondre, et une expression rationnelle à laquelle les noms de répertoires doivent correspondre et une expression rationnelle à laquelle la première ligne du fichier ne doit pas correspondre .. .. Vous pouvez utiliser ce dernier argument pour vérifier si l'en-tête est déjà inclus.

Ce script ignorera automatiquement la première ligne d'un fichier s'il commence par un Shebang (#!). Ceci pour ne pas casser d'autres scripts qui s'appuient sur ceci . Si vous ne le souhaitez pas, vous devrez commenter 3 lignes dans writeheader.

c'est ici: 

#!/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()
12
Jens Timmerman
10
marcospereira

Ok, voici un simple outil d'interface utilisateur Windows uniquement qui recherche tous les fichiers du type spécifié dans un dossier, ajoute le texte souhaité au dessus (votre texte de licence) et copie le résultat dans un autre répertoire (évitant ainsi d'éventuels problèmes de remplacement) . C'est aussi gratuit. Requis .Net 4.0. 

En fait, je suis l'auteur. N'hésitez donc pas à demander des correctifs ou de nouvelles fonctionnalités ... aucune promesse quant au calendrier de livraison. ;)

plus d'infos: Outil d'en-tête de licence à Amazify.com

10
Brady Moritz

Découvrez la licence-additionneur. Il prend en charge plusieurs fichiers de code (même personnalisés) et gère correctement les en-têtes existants. Livré avec des modèles pour les licences Open Source les plus courantes.

4
Peter Pratscher

Voici un j'ai trouvé sur la liste Apache. Son écrit en Ruby et semble assez facile à lire. Vous devriez même être capable de l'appeler de râteau pour plus de gentillesse. :)

2
Richard Hurt

En voici un que j'ai glissé dans PHP pour modifier les fichiers PHP. J'avais aussi les anciennes informations de licence à supprimer pour remplacer l'ancien texte en premier, puis ajouter le nouveau texte immédiatement après l'ouverture.

<?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();
2
Josh Ribakoff

Si vous en avez encore besoin, j’ai écrit un petit outil, nommé SrcHead. Vous pouvez le trouver à http://www.solvasoft.nl/downloads.html

1
Jan Langenberg

si vous utilisez sbt, il y a https://github.com/Banno/sbt-license-plugin

0
Martijn