brown_noser 0.2.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b5d664dcc46feadfc8739def0c8d3920c4c4e093
4
- data.tar.gz: 026a938363429d9accce0a82651d4c757668b32f
3
+ metadata.gz: e40fcf62cf35b124491ebfad296fef3b965c5564
4
+ data.tar.gz: c11e0646be3988b06ad3e84d678e59c9476e6f66
5
5
  SHA512:
6
- metadata.gz: 98e396aeca9adee12359253d4619ad56e0e9787199ed0b7524031a9df3ae4f5691e4debd9c83cf9dcbf8e66569f9bc7a10bfe9f830835a00af6ebb918b12613f
7
- data.tar.gz: d3ed1ef2733619002ac66d96e375a85817461913b3c46891ece862e71d153b3166b07bf03973b96b9bb65217a2d491b9dfe82de68b45fddaac3a15ac4d3dc966
6
+ metadata.gz: 687cc3f565935ce35417393bdc934f82e1c7efdf51a213f32548221d946a5135e98b573670cdc68ddbf1c99a966b392cbc2eb74228c673b3dddd3d2d7efe5a42
7
+ data.tar.gz: bb245d3eacfa69702a442f7cb2d53091ee27645e51c8f2729f782bbba68358374837b70ac45f0bfd37e8d089387482d637f1eca86421e54ad9352dd015100a51
data/README.md CHANGED
@@ -43,6 +43,17 @@ pet -f 'Your query or Regex'
43
43
  pet --find 'Your query or Regex'
44
44
  ```
45
45
 
46
+ ### Detect with Cheating through MOSS
47
+ Currently supports .cpp files only more coming soon
48
+ ```
49
+ pet <user> <repo> -u <username> -p <password> -c <moss_id>
50
+ ```
51
+ The resulting `brown_noser.html` will include a link so you can view the comparisons that MOSS detected as possible duplication.
52
+
53
+ ##### Create a moss account so you can have a moss_id
54
+ Visit [https://theory.stanford.edu/~aiken/moss/](https://theory.stanford.edu/~aiken/moss/) and follow the instructions listed under `Registering for MOSS`.
55
+ Once you send your registration email you will receive a response containing a bunch of perl code. Search the email for `userid`, your MOSS ID will look like this 11111927.
56
+
46
57
  ## Development
47
58
 
48
59
  Clone and run `bundle install` to receive deps.
@@ -1,3 +1,3 @@
1
1
  module BrownNoser
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
data/lib/brown_noser.rb CHANGED
@@ -1,9 +1,10 @@
1
1
  require 'optparse'
2
- autoload :ClientResolver, File.expand_path(File.dirname(__FILE__)) + '/client_resolver.rb'
3
- autoload :ProjectRepoSync, File.expand_path(File.dirname(__FILE__)) + '/project_repo_sync.rb'
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'
2
+ autoload :ClientResolver, File.expand_path(File.dirname(__FILE__)) + '/client_resolver.rb'
3
+ autoload :ProjectRepoSync, File.expand_path(File.dirname(__FILE__)) + '/project_repo_sync.rb'
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'
7
+ autoload :PullBranchFileExtractor, File.expand_path(File.dirname(__FILE__)) + '/pull_branch_file_extractor.rb'
7
8
 
8
9
  class BrownNoser
9
10
  attr_reader :options
@@ -42,7 +43,7 @@ class BrownNoser
42
43
  searcher = ProjectRepoSearcher.new.search find
43
44
  elsif cheat
44
45
  puts "CHEAT"
45
- cheat_detection = CheatingDetection.new(ARGV[0], ARGV[1], cheat).detect
46
+ cheat_detection = CheatingDetection.new(ARGV[0], ARGV[1], {moss_id: cheat}).detect
46
47
  end
47
48
  end
48
49
  end
@@ -3,87 +3,47 @@ require 'fileutils'
3
3
 
4
4
  class CheatingDetection
5
5
 
6
+ MOSS_LOGGER_CALLBACK = ->(message=""){puts message}
6
7
  TEMP_DIR = 'brown_noser_cheat_detection'
7
8
 
8
- def initialize(user, repo, moss_id = 000000000)
9
+ def initialize(user, repo, moss_options={})
9
10
  @user = user
10
11
  @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
12
+ @moss_id = moss_options.fetch(:moss_id, 000000000)
26
13
 
27
14
  # Create the MossRuby object
28
15
  @moss ||= MossRuby.new(@moss_id) #replace 000000000 with your user id
29
16
 
30
17
  # 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"
18
+ @moss.options[:max_matches] = moss_options.fetch(:max_matches, 10)
19
+ @moss.options[:directory_submission] = moss_options.fetch(:directory_submission, false)
20
+ @moss.options[:show_num_matches] = moss_options.fetch(:show_num_matches, 250)
21
+ @moss.options[:experimental_server] = moss_options.fetch(:experimental_server, false)
22
+ @moss.options[:comment] = moss_options.fetch(:comment, '')
23
+ @moss.options[:language] = moss_options.fetch(:comment, 'cc')
24
+ end
25
+
26
+ def detect
27
+ pull_details = PullBranchLister.new(@user, @repo).list
28
+ extractor = PullBranchFileExtractor.new(TEMP_DIR, pull_details)
29
+ extractor.extract
37
30
 
38
31
  # Create a file hash, with the files to be processed
39
32
  to_check = MossRuby.empty_file_hash
40
- #MossRuby.add_file(to_check, "#{TEMP_DIR}/**/*.h")
41
- MossRuby.add_file(to_check, "#{TEMP_DIR}/**/*.cpp")
33
+ files_to_check = Dir.glob("#{TEMP_DIR}/**/*").select { |f| f =~ /\.(h|cpp)$/ }
34
+ MossRuby.add_file(to_check, files_to_check)
42
35
 
43
36
  # Get server to process files
44
- url = @moss.check to_check
37
+ url = @moss.check to_check, MOSS_LOGGER_CALLBACK
45
38
 
46
39
  IO.write "brown_noser.html", "<div><h3>Cheat Detection Results</h3><br/><a href='#{url}'>#{url}</a></div>"
47
- FileUtils.rm_rf TEMP_DIR
40
+ extractor.cleanup
48
41
 
49
42
  # Get results
50
43
  results = @moss.extract_results url
51
44
  end
52
45
 
53
46
  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
47
  def extract_results
88
48
  results.each_with_index { |match, i|
89
49
  match.each { |file|
@@ -0,0 +1,61 @@
1
+ class PullBranchFileExtractor
2
+ def initialize(temp_dir, pull_details)
3
+ @temp_dir = temp_dir
4
+ @pull_details = pull_details
5
+ end
6
+
7
+ def extract
8
+ clean_tmp_dir
9
+ create_tmp_dir
10
+
11
+ commands = @pull_details.map &command_orgnaizer()
12
+
13
+ commands.flatten.each do |command|
14
+ prepared_command = command.call
15
+ puts prepared_command unless prepared_command.empty?
16
+ `#{prepared_command}` unless prepared_command.empty?
17
+ end
18
+ end
19
+
20
+ def cleanup
21
+ clean_tmp_dir
22
+ end
23
+
24
+ private
25
+
26
+ def create_tmp_dir
27
+ FileUtils.mkdir @temp_dir
28
+ end
29
+
30
+ def clean_tmp_dir
31
+ FileUtils.rm_rf @temp_dir
32
+ end
33
+
34
+ def make_folder_for_branch(user, branch)
35
+ ->(){ FileUtils.mkdir_p("#{@temp_dir}/#{user}_#{branch}") }
36
+ end
37
+
38
+ def copy_file(source, dest)
39
+ ->(){ "cp \"#{source}\" \"#{dest}\"" }
40
+ end
41
+
42
+ def extract_source_files(user, branch, dest_folder)
43
+ ->(){
44
+ files = `git ls-tree --full-name --name-only -r #{user}/#{branch} | grep '\.h$\\|\.cpp$'`.split("\n")
45
+ copy_files = files.map do |file|
46
+ copy_file(file, "#{dest_folder}/#{file}").call
47
+ end
48
+ copy_files.join(" && ")
49
+ }
50
+ end
51
+
52
+ def command_orgnaizer
53
+ ->(pull_context){
54
+ [
55
+ make_folder_for_branch(pull_context[0], pull_context[1]),
56
+ ProjectRepoSync::git_checkout("#{pull_context[0]}/#{pull_context[1]}"),
57
+ extract_source_files(pull_context[0], pull_context[1], "#{@temp_dir}/#{pull_context[0]}_#{pull_context[1]}")
58
+ ]
59
+ }
60
+ end
61
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brown_noser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Scarrone
@@ -88,6 +88,7 @@ files:
88
88
  - lib/client_resolver.rb
89
89
  - lib/project_repo_searcher.rb
90
90
  - lib/project_repo_sync.rb
91
+ - lib/pull_branch_file_extractor.rb
91
92
  - lib/pull_branch_lister.rb
92
93
  homepage: https://github.com/WCCCEDU/github_grading_tools_rb
93
94
  licenses: