gitreport 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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