Інструмент для додавання заголовків ліцензій до вихідних файлів? [зачинено]


89

Я шукаю інструмент, який навалом додасть заголовок ліцензії до деяких вихідних файлів, деякі з яких вже мають заголовок. Чи є там інструмент, який вставить заголовок, якщо його ще немає?

Редагувати: Я навмисно не позначаю відповіді на це запитання, оскільки відповіді в основному є специфічними для оточення та суб’єктивними


5
"Я навмисно не позначаю відповіді на це запитання, оскільки відповіді в основному є специфічними для навколишнього середовища та суб'єктивними". Ви шукаєте агностичне рішення щодо середовища, наприклад, псевдокод? Якщо ні, повідомте нам, з яким середовищем ви працюєте.
jrummell

1
jrummell: Ні, не шукаю екологічно-агностичного рішення. Шукав речі, якими могла б скористатись команда з кількох середовищ, в якій я був.
Alex Lyman,

чи є програма інтерфейсу Windows, яка дозволяє це зробити, прийнятною відповіддю?
Brady Moritz

@boomhauer Я шукаю програму інтерфейсу Windows. Чи знаєте ви когось із них?
Jus12,

Я додав нову відповідь нижче, вона повинна робити саме це.
Брейді Моріц

Відповіді:


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
для i в "$ @" це досить хороший вибір. Ви також можете отримати винахідливий спосіб оплати, якщо ваша система VCS це потребує.
Джонатан Леффлер

10
-1, слід цитувати"$i"
Алекс-Даніель Якименко-А.

Я думаю, це не працює в підкаталогах рекурсивно :-(
knocte

2
@knocte Замініть цикл for цим, for i in $(find /folder -name '*.cc');щоб запустити скрипт у підкаталогах
Джойс,

16

Рішення Python, модифікуйте для власних потреб

Особливості:

  • обробляє заголовки UTF (важливо для більшості середовищ розробки)
  • рекурсивно оновлює всі файли в цільовому каталозі, передаючи задану маску (змініть параметр .endswith для файлової маски вашої мови (.c, .java, ..etc)
  • можливість перезаписати попередній текст авторського права (для цього надайте старий параметр авторського права)
  • необов'язково опускає каталоги, вказані в масиві excluir

-

# 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
Напевно, не завадило б згадати, що ваш сценарій написаний на python.
Дана

16

Ознайомтесь із заголовком авторських прав RubyGem. Він підтримує файли з розширеннями, що закінчуються на php, c, h, cpp, hpp, hh, rb, css, js, html. Він також може додавати та видаляти заголовки.

Встановіть його, набравши " sudo gem install copyright-header"

Після цього можна зробити щось на зразок:

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

Він також підтримує користувацькі файли ліцензії за допомогою аргументу --license-file.


Це чудово, за винятком того, що він не видаляє власні існуючі заголовки :(
pgpb.padilla

3
Ви можете видалити наявні заголовки, якщо створили для них шаблон. Передайте шаблон як аргумент сценарію з --license-fileаргументом і використовуйте --remove-pathпрапор, щоб вилучити саме той заголовок з усіх файлів. В основному існує так багато різних типів заголовків, створення алгоритму для їх надійного видалення є нетривіальним.
Ерік Остерман

1
Нещодавно ми додали, Dockerfileтому встановлення обтяжливих залежностей від рубіну вже не є проблемою
Ерік Остерман

15

Ось сценарій Bash, який зробить трюк, якщо припустити, що у файлі license.txt є заголовок ліцензії:

Файл 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  

Тепер запустіть це у своєму вихідному каталозі:

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

1
Вираз sed не буде добре працювати, якщо ім'я файлу містить цифри. Натомість розгляньте можливість використанняcut -f1 -d ' '
schweerelos

1
@Rosenfield Заключна одинарна пропозиція пропущена в експортній заяві.
Talespin_Kit

навіщо потрібні дужки в команді find? для мене це не вдалося
knocte

13

Редагувати: Якщо ви використовуєте eclipse, є плагін

Я написав простий сценарій python на основі відповіді Silver Dragon. Мені потрібне було більш гнучке рішення, тому я придумав це. Це дозволяє додавати файл заголовка до всіх файлів у каталозі, рекурсивно. Ви можете за бажанням додати регулярний вираз, якому мають відповідати імена файлів, і регулярний вираз, якому мають відповідати імена каталогів, і регулярний вираз, якому не повинен збігатися перший рядок у файлі. Ви можете використовувати цей останній аргумент, щоб перевірити, чи вже включений заголовок.

Цей скрипт автоматично пропускає перший рядок у файлі, якщо він починається з шебанга (#!). Це не для того, щоб порушити інші сценарії, які на це покладаються. Якщо ви не хочете такої поведінки, вам доведеться прокоментувати 3 рядки в заголовку.

ось:

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


Я думаю, що це може бути це: wiki.eclipse.org/Development_Resources/…
mbdevpl

Мені не вдалося ретельно погуглити, перш ніж написати власну версію пакета python цього. Швидше за все, я буду спиратися на ваше рішення для майбутніх удосконалень. github.com/zkurtz/license_proliferator
zkurtz


11

Добре, ось простий інструмент інтерфейсу лише для Windows, який здійснює пошук усіх файлів вказаного типу в папці, додає текст, який ви бажаєте, до верхньої частини (текст вашої ліцензії) та копіює результат в інший каталог (уникаючи потенційних проблем із перезаписом) . Це також безкоштовно. Потрібно .Net 4.0.

Я насправді є автором, тому сміливо вимагайте виправлення або нових функцій ... проте жодних обіцянок щодо графіку доставки. ;)

докладніше: Інструмент заголовка ліцензії на Amazify.com


також, я був би вдячний за будь-який відгук щодо цього, дякую
Брейді Моріц

1
Мені дуже подобається програмне забезпечення, але для введення імені файлу в заголовок потрібен макрос. Allso було б непогано показати список файлів для редагування з можливістю виключити файли. (:
hs2d

Спасибі, макрос та список виключень - це чудова ідея
Брейді Моріц

Термін дії вашого посилання закінчився. Завантажити його з сайту теж не можна
валіжон,

Дякую, я відремонтую
Брейді Моріц,

5

Перевірте додавач ліцензій. Він підтримує декілька файлів коду (навіть власні) і правильно обробляє наявні заголовки. Поставляється вже з шаблонами для найбільш поширених ліцензій з відкритим кодом.


1
Дякую за це, про що license-adderви маєте на увазі саме? Я знайшов
додавач

GitHub тепер знаходить: github.com/sanandrea/License-Adder
koppor

4

Ось один, який я прокатував у PHP, щоб змінити файли PHP. У мене також була стара інформація про ліцензію для видалення, тому вона спочатку замінює старий текст, а потім додає новий текст відразу після відкриття

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

Ось один я знайшов у списку Apache. Його написано на Ruby і, здається, досить легко читати. Ви навіть зможете назвати це з граблі для особливої ​​приємності. :)


1

Якщо він вам все ще потрібен, є невеликий інструмент, який я написав, на ім’я SrcHead . Ви можете знайти його на веб- сайті http://www.solvasoft.nl/downloads.html


3
На сторінці завантаження: "Написано для Windows і для роботи потрібен .NET Framework 2.0".
Ріккардо Муррі,

Додає заголовки стилю C / C ++ та специфікацію Unicode. Значення: вміст header.txtдодається до //кожного рядка, а перший рядок починається зі специфікації Unicode.
koppor

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.