我正在寻找一种可以批量向一些源文件添加许可证头信息的工具,其中一些文件已经包含了头信息。是否有这样一种工具,可以在头信息不存在时插入头信息?
编辑:我故意没有标记这个问题的答案,因为答案基本上都是环境特定和主观的。
我正在寻找一种可以批量向一些源文件添加许可证头信息的工具,其中一些文件已经包含了头信息。是否有这样一种工具,可以在头信息不存在时插入头信息?
编辑:我故意没有标记这个问题的答案,因为答案基本上都是环境特定和主观的。
#!/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
for i in $(find /folder -name '*.cc');
,这样可以在子目录上运行脚本。 - Joyce以下是一段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
cut -f1 -d ' '
- schweerelosPython 2的解决方案,根据您自己的需要进行修改
特点:
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()
请查看copyright-header 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参数自定义许可证文件。
--license-file
参数,然后使用 --remove-path
标志从所有文件中去除该准确的头文件。基本上,由于有许多不同类型的头文件,创建可靠地移除它们的算法是非常困难的。 - Erik OstermanDockerfile
,因此安装繁琐的 Ruby 依赖不再是问题。 - Erik Osterman编辑: 如果你使用的是eclipse,有一个插件
我根据Silver Dragon的回答编写了一个简单的Python脚本。 我需要一个更灵活的解决方案,所以我想出了这个。 它允许你向一个目录中的所有文件递归地添加一个头文件。 你可以选择添加一个正则表达式来匹配文件名,一个正则表达式来匹配目录名,以及一个正则表达式来匹配文件的第一行不应该匹配的内容。 你可以使用最后一个参数来检查头文件是否已经被包含。
如果文件的第一行以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()
如果是Java语言,可以使用Maven的许可证插件:http://code.google.com/p/maven-license-plugin/
这是一个简单的仅适用于Windows的UI工具,它可以在文件夹中搜索指定类型的所有文件,将您想要添加的文本(即许可证文本)添加到每个文件的开头,并将结果复制到另一个目录中(避免潜在的覆盖问题)。该工具是免费的,需要 .Net 4.0。
实际上,我是这个工具的作者,如果您有任何问题或新功能请求,请随时与我联系…但不能保证交付时间表。 ;)
更多信息:许可证头工具 在 Amazify.com
请查看license-adder。它支持多个代码文件(甚至自定义的文件),并且正确处理现有的头文件。已经配备了最常见的开源许可证模板。
license-adder
工具?我找到了 license-adder - free .NET application - Google Project Hosting 和 License-Adder · simple python script · GitHub。 - sdaauHere is one I rolled in PHP to modify PHP files. I also had old license information to delete so it replaces the old text first, then adds the new text immediately after the opening
<?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();