brown_noser 0.1.2 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 499cd85310b74f6cb80f4330be3f59fefd7c77f0
4
- data.tar.gz: 0bc0ae8d96d9d849ba221430c3ad3d019369e65a
3
+ metadata.gz: b5d664dcc46feadfc8739def0c8d3920c4c4e093
4
+ data.tar.gz: 026a938363429d9accce0a82651d4c757668b32f
5
5
  SHA512:
6
- metadata.gz: 9f32139d5c73a6c8aaf4f5520d78071c8d7140d998ea2dbe2adb3953ed9329f11db8c00d807297f4064a2574f9c27e9f946c47c33be818e319ad890bc7dbc99d
7
- data.tar.gz: dce5f18fbccca926d2432c681f4c89916e3ce708b75f0c8641efe0585f24481045577ec1f71573a2da1e5de15bc1b2647129d80a61f71afce70fad94af83bb94
6
+ metadata.gz: 98e396aeca9adee12359253d4619ad56e0e9787199ed0b7524031a9df3ae4f5691e4debd9c83cf9dcbf8e66569f9bc7a10bfe9f830835a00af6ebb918b12613f
7
+ data.tar.gz: d3ed1ef2733619002ac66d96e375a85817461913b3c46891ece862e71d153b3166b07bf03973b96b9bb65217a2d491b9dfe82de68b45fddaac3a15ac4d3dc966
data/Gemfile CHANGED
@@ -7,4 +7,5 @@ gem 'awesome_print'
7
7
  gem 'foreman'
8
8
  gem 'rake'
9
9
  gem 'pry'
10
+ gem 'moss_ruby'
10
11
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- teachers_pet (0.1.0)
4
+ brown_noser (0.1.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -14,6 +14,7 @@ GEM
14
14
  foreman (0.78.0)
15
15
  thor (~> 0.19.1)
16
16
  method_source (0.8.2)
17
+ moss_ruby (1.1.2)
17
18
  multipart-post (2.0.0)
18
19
  octokit (4.2.0)
19
20
  sawyer (~> 0.6.0, >= 0.5.3)
@@ -33,12 +34,13 @@ PLATFORMS
33
34
 
34
35
  DEPENDENCIES
35
36
  awesome_print
37
+ brown_noser!
36
38
  bundler (~> 1.10)
37
39
  foreman
40
+ moss_ruby
38
41
  octokit (~> 4.0)
39
42
  pry
40
43
  rake
41
- teachers_pet!
42
44
 
43
45
  BUNDLED WITH
44
46
  1.10.6
data/README.md CHANGED
@@ -1,15 +1,21 @@
1
- # TeachersPet
1
+ # BrownNoser
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/teachers_pet`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ This tool is to help manage and inspect Git Repos used for our the Coursework at WCCCEDU.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ ## Major Milestones
6
+ - Sync pull request branches locally so they can be reviewed and graded locally
7
+ - Search all submissions to validate academnic honesty
8
+ - Step through each submission branch and build/compile/execute the code
9
+ - Run automated tests and fuzzy acceptance on output on each submission based on a project described _Rubric_ file
10
+ - Provide DSL to work with compiled and web based execution
11
+ - Integrate with Linters to verify student style to save time on pedantic comments by automating comments on student repos for teachers review.
6
12
 
7
13
  ## Installation
8
14
 
9
15
  Add this line to your application's Gemfile:
10
16
 
11
17
  ```ruby
12
- gem 'teachers_pet'
18
+ gem 'brown_noser', '~> 0.1.2'
13
19
  ```
14
20
 
15
21
  And then execute:
@@ -18,21 +24,32 @@ And then execute:
18
24
 
19
25
  Or install it yourself as:
20
26
 
21
- $ gem install teachers_pet
27
+ $ gem install brown_noser
22
28
 
23
29
  ## Usage
24
30
 
25
- TODO: Write usage instructions here
31
+ This gem exposes the `pet` command
26
32
 
27
- ## Development
33
+ ### Sync PR Branches
34
+ Bring unmerged branches to local repo for easy viewing and searching without merging.
35
+ ```
36
+ pet <user> <repo> -u <username> -p <password> -s
37
+ pet <user> <repo> --username <username> --pasword <password> --sync
38
+ ```
28
39
 
29
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
40
+ ### Search for patterns in local repo (Help find cheating)
41
+ ```
42
+ pet -f 'Your query or Regex'
43
+ pet --find 'Your query or Regex'
44
+ ```
45
+
46
+ ## Development
30
47
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
48
+ Clone and run `bundle install` to receive deps.
32
49
 
33
50
  ## Contributing
34
51
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/teachers_pet.
52
+ Bug reports and pull requests are welcome on GitHub at https://github.com/WCCCEDU/brown_noser.
36
53
 
37
54
 
38
55
  ## License
@@ -1,3 +1,3 @@
1
1
  module BrownNoser
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/brown_noser.rb CHANGED
@@ -2,6 +2,8 @@ require 'optparse'
2
2
  autoload :ClientResolver, File.expand_path(File.dirname(__FILE__)) + '/client_resolver.rb'
3
3
  autoload :ProjectRepoSync, File.expand_path(File.dirname(__FILE__)) + '/project_repo_sync.rb'
4
4
  autoload :ProjectRepoSearcher, File.expand_path(File.dirname(__FILE__)) + '/project_repo_searcher.rb'
5
+ autoload :CheatingDetection, File.expand_path(File.dirname(__FILE__)) + '/cheating_detection.rb'
6
+ autoload :PullBranchLister, File.expand_path(File.dirname(__FILE__)) + '/pull_branch_lister.rb'
5
7
 
6
8
  class BrownNoser
7
9
  attr_reader :options
@@ -13,8 +15,9 @@ class BrownNoser
13
15
 
14
16
  opts.on('-s', '--sync', 'Sync') { |v| @options[:sync_flag] = true }
15
17
  opts.on('-f', '--find QUERY', 'Find') { |v| @options[:query] = v }
16
- opts.on('-u', '--username USER', 'Source host') { |v| @options[:username] = v }
17
- opts.on('-p', '--password PASS', 'Source port') { |v| @options[:password] = v }
18
+ opts.on('-u', '--username USER', 'Github User') { |v| @options[:username] = v }
19
+ opts.on('-p', '--password PASS', 'Github Pass') { |v| @options[:password] = v }
20
+ opts.on('-c', '--cheat MOSSID', 'Moss Userid') { |v| @options[:moss_id] = v }
18
21
 
19
22
  end.parse!
20
23
  end
@@ -30,12 +33,16 @@ class BrownNoser
30
33
  def run
31
34
  sync = @options[:sync_flag]
32
35
  find = @options[:query]
36
+ cheat = @options[:moss_id]
33
37
  resolve_client
34
38
  if sync
35
39
  repo_syncer = ProjectRepoSync.new ARGV[0], ARGV[1]
36
40
  repo_syncer.sync_assignment_branches
37
41
  elsif find
38
42
  searcher = ProjectRepoSearcher.new.search find
43
+ elsif cheat
44
+ puts "CHEAT"
45
+ cheat_detection = CheatingDetection.new(ARGV[0], ARGV[1], cheat).detect
39
46
  end
40
47
  end
41
48
  end
@@ -0,0 +1,105 @@
1
+ require 'moss_ruby'
2
+ require 'fileutils'
3
+
4
+ class CheatingDetection
5
+
6
+ TEMP_DIR = 'brown_noser_cheat_detection'
7
+
8
+ def initialize(user, repo, moss_id = 000000000)
9
+ @user = user
10
+ @repo = repo
11
+ @moss_id = moss_id
12
+ end
13
+
14
+ def detect
15
+ pull_details = PullBranchLister.new(@user, @repo).list
16
+
17
+ recreate_tmp_dir
18
+
19
+ commands = pull_details.map &command_orgnaizer()
20
+
21
+ commands.flatten.each do |command|
22
+ prepared_command = command.call
23
+ puts prepared_command unless prepared_command.empty?
24
+ `#{prepared_command}` unless prepared_command.empty?
25
+ end
26
+
27
+ # Create the MossRuby object
28
+ @moss ||= MossRuby.new(@moss_id) #replace 000000000 with your user id
29
+
30
+ # Set options -- the options will already have these default values
31
+ @moss.options[:max_matches] = 10
32
+ @moss.options[:directory_submission] = false
33
+ @moss.options[:show_num_matches] = 250
34
+ @moss.options[:experimental_server] = false
35
+ @moss.options[:comment] = ""
36
+ @moss.options[:language] = "cc"
37
+
38
+ # Create a file hash, with the files to be processed
39
+ to_check = MossRuby.empty_file_hash
40
+ #MossRuby.add_file(to_check, "#{TEMP_DIR}/**/*.h")
41
+ MossRuby.add_file(to_check, "#{TEMP_DIR}/**/*.cpp")
42
+
43
+ # Get server to process files
44
+ url = @moss.check to_check
45
+
46
+ IO.write "brown_noser.html", "<div><h3>Cheat Detection Results</h3><br/><a href='#{url}'>#{url}</a></div>"
47
+ FileUtils.rm_rf TEMP_DIR
48
+
49
+ # Get results
50
+ results = @moss.extract_results url
51
+ end
52
+
53
+ private
54
+ def make_folder_for_branch(user, branch)
55
+ ->(){ FileUtils.mkdir_p("#{TEMP_DIR}/#{user}_#{branch}") }
56
+ end
57
+
58
+ def copy_file(source, dest)
59
+ ->(){ "cp \"#{source}\" \"#{dest}\"" }
60
+ end
61
+
62
+ def extract_source_files(user, branch, dest_folder)
63
+ ->(){
64
+ files = `git ls-tree --full-name --name-only -r #{user}/#{branch} | grep '.h$\\|.cpp$'`.split("\n")
65
+ copy_files = files.map do |file|
66
+ copy_file(file, "#{dest_folder}/#{file}").call
67
+ end
68
+ copy_files.join(" && ")
69
+ }
70
+ end
71
+
72
+ def recreate_tmp_dir
73
+ FileUtils.rm_rf TEMP_DIR
74
+ FileUtils.mkdir TEMP_DIR
75
+ end
76
+
77
+ def command_orgnaizer
78
+ ->(pull_context){
79
+ [
80
+ make_folder_for_branch(pull_context[0], pull_context[1]),
81
+ ProjectRepoSync::git_checkout("#{pull_context[0]}/#{pull_context[1]}"),
82
+ extract_source_files(pull_context[0], pull_context[1], "#{TEMP_DIR}/#{pull_context[0]}_#{pull_context[1]}")
83
+ ]
84
+ }
85
+ end
86
+
87
+ def extract_results
88
+ results.each_with_index { |match, i|
89
+ match.each { |file|
90
+ report_match = <<-HTML
91
+ <div class="match">
92
+ <h3>#{file[:filename]}</h3>
93
+ <h4>#{file[:pct]}</h4>
94
+ <h4>#{file[:url]}</h4>
95
+ <h4>#{file[:part_url]}</h4>
96
+ <div class="code">#{file[:html]}</div>
97
+ </div>
98
+ HTML
99
+ result_html += report_match
100
+ }
101
+ result_html += "<hr/>"
102
+ }
103
+ IO.write "cheat_report.html", result_html
104
+ end
105
+ end
@@ -1,8 +1,9 @@
1
1
  class ProjectRepoSync
2
2
  attr_reader :user, :repo
3
3
 
4
- PULL_EXTRACTOR = ->(pull){ pull.head.label }
5
- GIT_COMMAND_EXTRACTOR = ->(pull_info){ pull_info.split(':') }
4
+ def self.git_checkout(branch)
5
+ ->(){ "git checkout #{branch}" }
6
+ end
6
7
 
7
8
  def initialize(user, repo)
8
9
  @client = ClientResolver.client
@@ -11,8 +12,7 @@ class ProjectRepoSync
11
12
  end
12
13
 
13
14
  def sync_assignment_branches
14
- pulls = @client.pulls "#{@user}/#{@repo}"
15
- pull_details = pulls.map(&PULL_EXTRACTOR).map(&GIT_COMMAND_EXTRACTOR)
15
+ pull_details = PullBranchLister.new(@user, @repo).list
16
16
 
17
17
  %x(git checkout -f master | git branch | grep -v "^..master$" | sed 's/^[ *]*//' | sed 's/^/git branch -D /' | bash)
18
18
 
@@ -34,10 +34,6 @@ private
34
34
  ->(){ "git checkout -B #{user}/#{branch} master" }
35
35
  end
36
36
 
37
- def git_checkout(branch)
38
- ->(){ "git checkout #{branch}" }
39
- end
40
-
41
37
  def git_pull(repo_url, branch)
42
38
  ->(){ "git pull #{repo_url} #{branch}" }
43
39
  end
@@ -47,7 +43,7 @@ private
47
43
  [
48
44
  git_checkout_new( pull_context[0], pull_context[1] ),
49
45
  git_pull( prep_repo(pull_context[0], @repo).call, pull_context[1] ),
50
- git_checkout( 'master' )
46
+ ProjectRepoSync::git_checkout( 'master' )
51
47
  ]
52
48
  }
53
49
  end
@@ -0,0 +1,16 @@
1
+ class PullBranchLister
2
+
3
+ PULL_EXTRACTOR = ->(pull){ pull.head.label }
4
+ GIT_COMMAND_EXTRACTOR = ->(pull_info){ pull_info.split(':') }
5
+
6
+ def initialize(user, repo)
7
+ @client = ClientResolver.client
8
+ @user = user
9
+ @repo = repo
10
+ end
11
+
12
+ def list
13
+ pulls = @client.pulls "#{@user}/#{@repo}"
14
+ pulls.map(&PULL_EXTRACTOR).map(&GIT_COMMAND_EXTRACTOR)
15
+ end
16
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brown_noser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Scarrone
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-03 00:00:00.000000000 Z
11
+ date: 2016-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -84,9 +84,11 @@ files:
84
84
  - brown_noser.gemspec
85
85
  - lib/brown_noser.rb
86
86
  - lib/brown_noser/version.rb
87
+ - lib/cheating_detection.rb
87
88
  - lib/client_resolver.rb
88
89
  - lib/project_repo_searcher.rb
89
90
  - lib/project_repo_sync.rb
91
+ - lib/pull_branch_lister.rb
90
92
  homepage: https://github.com/WCCCEDU/github_grading_tools_rb
91
93
  licenses:
92
94
  - MIT