소스 파일에 라이센스 헤더를 추가하는 도구? [닫은]


89

일부 소스 파일에 라이센스 헤더를 대량으로 추가하는 도구를 찾고 있는데 일부는 이미 헤더가 있습니다. 아직없는 경우 헤더를 삽입하는 도구가 있습니까?

편집 : 답변은 기본적으로 모두 환경에 따라 다르며 주관적이기 때문에 의도적 으로이 질문에 대한 답변을 표시하지 않습니다.


5
"답변은 기본적으로 모두 환경에 따라 다르고 주관적이므로 의도적으로이 질문에 대한 답을 표시하지 않습니다."의사 코드와 같은 환경에 구애받지 않는 솔루션을 찾고 있습니까? 그렇지 않은 경우 작업중인 환경을 알려주십시오.
jrummell

1
jrummell : 아니요, 환경에 구애받지 않는 솔루션을 찾지 않습니다. 내가 속한 다중 환경 팀이 사용할 수있는 것을 찾고있었습니다.
Alex Lyman

이 작업을 수행 할 수있는 Windows UI 앱이 허용되는 대답이 될까요?
Brady Moritz 2011 년

@boomhauer Windows UI 앱을 찾고 있습니다. 알고 계십니까?
Jus12

아래에 새로운 답변을 추가했습니다.
Brady Moritz

답변:


63
#!/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 시스템에 필요한 경우 체크 아웃으로 창의성을 얻을 수도 있습니다.
Jonathan Leffler

10
-1, 당신은 인용해야합니다"$i"
Aleks-Daniel Jakimenko-A.

나는 이것이 재귀 적으로 하위 디렉토리에서 작동하지 않는다고 생각합니다 :-(
knocte

3
이과에 대한 루프를 교체 @knocte은 for i in $(find /folder -name '*.cc');하위 디렉토리에서 스크립트를 실행합니다
조이스

16

Python 솔루션, 필요에 맞게 수정

풍모:

  • UTF 헤더 처리 (대부분의 IDE에서 중요)
  • 주어진 마스크를 전달하는 대상 디렉토리의 모든 파일을 재귀 적으로 업데이트합니다 (사용자 언어 (.c, .java, ..etc)의 파일 마스크에 대한 .endswith 매개 변수 수정).
  • 이전 저작권 텍스트를 덮어 쓸 수있는 기능 (이 작업을 수행하기 위해 이전 저작권 매개 변수 제공)
  • 선택적으로 excludeir 배열에 제공된 디렉토리를 생략합니다.

-

# 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
아마 당신의 스크립트가 파이썬에 있다는 것을 언급해도 아프지 않을 것입니다.
Dana

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플래그를 사용하여 모든 파일에서 정확한 헤더를 제거합니다. 기본적으로 다양한 유형의 헤더가 있으므로이를 안정적으로 제거하는 알고리즘을 만드는 것은 사소한 일이 아닙니다.
Erik Osterman 2014

1
우리는 최근에 추가되지 Dockerfile더 이상 문제가 있으므로 설치 부담스러운 루비 종속성을
에릭 오스터

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

13

편집 : 이클립스를 사용 하는 경우 플러그인이 있습니다.

Silver Dragon의 답변을 바탕으로 간단한 파이썬 스크립트를 작성했습니다. 더 유연한 솔루션이 필요했기 때문에 이것을 생각해 냈습니다. 디렉토리의 모든 파일에 헤더 파일을 재귀 적으로 추가 할 수 있습니다. 선택적으로 파일 이름이 일치해야하는 정규식, 디렉토리 이름이 일치해야하는 정규식 및 파일의 첫 번째 줄이 일치하지 않아야하는 정규식을 추가 할 수 있습니다. 이 마지막 인수를 사용하여 헤더가 이미 포함되어 있는지 확인할 수 있습니다.

이 스크립트는 shebang (#!)으로 시작하는 경우 파일의 첫 번째 줄을 자동으로 건너 뜁니다. 이것은 이것에 의존하는 다른 스크립트를 깨뜨리지 않습니다. 이 동작을 원하지 않으면 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

나는이 그것을 할 수 있다고 생각 : wiki.eclipse.org/Development_Resources/...
mbdevpl

나는 이것의 파이썬 패키지 버전을 작성하기 전에 철저히 구글에 실패했습니다. 향후 개선을 위해 귀하의 솔루션을 그릴 것입니다. github.com/zkurtz/license_proliferator
zkurtz


11

Ok 여기는 폴더에서 지정된 유형의 모든 파일을 검색하고 원하는 텍스트 (라이선스 텍스트)를 맨 위에 추가하고 결과를 다른 디렉터리에 복사 (잠재적 인 덮어 쓰기 문제 방지)하는 간단한 Windows 전용 UI 도구입니다. . 또한 무료입니다. .Net 4.0이 필요합니다.

나는 실제로 저자이므로 수정이나 새로운 기능을 자유롭게 요청하십시오.하지만 배송 일정에 대한 약속은 없습니다. ;)

더 많은 정보 : 라이센스 헤더 도구 에서 Amazify.com


또한, 이것에 대한 피드백을 주셔서 감사합니다. 감사합니다
Brady Moritz

1
나는 소프트웨어가 정말 마음에 들지만 헤더에 파일 이름을 입력하려면 매크로가 필요합니다. Allso는 파일을 제외하는 옵션으로 편집 할 파일 목록을 표시하는 것이 좋습니다. (:
hs2d 2012

감사합니다, 매크로 및 제외 목록은 좋은 생각입니다
브래디 모리츠

링크가 만료되었습니다. 사이트에서도 다운로드 할 수 없습니다
valijon

감사합니다. 수리하겠습니다
Brady Moritz

5

라이센스 추가를 확인하십시오. 여러 코드 파일 (사용자 지정 파일 포함)을 지원하고 기존 헤더를 올바르게 처리합니다. 가장 일반적인 오픈 소스 라이선스에 대한 템플릿이 이미 제공됩니다.



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 목록에서 찾은 것이 있습니다. 그것은 루비로 작성되었고 읽기에 충분히 쉬워 보인다. 특별한 쾌적함을 위해 레이크에서 호출 할 수도 있습니다. :)


1

여전히 필요한 경우 SrcHead 라는 이름의 작은 도구가 있습니다 . http://www.solvasoft.nl/downloads.html 에서 찾을 수 있습니다 .


3
다운로드 페이지에서 : "Windows 용으로 작성되었으며 작동하려면 .NET Framework 2.0이 필요합니다."
Riccardo Murri

C / C ++ 스타일 헤더와 유니 코드 BOM을 추가합니다. 의미 :의 내용은 각 줄에 header.txt추가되고 //첫 줄은 유니 코드 BOM으로 시작합니다.
koppor

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.