代码之家  ›  专栏  ›  技术社区  ›  Alex Lyman

用于将许可证标题添加到源文件的工具?[闭门]

  •  80
  • Alex Lyman  · 技术社区  · 18 年前

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

    12 回复  |  直到 11 年前
        1
  •  69
  •   joshperry    10 年前
    #!/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
    
        2
  •  16
  •   Community Mohan Dere    14 年前

    假设您在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  
    
        3
  •  16
  •   Erik Osterman    12 年前

    查看 copyright-header 鲁比基姆。它支持扩展名以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参数自定义许可证文件。

        4
  •  16
  •   UniquePineapple    5 年前

    Python 2解决方案,根据自己的需要进行修改

    特征:

    • 处理UTF头(对大多数IDE都很重要)
    • 递归更新通过给定掩码的目标目录中的所有文件(修改语言(.c、.java,…等)的filemask的.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()
    
        5
  •  13
  •   Jens Timmerman    12 年前

    如果您使用的是eclipse,那么 a plugin

    我根据银龙的回复写了一个简单的python脚本。 我需要一个更灵活的解决方案,所以我想出了这个。 它允许您递归地向目录中的所有文件添加头文件。 您可以选择添加文件名应匹配的正则表达式、目录名应匹配的正则表达式和文件中第一行不应匹配的正则表达式。 您可以使用最后一个参数来检查是否已包含标头。

    如果以shebang(#!)开头,此脚本将自动跳过文件中的第一行。这是为了不破坏依赖于此的其他脚本。

    这是:

    #!/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()
    
        6
  •  12
  •   Flow Matt McDonald    5 年前

    对于Java,您可以使用Maven的许可证插件: http://code.google.com/p/maven-license-plugin/

        7
  •  11
  •   Brady Moritz    6 年前

    我实际上是作者,所以请随时请求修复或新功能。。。但没有关于交货时间表的承诺。;)

    更多信息: License Header tool 在 Amazify.com

        8
  •  5
  •   Peter Pratscher    14 年前

        9
  •  4
  •   Josh Ribakoff    13 年前

    下面是我在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();
    
        10
  •  3
  •   Richard Hurt    17 年前

    Here's one 我在Apache列表中找到了。它是用Ruby写的,看起来很容易阅读。您甚至可以从rake中调用它,以获得额外的精确性。:)

        11
  •  1
  •   Jan Langenberg Jan Langenberg    17 年前

    如果你还需要一个,我写了一个小工具,叫做 . 你可以在 http://www.solvasoft.nl/downloads.html

        12
  •  1
  •   Martijn    13 年前

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

    推荐文章