Domanda

Sto cercando uno strumento che, in blocco, aggiungerà un'intestazione di licenza ad alcuni file sorgente, alcuni dei quali hanno già l'intestazione. Esiste uno strumento che inserirà un'intestazione, se non è già presente?

Modifica: non sto segnando intenzionalmente una risposta a questa domanda, poiché le risposte sono sostanzialmente tutte specifiche dell'ambiente e soggettive

È stato utile?

Soluzione

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

Altri suggerimenti

Soluzione Python, modifica per le tue necessità

Caratteristiche:

  • gestisce le intestazioni UTF (importante per la maggior parte degli IDE)
  • aggiorna ricorsivamente tutti i file nella directory di destinazione passando una determinata maschera (modifica il parametro .endswith per la maschera dei file della tua lingua (.c, .java, ..etc)
  • capacità di sovrascrivere il testo precedente del copyright (fornire il vecchio parametro del copyright per farlo)
  • facoltativamente omette le directory fornite nella matrice esclusa

-

# 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()

Dai un'occhiata al copyright-header RubyGem. Supporta file con estensioni che terminano in php, c, h, cpp, hpp, hh, rb, css, js, html. Può anche aggiungere e rimuovere le intestazioni.

Installalo digitando " sudo gem install copyright-header "

Dopodiché, può fare qualcosa del tipo:

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

Supporta anche file di licenza personalizzati usando l'argomento --license-file.

Ecco uno script Bash che farà il trucco, supponendo che tu abbia l'intestazione della licenza nel file license.txt:

File 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  

Ora eseguilo nella directory di origine:

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

Modifica: Se stai usando eclipse, c'è un plug-in

Ho scritto un semplice script in pitone basato sulla risposta di Silver Dragon. Avevo bisogno di una soluzione più flessibile, quindi ho pensato a questo. Ti consente di aggiungere un file di intestazione a tutti i file in una directory, in modo ricorsivo. È possibile aggiungere facoltativamente una regex a cui i nomi dei file devono corrispondere e una regex a cui i nomi delle directory devono corrispondere e una regex a cui la prima riga del file non deve corrispondere. Puoi utilizzare quest'ultimo argomento per verificare se l'intestazione è già inclusa.

Questo script salta automaticamente la prima riga di un file se inizia con uno shebang (#!). Questo per non interrompere altri script che si basano su questo. Se non desideri questo comportamento, dovrai commentare 3 righe nello strumento di scrittura.

eccolo:

#!/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).)*<*>quot; "#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()

Ok, ecco un semplice strumento dell'interfaccia utente solo per Windows che cerca tutti i file del tipo specificato in una cartella, antepone il testo desiderato (testo della licenza) e copia il risultato in un'altra directory (evitando potenziali sovrascrivere problemi). È anche gratuito. Richiesto .Net 4.0.

In realtà sono l'autore, quindi sentiti libero di richiedere correzioni o nuove funzionalità ... nessuna promessa sul programma di consegna. ;)

maggiori informazioni: Strumento di intestazione della licenza in Amazify.com

Dai un'occhiata al licenziatario. Supporta più file di codice (anche personalizzati) e gestisce correttamente le intestazioni esistenti. Viene già fornito con modelli per le licenze Open Source più comuni.

Eccone uno che ho trovato nell'elenco Apache. È scritto in Ruby e sembra abbastanza facile da leggere. Dovresti anche essere in grado di chiamarlo dal rastrello per una gentilezza ancora più speciale. :)

Eccone uno che ho inserito in PHP per modificare i file PHP. Avevo anche informazioni sulla vecchia licenza da eliminare, in modo che sostituisse prima il vecchio testo, quindi aggiungesse il nuovo testo immediatamente dopo l'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();

Se ne hai ancora bisogno, c'è un piccolo strumento che ho scritto, chiamato SrcHead . Puoi trovarlo su http://www.solvasoft.nl/downloads.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top