Outil pour ajouter des en-têtes de licence aux fichiers source? [fermé]


89

Je recherche un outil qui, en vrac, ajoutera un en-tête de licence à certains fichiers source, dont certains ont déjà l'en-tête. Existe-t-il un outil qui insérera un en-tête, s'il n'est pas déjà présent?

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


5
«Je ne marque pas intentionnellement une réponse à cette question, car les réponses sont fondamentalement toutes spécifiques à l'environnement et subjectives.» Recherchez-vous une solution indépendante de l'environnement, comme un pseudo-code? Sinon, veuillez nous indiquer dans quel environnement vous travaillez.
jrummell

1
jrummell: Non, je ne cherche pas une solution indépendante de l'environnement. Je cherchais des choses qu'une équipe multi-environnement dans laquelle je faisais pourrait utiliser.
Alex Lyman

une application d'interface utilisateur Windows qui vous permet de le faire serait-elle une réponse acceptable?
Brady Moritz le

@boomhauer Je recherche une application d'interface utilisateur Windows. En connaissez-vous?
Jus12 du

J'ai ajouté une nouvelle réponse ci-dessous, il devrait le faire.
Brady Moritz

Réponses:


61
#!/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

1
for i dans "$ @" est un très bon choix. Vous pouvez également être inventif avec les vérifications si votre système VCS en a besoin.
Jonathan Leffler

10
-1, vous devriez citer"$i"
Aleks-Daniel Jakimenko-A.

Je suppose que cela ne fonctionne pas dans les sous-répertoires de manière récursive :-(
knocte

2
@knocte Remplacez la boucle for par ceci for i in $(find /folder -name '*.cc');pour exécuter le script sur les sous
Joyce

16

Solution Python, modifiez selon vos besoins

Fonctionnalités:

  • gère les en-têtes UTF (important pour la plupart des IDE)
  • met à jour récursivement 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 ce 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()

6
Cela ne ferait probablement pas de mal de mentionner que votre script est en python.
Dana

16

Consultez l'en -tête du copyright RubyGem. Il prend en charge les fichiers avec des 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, vous pouvez faire quelque chose comme:

copyright-header --license GPL3 \
  --add-path lib/ \
  --copyright-holder 'Dude1 <dude1@host.com>' \
  --copyright-holder 'Dude2 <dude2@host.com>' \
  --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.


C'est génial sauf que cela ne supprime pas les en-têtes existants personnalisés :(
pgpb.padilla

3
Vous pouvez supprimer les en-têtes existants si vous créez un modèle pour eux. Transmettez le modèle comme argument au script avec l' --license-fileargument et utilisez l' --remove-pathindicateur pour supprimer cet en-tête exact de tous les fichiers. Fondamentalement, il existe tellement de types d'en-têtes différents, créer un algorithme pour les supprimer de manière fiable n'est pas trivial.
Erik Osterman

1
Nous avons récemment ajouté une Dockerfileinstallation de dépendances ruby ​​onéreuses n'est plus un problème
Erik Osterman

15

Voici un script Bash qui fera l'affaire, en supposant que vous ayez 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, exécutez 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  

1
L'expression sed ne fonctionnera pas correctement si le nom de fichier contient des chiffres. Au lieu de cela, pensez à utilisercut -f1 -d ' '
schweerelos

1
@Rosenfield Le guillemet simple de clôture est omis dans la déclaration d'exportation.
Talespin_Kit

pourquoi avez-vous besoin de la parenthèse dans la commande find? il a échoué pour moi
knocte

13

Edit: Si vous utilisez eclipse, il existe un plugin

J'ai écrit un simple script python basé sur la réponse de Silver Dragon. J'avais besoin d'une solution plus flexible, alors j'ai trouvé ça. 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 régulière avec laquelle les noms de fichiers doivent correspondre, et une expression régulière avec laquelle les noms de répertoire doivent correspondre et une expression régulière à 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 sautera automatiquement la première ligne d'un fichier si cela commence par un shebang (#!). Ceci pour ne pas casser les autres scripts qui reposent sur cela. Si vous ne souhaitez pas ce comportement, 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()

3
Lien cassé pour le plugin
mjaggard

Je pense que ça pourrait être ça: wiki.eclipse.org/Development_Resources/…
mbdevpl

Je n'ai pas réussi à bien rechercher sur Google avant d'écrire ma propre version de package Python. Je vais probablement m'appuyer sur votre solution pour de futures améliorations. github.com/zkurtz/license_proliferator
zkurtz


11

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 que vous souhaitez en haut (votre texte de licence) et copie le résultat dans un autre répertoire (évitant les problèmes d'écrasement potentiels) . C'est aussi gratuit. Requis .Net 4.0.

Je suis en fait l'auteur, alors n'hésitez pas à demander des correctifs ou de nouvelles fonctionnalités ... pas de promesses sur le calendrier de livraison cependant. ;)

plus d'informations: Outil d'en-tête de licence sur Amazify.com


aussi, j'apprécierais tout commentaire à ce sujet, merci
Brady Moritz

1
J'aime beaucoup le logiciel mais il faut une macro pour entrer le nom de fichier dans l'en-tête. Ce serait également bien d'afficher la liste des fichiers à modifier avec une option pour exclure les fichiers. (:
hs2d

Merci, la liste de macro et d'exclusion est une excellente idée
Brady Moritz

Votre lien a expiré. Il n'est pas non plus possible de le télécharger depuis le site
valijon

Merci, je vais le faire réparer
Brady Moritz

5

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



GitHub trouve maintenant: github.com/sanandrea/License-Adder
koppor

4

En voici un que j'ai roulé en PHP pour modifier les fichiers PHP. J'avais également d'anciennes informations de licence à supprimer afin qu'elles remplacent d'abord l'ancien texte, puis ajoute 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();

3

En voici un que j'ai trouvé sur la liste Apache. Il est écrit en Ruby et semble assez facile à lire. Vous devriez même pouvoir l'appeler du râteau pour une gentillesse particulière. :)


1

Si vous en avez encore besoin, il y a un petit outil que j'ai écrit, nommé SrcHead . Vous pouvez le trouver sur http://www.solvasoft.nl/downloads.html


3
À partir de la page de téléchargement: «Il est écrit pour Windows et nécessite le .NET Framework 2.0 pour fonctionner».
Riccardo Murri

Ajoute des en-têtes de style C / C ++ et une nomenclature Unicode. Signification: Le contenu de header.txtest précédé de //à chaque ligne et la première ligne commence par la nomenclature Unicode.
koppor

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.