Alat untuk menambahkan header lisensi ke file sumber? [Tutup]


89

Saya mencari alat yang akan, secara massal, menambahkan header lisensi ke beberapa file sumber, beberapa di antaranya sudah memiliki header. Apakah ada alat di luar sana yang akan memasukkan tajuk, jika belum ada?

Sunting: Saya sengaja tidak menandai jawaban atas pertanyaan ini, karena jawaban pada dasarnya semuanya khusus lingkungan dan subjektif


5
"Saya sengaja tidak menandai jawaban atas pertanyaan ini, karena jawaban pada dasarnya semua spesifik lingkungan dan subjektif" Apakah Anda mencari solusi agnostik lingkungan, seperti kode semu? Jika tidak, beri tahu kami lingkungan tempat Anda bekerja.
jrummell

1
jrummell: Tidak, tidak mencari solusi agnostik lingkungan. Sedang mencari hal-hal yang dapat digunakan oleh tim multi-lingkungan yang saya ikuti.
Alex Lyman

akankah aplikasi Windows UI yang memungkinkan Anda melakukan ini, menjadi jawaban yang dapat diterima?
Brady Moritz

@boomhauer Saya mencari aplikasi Windows UI. Apa kamu mengetahui sesuatu?
Jus12

Saya menambahkan jawaban baru di bawah ini, seharusnya melakukan ini.
Brady Moritz

Jawaban:


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
karena saya di "$ @" adalah pilihan yang cukup bagus. Anda juga bisa menjadi inventif dengan pembayaran jika sistem VCS Anda membutuhkannya.
Jonathan Leffler

10
-1, Anda harus mengutip"$i"
Aleks-Daniel Jakimenko-A.

Saya kira ini tidak berfungsi di subdirektori secara rekursif :-(
knocte

2
@knocte Ganti for-loop dengan ini for i in $(find /folder -name '*.cc');untuk menjalankan skrip pada subdirektori
Joyce

16

Solusi Python, modifikasi untuk kebutuhan Anda sendiri

Fitur:

  • menangani header UTF (penting untuk sebagian besar IDE)
  • memperbarui semua file secara rekursif dalam direktori target dengan meneruskan mask yang diberikan (ubah parameter .endswith untuk filemask bahasa Anda (.c, .java, ..etc)
  • kemampuan untuk menimpa teks hak cipta sebelumnya (berikan parameter hak cipta lama untuk melakukan ini)
  • secara opsional menghilangkan direktori yang diberikan dalam larik 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
Mungkin tidak ada salahnya untuk menyebutkan skrip Anda dalam python.
Dana

16

Lihat header-hak cipta RubyGem. Ini mendukung file dengan ekstensi yang diakhiri dengan php, c, h, cpp, hpp, hh, rb, css, js, html. Itu juga dapat menambah dan menghapus header.

Instal dengan mengetik " sudo gem install copyright-header"

Setelah itu, bisa melakukan sesuatu seperti:

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 ./

Ini juga mendukung file lisensi kustom menggunakan argumen --license-file.


Ini bagus, kecuali bahwa ia tidak menghapus tajuk khusus yang ada :(
pgpb.padilla

3
Anda dapat menghapus header yang ada jika Anda membuat template untuk mereka. Teruskan template sebagai argumen ke skrip dengan --license-fileargumen tersebut, dan gunakan --remove-pathbendera untuk menghapus header yang tepat dari semua file. Pada dasarnya, ada begitu banyak jenis header, membuat algoritme untuk menghapusnya dengan andal bukanlah hal yang sepele.
Erik Osterman

1
Kami baru-baru ini menambahkan Dockerfilesehingga memasang dependensi ruby ​​yang memberatkan tidak lagi menjadi masalah
Erik Osterman

15

Berikut ini skrip Bash yang akan melakukan triknya, dengan asumsi Anda memiliki header lisensi di file license.txt:

File 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  

Sekarang jalankan ini di direktori sumber Anda:

export LICENSELEN=`wc -l license.txt | cut -f1 -d ' '`  
find . -type f \(-name \*.cpp -o -name \*.h \) -print0 | xargs -0 ./addlicense.sh  

1
Ekspresi sed tidak akan bekerja dengan baik jika nama file mengandung angka. Sebagai gantinya, pertimbangkan untuk menggunakancut -f1 -d ' '
schweerelos

1
@Rosenfield Kutipan tunggal penutup tidak ditemukan dalam pernyataan ekspor.
Talespin_Kit

mengapa Anda membutuhkan tanda kurung dalam perintah find? itu gagal untuk saya
knocte

13

Sunting: Jika Anda menggunakan gerhana, ada plugin

Saya menulis skrip python sederhana berdasarkan balasan Silver Dragon. Saya membutuhkan solusi yang lebih fleksibel jadi saya datang dengan ini. Ini memungkinkan Anda untuk menambahkan file header ke semua file dalam direktori, secara rekursif. Secara opsional, Anda dapat menambahkan regex yang harus cocok dengan nama file, dan regex yang harus cocok dengan nama direktori dan regex yang tidak boleh cocok dengan baris pertama dalam file. Anda dapat menggunakan argumen terakhir ini untuk memeriksa apakah tajuk sudah disertakan.

Skrip ini secara otomatis akan melewati baris pertama dalam file jika ini dimulai dengan shebang (#!). Ini untuk tidak merusak skrip lain yang mengandalkan ini. Jika Anda tidak menginginkan perilaku ini, Anda harus mengomentari 3 baris di kepala artikel.

ini dia:

#!/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
Tautan rusak untuk plugin
mjaggard


Saya gagal ke google secara menyeluruh sebelum menulis versi paket python saya sendiri ini. Saya kemungkinan akan menggunakan solusi Anda untuk perbaikan di masa mendatang. github.com/zkurtz/license_proliferator
zkurtz


11

Ok di sini adalah alat UI khusus windows yang mencari semua file dari tipe yang Anda tentukan dalam folder, menambahkan teks yang Anda inginkan ke atas (teks lisensi Anda), dan menyalin hasilnya ke direktori lain (menghindari potensi masalah timpa) . Ini juga gratis. Diperlukan .Net 4.0.

Saya sebenarnya penulisnya, jadi silakan meminta perbaikan atau fitur baru ... meskipun tidak ada janji tentang jadwal pengiriman. ;)

info lebih lanjut: Alat Header Lisensi di Amazify.com


juga, saya akan menghargai umpan balik apa pun tentang ini, terima kasih
Brady Moritz

1
Saya sangat suka perangkat lunaknya tetapi ada kebutuhan makro untuk memasukkan nama file ke header. Alangkah baiknya, tunjukkan daftar file yang akan diedit dengan opsi untuk mengecualikan file. (:
hs2d

Terima kasih, daftar makro dan pengecualian adalah ide bagus
Brady Moritz

Tautan Anda telah kedaluwarsa. Tidak mungkin untuk mengunduhnya dari situs juga
valijon

Terima kasih, saya akan memperbaikinya
Brady Moritz

5

Lihat penambah lisensi. Ini mendukung banyak file kode (bahkan yang khusus) dan menangani header yang ada dengan benar. Sudah dilengkapi dengan template untuk lisensi Open Source yang paling umum.


1
Terima kasih untuk ini, yang license-addersebenarnya Anda maksud? Saya telah menemukan penambah lisensi - aplikasi .NET gratis - Hosting Proyek Google , dan Adder-Lisensi · skrip python sederhana · GitHub
sdaau

GitHub sekarang menemukan: github.com/sanandrea/License-Adder
koppor

4

Ini adalah salah satu yang saya putar di PHP untuk memodifikasi file PHP. Saya juga memiliki informasi lisensi lama untuk dihapus sehingga menggantikan teks lama terlebih dahulu, kemudian menambahkan teks baru segera setelah pembukaan

<?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

Ini yang saya temukan di daftar Apache. Ini ditulis dalam Ruby dan tampaknya cukup mudah dibaca. Anda bahkan harus dapat memanggilnya dari rake untuk mendapatkan kenyamanan ekstra. :)


1

Jika Anda masih membutuhkannya, ada alat kecil yang saya tulis, bernama SrcHead . Anda dapat menemukannya di http://www.solvasoft.nl/downloads.html


3
Dari halaman download: "Ini ditulis untuk Windows dan membutuhkan .NET Framework 2.0 untuk bekerja."
Riccardo Murri

Menambahkan header C / C ++ Style dan Unicode BOM. Artinya: Konten header.txtdiawali dengan //di setiap baris dan baris pertama dimulai dengan Unicode BOM.
koppor

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.