Narzędzie do dodawania nagłówków licencji do plików źródłowych? [Zamknięte]


89

Szukam narzędzia, które zbiorczo doda nagłówek licencji do niektórych plików źródłowych, z których niektóre mają już nagłówek. Czy istnieje narzędzie, które wstawi nagłówek, jeśli jeszcze go nie ma?

Edycja: Celowo nie zaznaczam odpowiedzi na to pytanie, ponieważ odpowiedzi są w zasadzie wszystkie specyficzne dla środowiska i subiektywne


5
„Celowo nie zaznaczam odpowiedzi na to pytanie, ponieważ odpowiedzi są w zasadzie specyficzne dla środowiska i subiektywne” Czy szukasz rozwiązania niezależnego od środowiska, takiego jak pseudokod? Jeśli nie, daj nam znać, w jakim środowisku pracujesz.
jrummell

1
jrummell: Nie, nie szukam rozwiązania niezależnego od środowiska. Szukałem rzeczy, których mógłbym użyć w zespole zajmującym się wieloma środowiskami.
Alex Lyman

czy aplikacja interfejsu użytkownika systemu Windows, która pozwoli ci to zrobić, byłaby akceptowalną odpowiedzią?
Brady Moritz

@boomhauer Szukam aplikacji UI systemu Windows. Wiesz coś o którymś?
Jus12

Dodałem nową odpowiedź poniżej, powinno to zrobić.
Brady Moritz

Odpowiedzi:


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 w „$ @” to całkiem dobry wybór. Możesz także wykazać się pomysłowością przy kasach, jeśli Twój system VCS tego potrzebuje.
Jonathan Leffler,

10
-1, należy zacytować"$i"
Aleks-Daniel Jakimenko-A.

Myślę, że to nie działa w podkatalogach rekurencyjnie :-(
knocte

2
@knocte Zastąp pętlę for tym, for i in $(find /folder -name '*.cc');aby uruchomić skrypt w podkatalogach
Joyce

16

Rozwiązanie Python, zmodyfikuj na własne potrzeby

Cechy:

  • obsługuje nagłówki UTF (ważne dla większości IDE)
  • rekurencyjnie aktualizuje wszystkie pliki w katalogu docelowym, przekazując podaną maskę (zmodyfikuj parametr .endswith dla maski plików Twojego języka (.c, .java, ..etc)
  • możliwość nadpisania poprzedniego tekstu dotyczącego praw autorskich (w tym celu należy podać stary parametr dotyczący praw autorskich)
  • opcjonalnie pomija katalogi podane w tablicy excludedir

-

# 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
Prawdopodobnie nie zaszkodzi wspomnieć, że twój skrypt jest w Pythonie.
Dana

16

Sprawdź RubyGem z nagłówkiem autorskim. Obsługuje pliki z rozszerzeniami kończącymi się na php, c, h, cpp, hpp, hh, rb, css, js, html. Może również dodawać i usuwać nagłówki.

Zainstaluj go, wpisując „ sudo gem install copyright-header

Następnie możesz zrobić coś takiego:

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

Obsługuje również pliki licencji niestandardowych przy użyciu argumentu --license-file.


Jest to świetne, z wyjątkiem tego, że nie usuwa niestandardowych istniejących nagłówków :(
pgpb.padilla

3
Możesz usunąć istniejące nagłówki, jeśli utworzysz dla nich szablon. Przekaż szablon jako argument do skryptu z --license-fileargumentem i użyj --remove-pathflagi, aby usunąć ten dokładny nagłówek ze wszystkich plików. Zasadniczo istnieje tak wiele różnych typów nagłówków, więc stworzenie algorytmu niezawodnego ich usuwania jest nietrywialne.
Erik Osterman,

1
Niedawno dodaliśmy, Dockerfilewięc instalacja uciążliwych zależności ruby ​​nie jest już problemem
Erik Osterman

15

Oto skrypt Bash, który załatwi sprawę, zakładając, że masz nagłówek licencji w pliku license.txt:

Plik 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  

Teraz uruchom to w swoim katalogu źródłowym:

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

1
Wyrażenie sed nie będzie działać dobrze, jeśli nazwa pliku zawiera cyfry. Zamiast tego rozważ użyciecut -f1 -d ' '
schweerelos

1
@Rosenfield W wyciągu eksportowym brakuje zamykającego pojedynczego cudzysłowu.
Talespin_Kit

dlaczego potrzebujesz nawiasów w poleceniu wyszukiwania? nie udało mi się
knocte

13

Edycja: jeśli używasz eclipse, jest wtyczka

Napisałem prosty skrypt w Pythonie na podstawie odpowiedzi Silver Dragon. Potrzebowałem bardziej elastycznego rozwiązania, więc wymyśliłem to. Pozwala na rekurencyjne dodawanie pliku nagłówkowego do wszystkich plików w katalogu. Opcjonalnie możesz dodać wyrażenie regularne, do którego nazwy plików powinny pasować, oraz wyrażenie regularne, w którym nazwy katalogów powinny być zgodne, oraz wyrażenie regularne, do którego nie powinna pasować pierwsza linia w pliku. Możesz użyć tego ostatniego argumentu, aby sprawdzić, czy nagłówek jest już uwzględniony.

Ten skrypt automatycznie pominie pierwszą linię w pliku, jeśli zaczyna się od shebang (#!). Ma to na celu nie zepsucie innych skryptów, które na tym polegają. Jeśli nie chcesz tego zachowania, musisz zakomentować 3 linie w writeheader.

tutaj jest:

#!/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
Uszkodzony link do wtyczki
mjaggard

Myślę, że to może być to: wiki.eclipse.org/Development_Resources/ ...
mbdevpl

Nie udało mi się dokładnie wygooglować przed napisaniem mojej własnej wersji pakietu dla Pythona. Prawdopodobnie skorzystam z Twojego rozwiązania w celu wprowadzenia przyszłych ulepszeń. github.com/zkurtz/license_proliferator
zkurtz


11

Ok, tutaj jest proste narzędzie interfejsu użytkownika tylko dla systemu Windows, które wyszukuje wszystkie pliki określonego typu w folderze, dołącza tekst, który chcesz, na górze (tekst licencji) i kopiuje wynik do innego katalogu (unikając potencjalnych problemów z nadpisaniem) . Jest to również bezpłatne. Wymagany .Net 4.0.

Właściwie jestem autorem, więc nie krępuj się prosić o poprawki lub nowe funkcje ... ale bez obietnic dotyczących harmonogramu dostaw. ;)

więcej informacji: narzędzie License Header na Amazify.com


również byłbym wdzięczny za wszelkie opinie na ten temat, dzięki
Brady Moritz

1
Oprogramowanie bardzo mi się podoba, ale potrzebne jest makro, aby wpisać nazwę pliku do nagłówka. Przydałoby się też wyświetlenie listy plików do edycji z opcją wykluczenia plików. (:
hs2d

Dzięki, lista makr i wykluczeń to świetny pomysł
Brady Moritz

Twój link stracił ważność. Nie można go również pobrać ze strony
valijon

Dzięki, naprawię to
Brady Moritz

5

Sprawdź dodatek do licencji. Obsługuje wiele plików kodu (nawet niestandardowych) i poprawnie obsługuje istniejące nagłówki. Zawiera już szablony dla najpopularniejszych licencji Open Source.



GitHub wyszukuje teraz: github.com/sanandrea/License-Adder
koppor

4

Oto jeden, który zwinąłem w PHP, aby zmodyfikować pliki PHP. Miałem również do usunięcia informacje o starej licencji, więc najpierw zastępuje stary tekst, a następnie dodaje nowy tekst natychmiast po otwarciu

<?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

Oto jeden, który znalazłem na liście Apache. Jest napisany w języku Ruby i wydaje się łatwy do odczytania. Powinieneś nawet być w stanie wywołać to z prowizji, aby uzyskać dodatkową wyjątkową uprzejmość. :)


1

Jeśli nadal go potrzebujesz, napisałem małe narzędzie o nazwie SrcHead . Możesz go znaleźć pod adresem http://www.solvasoft.nl/downloads.html


3
Ze strony pobierania: „Został napisany dla systemu Windows i do działania wymaga .NET Framework 2.0”.
Riccardo Murri

Dodaje nagłówki w stylu C / C ++ i zestawienie komponentów w formacie Unicode. Znaczenie: zawartość header.txtjest poprzedzona //w każdym wierszu, a pierwszy wiersz zaczyna się od BOM Unicode.
koppor

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.