[gnome-builder] copyright: add copyright plugin that can update copyrights



commit 809e0cd8f9449214293ea1897e46adf592ad7ba3
Author: Christian Hergert <chergert redhat com>
Date:   Fri Jan 17 11:14:17 2020 -0800

    copyright: add copyright plugin that can update copyrights
    
    This plugin, when enabled, can update copyright lines in the headers of
    your project. A toggle is provided in Preferences and defaults to false.
    
    This works by scanning for your real name, provided by g_get_real_name(),
    and then looking for years using a 4 digit regex. If a range is found,
    the range will be updated. Otherwise the first number will be updated.
    
    There are certainly things this will break on, but the limited set of
    things I've tested on work well. If you have something it breaks on, let
    me know and I'm sure we can accommodate.

 meson_options.txt                                  |   1 +
 src/plugins/copyright/copyright.plugin             |   9 ++
 src/plugins/copyright/copyright_plugin.py          | 117 +++++++++++++++++++++
 src/plugins/copyright/meson.build                  |  14 +++
 ...org.gnome.builder.plugins.copyright.gschema.xml |   9 ++
 src/plugins/meson.build                            |   2 +
 6 files changed, 152 insertions(+)
---
diff --git a/meson_options.txt b/meson_options.txt
index 5d5288ac5..1efc7c4ca 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -28,6 +28,7 @@ option('plugin_clang', type: 'boolean')
 option('plugin_cmake', type: 'boolean')
 option('plugin_code_index', type: 'boolean')
 option('plugin_color_picker', type: 'boolean')
+option('plugin_copyright', type: 'boolean')
 option('plugin_ctags', type: 'boolean')
 option('plugin_devhelp', type: 'boolean')
 option('plugin_deviced', type: 'boolean', value: false)
diff --git a/src/plugins/copyright/copyright.plugin b/src/plugins/copyright/copyright.plugin
new file mode 100644
index 000000000..a4e35eafb
--- /dev/null
+++ b/src/plugins/copyright/copyright.plugin
@@ -0,0 +1,9 @@
+[Plugin]
+Authors=Christian Hergert <chergert redhat com>
+Builtin=true
+Copyright=Copyright © 2020 Christian Hergert
+Description=Update copyright when files are saved
+Loader=python3
+Module=copyright_plugin
+Name=Update Copyright
+X-Builder-ABI=@PACKAGE_ABI@
diff --git a/src/plugins/copyright/copyright_plugin.py b/src/plugins/copyright/copyright_plugin.py
new file mode 100644
index 000000000..387ec09e9
--- /dev/null
+++ b/src/plugins/copyright/copyright_plugin.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python3
+
+#
+# copyright_plugin.py
+#
+# Copyright 2020 Christian Hergert <chergert redhat com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+from gi.repository import GLib, GObject, Gio
+from gi.repository import Gtk
+from gi.repository import Ide
+
+import re
+import time
+
+_YEAR_REGEX = r1 = re.compile('([0-9]{4})')
+_MAX_LINE = 100
+_ = Ide.gettext
+
+class CopyrightBufferAddin(Ide.Object, Ide.BufferAddin):
+    settings = None
+
+    def do_load(self, buffer):
+        self.settings = Gio.Settings.new('org.gnome.builder.plugins.copyright')
+
+    def do_unload(self, buffer):
+        self.settings = None
+
+    def do_save_file(self, buffer, file):
+        """
+        If there is a copyright block within the file and we find the users
+        name within it, we might want to update the year to include the
+        current year.
+        """
+        # Stop if we aren't enabled
+        if not self.settings.get_boolean('update-on-save'):
+            return
+
+        # Stop if we can't discover the user's real name
+        name = GLib.get_real_name()
+        if name == 'Unknown':
+            return
+
+        year = time.strftime('%Y')
+        iter = buffer.get_start_iter()
+        limit = buffer.get_iter_at_line(_MAX_LINE)
+
+        while True:
+            # Stop if we've past our limit
+            if iter.compare(limit) >= 0:
+                break
+
+            # Stop If we don't find the user's full name
+            ret = iter.forward_search(name, Gtk.TextSearchFlags.TEXT_ONLY, limit)
+            if not ret:
+                break
+
+            # Get the whole line text
+            match_begin, match_end = ret
+            match_begin.set_line_offset(0)
+            if not match_end.ends_line():
+                match_end.forward_to_line_end()
+            text = match_begin.get_slice(match_end)
+
+            # Split based on 4-digit years
+            parts = _YEAR_REGEX.split(text)
+
+            # If we have at least 2 years, we can update them
+            if len(parts) >= 2:
+                if '-' in parts:
+                    parts[parts.index('-')+1] = year
+                else:
+                    parts.insert(2, '-')
+                    parts.insert(3, year)
+
+                text = ''.join(parts)
+
+                # Replace the line text in a single undo action
+                buffer.begin_user_action()
+                buffer.delete(match_begin, match_end)
+                buffer.insert(match_begin, text)
+                buffer.end_user_action()
+
+                break
+
+            # Move to the end of the line
+            iter = match_end
+
+class CopyrightPreferencesAddin(GObject.Object, Ide.PreferencesAddin):
+    def do_load(self, prefs):
+        self.update_on_save = prefs.add_switch(
+                "editor", "general",
+                "org.gnome.builder.plugins.copyright",
+                "update-on-save",
+                None,
+                "false",
+                _("Update Copyright"),
+                _("When saving a file Builder will automatically update copyright information for you"),
+                # translators: these are keywords used to search for preferences
+                _("update copyright save"),
+                10)
+
+    def do_unload(self, prefs):
+        prefs.remove_id(self.update_on_save)
diff --git a/src/plugins/copyright/meson.build b/src/plugins/copyright/meson.build
new file mode 100644
index 000000000..ba75e7bbe
--- /dev/null
+++ b/src/plugins/copyright/meson.build
@@ -0,0 +1,14 @@
+if get_option('plugin_copyright')
+
+install_data('copyright_plugin.py', install_dir: plugindir)
+install_data('org.gnome.builder.plugins.copyright.gschema.xml', install_dir: schema_dir)
+
+configure_file(
+          input: 'copyright.plugin',
+         output: 'copyright.plugin',
+  configuration: config_h,
+        install: true,
+    install_dir: plugindir,
+)
+
+endif
diff --git a/src/plugins/copyright/org.gnome.builder.plugins.copyright.gschema.xml 
b/src/plugins/copyright/org.gnome.builder.plugins.copyright.gschema.xml
new file mode 100644
index 000000000..4db11f45a
--- /dev/null
+++ b/src/plugins/copyright/org.gnome.builder.plugins.copyright.gschema.xml
@@ -0,0 +1,9 @@
+<schemalist>
+  <schema id="org.gnome.builder.plugins.copyright" path="/org/gnome/builder/plugins/copyright/" 
gettext-domain="gnome-builder">
+    <key name="update-on-save" type="b">
+      <default>false</default>
+      <summary>Update Copyright before Saving</summary>
+      <description>Updates the copyright for the user before saving to disk.</description>
+    </key>
+  </schema>
+</schemalist>
diff --git a/src/plugins/meson.build b/src/plugins/meson.build
index 72794c712..5690b5ffa 100644
--- a/src/plugins/meson.build
+++ b/src/plugins/meson.build
@@ -48,6 +48,7 @@ subdir('codeui')
 subdir('color-picker')
 subdir('command-bar')
 subdir('comment-code')
+subdir('copyright')
 subdir('c-pack')
 subdir('create-project')
 subdir('ctags')
@@ -148,6 +149,7 @@ status += [
   'Code Index ............ : @0@'.format(get_option('plugin_code_index')),
   'Color Pickr ........... : @0@'.format(get_option('plugin_color_picker')),
   'CTags ................. : @0@'.format(get_option('plugin_ctags')),
+  'Copyright ............. : @0@'.format(get_option('plugin_copyright')),
   'Devhelp ............... : @0@'.format(get_option('plugin_devhelp')),
   'Deviced ............... : @0@'.format(get_option('plugin_deviced')),
   'D-Bus Spy ............. : @0@'.format(get_option('plugin_dspy')),


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]