ソースファイルにライセンスヘッダーを追加するためのツール?[閉まっている]


89

一部のソースファイルにライセンスヘッダーを一括で追加するツールを探しています。その一部にはすでにヘッダーがあります。ヘッダーがまだ存在しない場合、ヘッダーを挿入するツールはありますか?

編集:回答は基本的にすべて環境固有で主観的なものであるため、私は意図的にこの質問に対する回答をマークしていません


5
「回答は基本的にすべて環境固有で主観的なものであるため、意図的にこの質問に対する回答をマークしていません」疑似コードなど、環境にとらわれないソリューションをお探しですか?そうでない場合は、使用している環境をお知らせください。
jrummell 2009年

1
jrummell:いいえ、環境にとらわれないソリューションを探していません。私が所属していた複数の環境のチームが使用できるものを探していました。
Alex Lyman

これを可能にするWindowsUIアプリは、許容できる答えでしょうか?
Brady Moritz

@boomhauer WindowsUIアプリを探しています。何か知っていますか?
jus12 2011年

以下に新しい回答を追加しました。これで十分です。
Brady Moritz

回答:


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"
Aleks-DanielJakimenko-A。

これはサブディレクトリでは再帰的に機能しないと思います:
knocte 2018

2
@knocte forループをこれfor i in $(find /folder -name '*.cc');に置き換えて、サブディレクトリでスクリプトを実行します
Joyce

16

Pythonソリューション、必要に応じて変更

特徴:

  • UTFヘッダーを処理します(ほとんどのIDEにとって重要)
  • 指定されたマスクを渡して、ターゲットディレクトリ内のすべてのファイルを再帰的に更新します(言語(.c、.java、.. etc)のファイルマスクの.endswithパラメータを変更します)
  • 以前の著作権テキストを上書きする機能(これを行うために古い著作権パラメータを提供します)
  • オプションで、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
おそらく、スクリプトが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 2014

3
テンプレートを作成すると、既存のヘッダーを削除できます。テンプレートを引数としてスクリプトに--license-file引数とともに渡し、--remove-pathフラグを使用してすべてのファイルからその正確なヘッダーを削除します。基本的に、ヘッダーには非常に多くの種類があり、それらを確実に削除するアルゴリズムを作成することは簡単ではありません。
Erik Osterman 2014

1
最近追加したDockerfileので、面倒なルビーの依存関係をインストールすることはもはや問題ではありません
Erik Osterman 2017年

15

以下は、license.txtファイルにライセンスヘッダーがあると仮定して、トリックを実行するBashスクリプトです。

ファイル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 2011

1
@Rosenfieldエクスポートステートメントで、最後の一重引用符が欠落しています。
talespin_Kit 2011

findコマンドに括弧が必要なのはなぜですか?それは私にとって失敗しました
knocte 2018

13

編集:Eclipseを使用している場合は、プラグインがあります

SilverDragonの返信に基づいて簡単なPythonスクリプトを作成しました。より柔軟なソリューションが必要だったので、これを思いつきました。これにより、ディレクトリ内のすべてのファイルに再帰的にヘッダーファイルを追加できます。オプションで、ファイル名が一致する必要のある正規表現、ディレクトリ名が一致する必要のある正規表現、およびファイルの最初の行が一致しない必要のある正規表現を追加できます。この最後の引数を使用して、ヘッダーがすでに含まれているかどうかを確認できます。

これがシバン(#!)で始まる場合、このスクリプトはファイルの最初の行を自動的にスキップします。これは、これに依存する他のスクリプトを壊さないためです。この動作を望まない場合は、writeheaderで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()

3
プラグインのリンク切れ
mjaggard 2014

:私は、これはそれかもしれないと思うwiki.eclipse.org/Development_Resources/...
mbdevpl

私はこれの私自身のpythonパッケージバージョンを書く前に完全にグーグルに失敗しました。私はおそらく将来の改善のためにあなたの解決策を利用するでしょう。github.com/zkurtz/license_proliferator
zkurtz


11

これは、フォルダ内の指定した種類のすべてのファイルを検索し、必要なテキスト(ライセンステキスト)を先頭に追加して、結果を別のディレクトリにコピーする(潜在的な上書きの問題を回避する)単純なWindows専用UIツールです。 。それも無料です。必須の.Net4.0。

私は実際に作者なので、修正や新機能を自由にリクエストしてください...ただし、配信スケジュールについての約束はありません。;)

詳細:ライセンスヘッダのツールAmazify.com


また、これに関するフィードバック
Brady Moritz

1
私はこのソフトウェアが本当に好きですが、ヘッダーにファイル名を入力するためのマクロが必要です。Allsoは、ファイルを除外するオプションを使用して、編集するファイルのリストを表示すると便利です。(:
hs2d 2012

おかげで、マクロと除外リストは素晴らしいアイデアです
Brady Moritz

リンクの有効期限が切れています。サイトからダウンロードすることもできません
valijon

おかげで、私はそれを修理します
Brady Moritz

5

ライセンス追加機能を確認してください。複数のコードファイル(カスタムファイルも含む)をサポートし、既存のヘッダーを正しく処理します。最も一般的なオープンソースライセンスのテンプレートがすでに付属しています。


1
これをありがとう、license-adderあなたは正確にどちらを参照していますか?私が見つけた、Googleプロジェクトホスティング-自由な.NETアプリケーションを-ライセンス加算器、およびライセンス・アダー・簡単なPythonスクリプト・GitHubの
sdaau

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 Framework2.0が機能する必要があります。」
Riccardo Murri 2012

C / C ++スタイルヘッダーとUnicodeBOMを追加します。意味:の内容は各行のheader.txt前に付加され//、最初の行はUnicodeBOMで始まります。
koppor 2017年

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.