将许可证标题添加到源文件的工具?

我正在寻找一个工具,可以批量添加一个许可证头到一些源文件,其中一些已经有了头文件。 是否有一个工具,将插入一个标题,如果它不存在?

编辑:我故意不标记这个问题的答案,因为答案基本上都是环境特定的和主观的

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

Python解决scheme,根据您的需要进行修改

特征:

  • 处理UTF头文件(对于大多数IDE来说很重要)
  • recursion更新目标目录中的所有文件传递给定的掩码(修改.endswith参数为您的语言的文件掩码(.c,.java,..等)
  • 覆盖以前的版权文本的能力(提供旧的版权参数来做到这一点)
  • 可选地省略在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() 

查看版权标题 RubyGem。 它支持扩展名以php,c,h,cpp,hpp,hh,rb,css,js,html结尾的文件。 它也可以添加和删除标题。

通过input“ 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参数的自定义许可证文件。

这是一个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 

编辑:如果你使用的是Eclipse,那么有一个插件

我根据Silver Dragon的回复写了一个简单的python脚本。 我需要一个更灵活的解决scheme,所以我想出了这个。 它允许您recursion地向目录中的所有文件添加一个头文件。 您可以select添加文件名应匹配的正则expression式,以及目录名称应匹配的正则expression式以及文件中第一行不匹配的正则expression式。 你可以使用这个最后一个参数来检查头是否已经包含在内。

如果以脚本(#!)开头,该脚本将自动跳过文件中的第一行。 这不会打破依赖于此的其他脚本。 如果你不希望这种行为,你必须在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,请http://code.google.com/p/maven-license-plugin/

亲切的问候

好的,这里有一个简单的windows-only用户界面工具,它可以在文件夹中search指定types的所有文件,将您想要的文本前置到您的许可证文本中,并将结果复制到另一个目录中(避免潜在的覆盖问题) 。 这也是免费的。 必需.Net 4.0。

我实际上是作者,所以请随时申请修复或新的function…没有承诺交货时间表虽然。 ;)

更多信息: 许可证标题工具在Amazify.com

查看许可证加法器。 它支持多个代码文件(甚至自定义),并正确处理现有的标题。 已经有了最常见的开源许可证的模板。

这里是我在PHP中滚动来修改PHP文件。 我也有旧的许可证信息删除,所以它先replace旧的文本,然后在打开后立即添加新的文本

 <?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(); 

这是我在Apache列表中find的一个 。 它用Ruby编写,似乎很容易阅读。 你甚至应该能够从耙子中调用它来获得更多特别的好处。 🙂

如果你还需要一个,我写了一个名为SrcHead的工具。 你可以在http://www.solvasoft.nl/downloads.htmlfind它;

如果您使用sbt,则有https://github.com/Banno/sbt-license-plugin