gitreport 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/hook.rb ADDED
@@ -0,0 +1,122 @@
1
+ require "digest/sha1"
2
+
3
+ module GitReport
4
+ class Hook
5
+
6
+ # creates a hook file if not exists and adds our hook line if it does not exist already
7
+ def self.set!
8
+ create_hook_file! unless hook_file_exists?
9
+ set_hook! if hook_file_exists?
10
+ end
11
+
12
+ def self.remove!
13
+ remove_hook! if hook_file_exists?
14
+ end
15
+
16
+ private
17
+
18
+ # creates a git hook file
19
+ def self.create_hook_file!
20
+ write_to_file doc
21
+ end
22
+
23
+ # writes given data to hook file
24
+ def self.write_to_file data
25
+ begin
26
+ File.open(hook_file, 'w') {|f| f.write(data);f.chmod(0755);f.close }
27
+ rescue Exception => e
28
+ puts "Error while writing hookfile #{hook_file}: #{e}"
29
+ return false
30
+ end
31
+
32
+ true
33
+ end
34
+
35
+ # returns the hook files content
36
+ def self.file_content
37
+ begin
38
+ File.open(hook_file, 'r').read
39
+ # @@content ||= File.open(hook_file, 'r').read
40
+ rescue Exception => e
41
+ puts "Error while reading hookfile #{hook_file}: #{e}"
42
+ end
43
+ end
44
+
45
+ # returns true if a git hook file already exists, false else
46
+ def self.hook_file_exists?
47
+ File.exists? hook_file
48
+ end
49
+
50
+ # set's our hook line into an existing hook file if it does not exist already
51
+ def self.set_hook!
52
+ puts "Successfully registered post-commit hook." if (set_line! unless line_exists?)
53
+ end
54
+
55
+ # returns true if the hook file already has a hook line in
56
+ def self.line_exists?
57
+ if file_content.match(/bundle\sexec\sgitreport\scommit\s&/)
58
+ return true
59
+ end
60
+
61
+ false
62
+ end
63
+
64
+ # sets our hook line
65
+ def self.set_line!
66
+ write_to_file(file_content + line)
67
+ end
68
+
69
+ # returns the hook files path
70
+ def self.hook_file
71
+ @@file ||= GitReport.project.path + "/.git/hooks/post-commit"
72
+ end
73
+
74
+ # returns the document header
75
+ def self.doc
76
+ "#!/bin/sh\n" +
77
+ "# This is a post-commit hook created by gitreport (http://gitreport.com)\n" +
78
+ "#\n" +
79
+ "# To remove it issue 'bundle exec unregister' in the projects main directory\n" +
80
+ "# In case the gitreport gem is not installed anymore, simply remove this hook file\n" +
81
+ "#\n" +
82
+ "# Be aware of other post commit hooks that my be mentioned here!\n"
83
+ end
84
+
85
+ # returns the line to activate gitreport via post commit hook
86
+ def self.line
87
+ "\nbundle exec gitreport commit &\n"
88
+ end
89
+
90
+ # removes the hook
91
+ def self.remove_hook!
92
+ (remove_hook_file!; return) if hook_file_unchanged?
93
+ remove_line! if line_exists?
94
+ end
95
+
96
+ # removes the hook file
97
+ def self.remove_hook_file!
98
+ begin
99
+ File.unlink(hook_file)
100
+ puts "Successfully removed gitreport post-commit hook (file).\n"
101
+ rescue Exception => e
102
+ puts "Error while removing hookfile #{hook_file}: #{e}"
103
+ end
104
+ end
105
+
106
+ # returns true if the hook file is ours and was not changed
107
+ def self.hook_file_unchanged?
108
+ Digest::SHA1.hexdigest(file_content) == "9c69e61ce35b8ce21968343411e6abeb89b237dd"
109
+ end
110
+
111
+ # removes our hook line from hook file
112
+ def self.remove_line!
113
+ puts "Successfully removed gitreport post-commit hook.\n" if write_to_file(clean_up(file_content))
114
+ end
115
+
116
+ # removes our hook line from given content
117
+ def self.clean_up content
118
+ content.gsub(/\nbundle\sexec\sgitreport\scommit\s&\n/,'')
119
+ end
120
+
121
+ end
122
+ end
data/lib/log.rb ADDED
@@ -0,0 +1,26 @@
1
+ module GitReport
2
+ class Log
3
+
4
+ attr_accessor :project, :commits
5
+
6
+ def initialize project = nil
7
+ raise 'No git repo found!' unless project
8
+ @project = project
9
+ end
10
+
11
+ # returns all the commits of that project of the currently checked out branch
12
+ def commits
13
+ @commits ||= @project.log.entries.sort{ |a, b| a.author.date <=> b.author.date }
14
+ end
15
+
16
+ # returns the most recent commit
17
+ def last
18
+ @@last ||= self.commits.last
19
+ end
20
+
21
+ # returns the initial commit
22
+ def first
23
+ @@first ||= self.commits.first
24
+ end
25
+ end
26
+ end
data/lib/project.rb ADDED
@@ -0,0 +1,70 @@
1
+ module GitReport
2
+
3
+ class Project
4
+ attr_accessor :project, :log, :branch
5
+
6
+ def initialize path = nil
7
+ path ||= '.'
8
+ @project = Git.open(path)
9
+ @log = GitReport::Log.new(@project)
10
+ @branch = GitReport::CurrentBranch.new(@project)
11
+ end
12
+
13
+ # returns the local project directory
14
+ def path
15
+ @path ||= @project.dir.path
16
+ end
17
+
18
+ # returns the local name of the project extracted from the project directory
19
+ def name
20
+ @name ||= @project.dir.path.match(/.*\/(.*)$/).nil? ? "unknown" : $1
21
+ end
22
+
23
+ # returns an array of remote objects of the project
24
+ def remotes
25
+ @remotes ||= @project.remotes
26
+ end
27
+
28
+ # returns an array of names of all remote branches
29
+ def remote_branches
30
+ @remote_branches ||= @project.branches.remote.map(&:full)
31
+ end
32
+
33
+ # returns the projects first commits hash as an identifier
34
+ def identifier
35
+ @identifier ||= self.revlist.last
36
+ end
37
+
38
+ # returns the projects rev-list
39
+ def revlist
40
+ (`git rev-list --all`).split("\n")
41
+ end
42
+
43
+ # returns the branch name
44
+ def branchname
45
+ @branchname ||= self.branch.name
46
+ end
47
+
48
+ # returns projects core data as a hash for transfer of a commit batch
49
+ def data
50
+ @data ||= aggregate
51
+ end
52
+
53
+ private
54
+
55
+ # aggregates the projects core data
56
+ def aggregate
57
+ data = {}
58
+ data[:project_path] = self.path
59
+ data[:project_name] = self.name
60
+ data[:current_branch] = self.branchname
61
+ data[:remotes] = self.remotes.map(&:name)
62
+ data[:remote_urls] = self.remotes.map(&:url)
63
+ data[:remote_branches] = self.remote_branches
64
+ data[:project_identifier] = self.identifier
65
+ data
66
+ end
67
+
68
+ end
69
+
70
+ end
data/lib/sender.rb ADDED
@@ -0,0 +1,63 @@
1
+ module GitReport
2
+
3
+ class Sender
4
+
5
+ # sends or saves the commits
6
+ def self.send! options = nil
7
+ commits = GitReport::Supplier.commits(options)
8
+ commits.each do |commit|
9
+ send_data!(commit) ? commits = commits.inject([]){ |a,i| ( a << i unless i == commit );a } : break # weird, delete fails here
10
+ end
11
+ storage.save! commits
12
+
13
+ true
14
+ end
15
+
16
+ private
17
+
18
+ # sends the commit data to the server
19
+ def self.send_data! commit, options = nil
20
+ begin
21
+ response = Net::HTTP.Proxy(configuration.proxy_host, configuration.proxy_port).start(configuration.host, configuration.port) do |http|
22
+ request = Net::HTTP::Post.new(request_path options)
23
+ headers request
24
+ request.body = commit.to_json
25
+ http.open_timeout = configuration.timeout
26
+ http.read_timeout = configuration.timeout
27
+ http.request request
28
+ end
29
+ raise StandardError unless (response.code == "200" or response.code == "401")
30
+ rescue Exception => e
31
+ puts "Error during sending the commit: #{e}"
32
+ return false
33
+ end
34
+
35
+ true
36
+ end
37
+
38
+ # returns local storage
39
+ def self.storage
40
+ @@storage ||= GitReport::Storage.new(ENV['HOME'], '.gitreport_storage')
41
+ end
42
+
43
+ # returns configuration object
44
+ def self.configuration
45
+ @@configuration ||= GitReport.configuration
46
+ end
47
+
48
+ # returns the request path
49
+ def self.request_path options
50
+ @@path ||= "/v#{configuration.api_version}/commits"
51
+ end
52
+
53
+ # returns the default headers
54
+ def self.headers request
55
+ request['User-Agent'] = 'gitreport-client-ruby'
56
+ request['Content-Type'] = 'application/json'
57
+ request['Accept'] = 'application/json'
58
+ request['X-gitreport-Auth-Token'] = configuration.auth_token
59
+ end
60
+
61
+ end
62
+
63
+ end
data/lib/storage.rb ADDED
@@ -0,0 +1,27 @@
1
+ require 'base64'
2
+
3
+ module GitReport
4
+ class Storage
5
+
6
+ # inits storage object
7
+ def initialize path, filename
8
+ @path = path
9
+ @filename = filename
10
+ end
11
+
12
+ # locally stores data
13
+ def save! data
14
+ File.open("#{@path}/#{@filename}", 'w+') do |file|
15
+ file.write Base64.encode64(Marshal.dump(data))
16
+ end
17
+ end
18
+
19
+ # loads locally stored data
20
+ def load
21
+ if File.exists?("#{@path}/#{@filename}")
22
+ data = File.read "#{@path}/#{@filename}"
23
+ Marshal.load(Base64.decode64(data)) rescue NameError
24
+ end
25
+ end
26
+ end
27
+ end
data/lib/supplier.rb ADDED
@@ -0,0 +1,53 @@
1
+ module GitReport
2
+
3
+ class Supplier
4
+
5
+ # returns the commits in relation to the given option
6
+ def self.commits options
7
+ raise "No option given to fetch commits" unless options
8
+ case options
9
+ when :last_and_stored
10
+ last_and_stored_commits
11
+ when :stored
12
+ stored_commits
13
+ when :history
14
+ # history_commits :user #slow
15
+ history_commits :all #fast
16
+
17
+ # we sort out the foreign commits on the server if the user has a single user account
18
+ # this way we can realize company accounts and already have all the data we need during import
19
+ else
20
+ []
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ # returns stored commits plus the last commit taken
27
+ def self.last_and_stored_commits
28
+ @@all_commits ||= (stored_commits || []).push(recent_commit)
29
+ end
30
+
31
+ # returns the stored commits that could not be send before
32
+ def self.stored_commits
33
+ storage.load
34
+ end
35
+
36
+ # returns all commits of the actual user that were taken in the past
37
+ # DO NOT cache here!!
38
+ def self.history_commits scope
39
+ GitReport::History.commits(scope)
40
+ end
41
+
42
+ # returns the commit that should be send now
43
+ def self.recent_commit
44
+ @@commit_data ||= GitReport::Commit.new(GitReport.project.log.last, GitReport.project.identifier)
45
+ end
46
+
47
+ # returns local storage
48
+ def self.storage
49
+ @@storage ||= GitReport::Storage.new(ENV['HOME'], '.gitreport_storage')
50
+ end
51
+ end
52
+
53
+ end