Skip to content

Add submission_url to config and refactor logic into services #90

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
source "https://rubygems.org"
# Add dependencies required to use your gem here.
# Example:

gem "activesupport", ">= 2.3.5"
gem "oj", "~> 3.13.12"
gem "octokit", "~> 5.0"
gem "zip"
gem "faraday-retry", "~> 1.0.3"
gem "rake", "~> 13"
# Add dependencies to develop your gem here.
# Include everything needed to run rake, tests, features, etc.

group :development do
gem "rspec", "~> 3.5.0"
gem "rdoc", "~> 6.1"
gem "bundler", "~> 2.1.4"
gem "juwelier", "~> 2.1.0"
gem "bundler", "~> 2.6.7"
gem "juwelier", "~> 2.4.9"
gem "simplecov", ">= 0"
gem "pry", "~> 0"
gem "pry-byebug", "~> 3"
Expand Down
24 changes: 14 additions & 10 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,21 @@ GEM
i18n (1.14.1)
concurrent-ruby (~> 1.0)
interception (0.5)
juwelier (2.1.3)
juwelier (2.4.9)
builder
bundler (>= 1.13)
git (>= 1.2.5)
bundler
git
github_api
highline (>= 1.6.15)
nokogiri (>= 1.5.10)
highline
kamelcase (~> 0)
nokogiri
psych
rake
rdoc
semver
semver2
jwt (2.7.0)
kamelcase (0.0.2)
semver2 (~> 3)
method_source (1.0.0)
mini_portile2 (2.8.1)
minitest (5.19.0)
Expand Down Expand Up @@ -130,7 +134,7 @@ GEM
sawyer (0.9.2)
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
semver (1.0.1)
semver2 (3.4.2)
simplecov (0.21.2)
docile (~> 1.1)
simplecov-html (~> 0.11)
Expand All @@ -152,9 +156,9 @@ PLATFORMS

DEPENDENCIES
activesupport (>= 2.3.5)
bundler (~> 2.1.4)
bundler (~> 2.6.7)
faraday-retry (~> 1.0.3)
juwelier (~> 2.1.0)
juwelier (~> 2.4.9)
octokit (~> 5.0)
oj (~> 3.13.12)
pry (~> 0)
Expand All @@ -170,4 +174,4 @@ DEPENDENCIES
zip

BUNDLED WITH
2.1.4
2.6.7
3 changes: 2 additions & 1 deletion README.markdown
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# grade_runner

A Ruby client for [firstdraft Grades](https://grades.firstdraft.com)
A Ruby client for [Grades](https://grades.firstdraft.com)


## Installation
Expand Down Expand Up @@ -48,6 +48,7 @@ if Rails.env.development? || Rails.env.test?
GradeRunner.config do |config|
config.default_points = 1 # default 1
config.override_local_specs = false # default true
config.submission_url = "https://your-grading-server-url.com" # Set custom submission URL
end
end
```
Expand Down
3 changes: 3 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ Juwelier::Tasks.new do |gem|
gem.email = ["[email protected]", "[email protected]"]
gem.authors = ["Raghu Betina", "Jelani Woods"]

# Note: rspec tests do not yet support 3.4 (BigDecimal)
gem.required_ruby_version = Gem::Requirement.new(">= 2", "< 3.4")

# dependencies defined in Gemfile
end
Juwelier::RubygemsDotOrgTasks.new
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.13
0.0.14
79 changes: 34 additions & 45 deletions grade_runner.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
# DO NOT EDIT THIS FILE DIRECTLY
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
# -*- encoding: utf-8 -*-
# stub: grade_runner 0.0.13 ruby lib
# stub: grade_runner 0.0.14 ruby lib

Gem::Specification.new do |s|
s.name = "grade_runner".freeze
s.version = "0.0.13"
s.version = "0.0.14"

s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib".freeze]
s.authors = ["Raghu Betina".freeze, "Jelani Woods".freeze]
s.date = "2025-03-17"
s.date = "2025-04-03"
s.description = "This gem runs your RSpec test suite and posts the JSON output to grades.firstdraft.com.".freeze
s.email = ["[email protected]".freeze, "[email protected]".freeze]
s.extra_rdoc_files = [
Expand All @@ -29,57 +29,46 @@ Gem::Specification.new do |s|
"VERSION",
"grade_runner.gemspec",
"lib/grade_runner.rb",
"lib/grade_runner/formatters/hint_formatter.rb",
"lib/grade_runner/formatters/json_output_formatter.rb",
"lib/grade_runner/railtie.rb",
"lib/grade_runner/runner.rb",
"lib/grade_runner/services/config_service.rb",
"lib/grade_runner/services/github_service.rb",
"lib/grade_runner/services/grade_service.rb",
"lib/grade_runner/services/spec_service.rb",
"lib/grade_runner/services/token_service.rb",
"lib/grade_runner/utils/path_utils.rb",
"lib/tasks/grade.rake",
"lib/tasks/grade_runner.rake",
"spec/spec_helper.rb"
"spec/grade_service_spec.rb",
"spec/spec_helper.rb",
"spec/spec_service_spec.rb"
]
s.homepage = "http://github.com/firstdraft/grade_runner".freeze
s.licenses = ["MIT".freeze]
s.rubygems_version = "3.1.6".freeze
s.required_ruby_version = Gem::Requirement.new([">= 2".freeze, "< 3.4".freeze])
s.rubygems_version = "3.4.6".freeze
s.summary = "A Ruby client for [firstdraft Grades](https://grades.firstdraft.com)".freeze

if s.respond_to? :specification_version then
s.specification_version = 4
end
s.specification_version = 4

if s.respond_to? :add_runtime_dependency then
s.add_runtime_dependency(%q<activesupport>.freeze, [">= 2.3.5"])
s.add_runtime_dependency(%q<oj>.freeze, ["~> 3.13.12"])
s.add_runtime_dependency(%q<octokit>.freeze, ["~> 5.0"])
s.add_runtime_dependency(%q<zip>.freeze, [">= 0"])
s.add_runtime_dependency(%q<faraday-retry>.freeze, ["~> 1.0.3"])
s.add_runtime_dependency(%q<rake>.freeze, ["~> 13"])
s.add_development_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
s.add_development_dependency(%q<rdoc>.freeze, ["~> 6.1"])
s.add_development_dependency(%q<bundler>.freeze, ["~> 2.1.4"])
s.add_development_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
s.add_development_dependency(%q<pry>.freeze, ["~> 0"])
s.add_development_dependency(%q<pry-byebug>.freeze, ["~> 3"])
s.add_development_dependency(%q<pry-doc>.freeze, ["~> 0"])
s.add_development_dependency(%q<pry-remote>.freeze, ["~> 0"])
s.add_development_dependency(%q<pry-rescue>.freeze, ["~> 1"])
s.add_development_dependency(%q<pry-stack_explorer>.freeze, ["~> 0"])
else
s.add_dependency(%q<activesupport>.freeze, [">= 2.3.5"])
s.add_dependency(%q<oj>.freeze, ["~> 3.13.12"])
s.add_dependency(%q<octokit>.freeze, ["~> 5.0"])
s.add_dependency(%q<zip>.freeze, [">= 0"])
s.add_dependency(%q<faraday-retry>.freeze, ["~> 1.0.3"])
s.add_dependency(%q<rake>.freeze, ["~> 13"])
s.add_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
s.add_dependency(%q<rdoc>.freeze, ["~> 6.1"])
s.add_dependency(%q<bundler>.freeze, ["~> 2.1.4"])
s.add_dependency(%q<juwelier>.freeze, ["~> 2.1.0"])
s.add_dependency(%q<simplecov>.freeze, [">= 0"])
s.add_dependency(%q<pry>.freeze, ["~> 0"])
s.add_dependency(%q<pry-byebug>.freeze, ["~> 3"])
s.add_dependency(%q<pry-doc>.freeze, ["~> 0"])
s.add_dependency(%q<pry-remote>.freeze, ["~> 0"])
s.add_dependency(%q<pry-rescue>.freeze, ["~> 1"])
s.add_dependency(%q<pry-stack_explorer>.freeze, ["~> 0"])
end
s.add_runtime_dependency(%q<activesupport>.freeze, [">= 2.3.5"])
s.add_runtime_dependency(%q<oj>.freeze, ["~> 3.13.12"])
s.add_runtime_dependency(%q<octokit>.freeze, ["~> 5.0"])
s.add_runtime_dependency(%q<zip>.freeze, [">= 0"])
s.add_runtime_dependency(%q<faraday-retry>.freeze, ["~> 1.0.3"])
s.add_runtime_dependency(%q<rake>.freeze, ["~> 13"])
s.add_development_dependency(%q<rspec>.freeze, ["~> 3.5.0"])
s.add_development_dependency(%q<rdoc>.freeze, ["~> 6.1"])
s.add_development_dependency(%q<bundler>.freeze, ["~> 2.6.7"])
s.add_development_dependency(%q<juwelier>.freeze, ["~> 2.4.9"])
s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
s.add_development_dependency(%q<pry>.freeze, ["~> 0"])
s.add_development_dependency(%q<pry-byebug>.freeze, ["~> 3"])
s.add_development_dependency(%q<pry-doc>.freeze, ["~> 0"])
s.add_development_dependency(%q<pry-remote>.freeze, ["~> 0"])
s.add_development_dependency(%q<pry-rescue>.freeze, ["~> 1"])
s.add_development_dependency(%q<pry-stack_explorer>.freeze, ["~> 0"])
end

18 changes: 17 additions & 1 deletion lib/grade_runner.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
require "grade_runner/runner"
require "grade_runner/utils/path_utils"
require "grade_runner/services/token_service"
require "grade_runner/services/config_service"
require "grade_runner/services/github_service"
require "grade_runner/services/spec_service"
require "grade_runner/services/grade_service"
require "grade_runner/railtie" if defined?(Rails)

module GradeRunner
class Error < StandardError; end

DEFAULT_SUBMISSION_URL = "https://grades.firstdraft.com"

class << self
attr_writer :default_points, :override_local_specs
attr_writer :default_points, :override_local_specs, :submission_url

def default_points
@default_points || 1
Expand All @@ -19,8 +27,16 @@ def override_local_specs
end
end

def submission_url
@submission_url || DEFAULT_SUBMISSION_URL
end

def config
yield self
end

def project_root
Utils::PathUtils.project_root
end
end
end
12 changes: 6 additions & 6 deletions lib/grade_runner/formatters/json_output_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def dump_summary(summary)
examples.
map { |example| example.metadata.fetch(:points, GradeRunner.default_points).to_i }.
sum

earned_points = summary.
examples.
select { |example| example.execution_result.status == :passed }.
Expand All @@ -17,7 +17,7 @@ def dump_summary(summary)

score = (earned_points.to_f / total_points).round(4)
score = 0 if score.nan?

@output_hash[:summary] = {
duration: summary.duration,
example_count: summary.example_count,
Expand All @@ -29,14 +29,14 @@ def dump_summary(summary)
score: score
}
result = (@output_hash[:summary][:score] * 100).round(2)

if summary.errors_outside_of_examples_count.positive?
result = "An error occurred while running tests"
else
result = result.to_s + "%"
end


@output_hash[:summary_line] = [
"#{summary.example_count} #{summary.example_count == 1 ? "test" : "tests"}",
"#{summary.failure_count} failures",
Expand All @@ -48,7 +48,7 @@ def dump_summary(summary)
def close(_notification)
output.write Oj.dump @output_hash
end

private

def format_example(example)
Expand Down
2 changes: 0 additions & 2 deletions lib/grade_runner/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

module GradeRunner
class Runner

def initialize(submission_root_url, grades_access_token, rspec_output_json, username, reponame, sha, source)
@submission_url = submission_root_url + submission_path
@grades_access_token = grades_access_token
Expand Down Expand Up @@ -47,6 +46,5 @@ def data
source: @source
}
end

end
end
55 changes: 55 additions & 0 deletions lib/grade_runner/services/config_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
require "yaml"
require "fileutils"
require "grade_runner/utils/path_utils"

module GradeRunner
module Services
class ConfigService
def initialize
@path_utils = GradeRunner::Utils::PathUtils
end

def find_or_create_directory(directory_name)
@path_utils.find_or_create_directory(directory_name)
end

def update_config_file(config_file_name, config)
File.write(config_file_name, YAML.dump(config))
end

def load_config(config_file_name, default_submission_url)
if File.exist?(config_file_name)
begin
YAML.load_file(config_file_name)
rescue
abort "It looks like there's something wrong with your token in `#{config_file_name}`. Please delete that file and try `rails grade` again, and be sure to provide the access token for THIS project.".red
end
else
{ "submission_url" => default_submission_url }
end
end

def get_config_file_path(directory = ".vscode", filename = ".ltici_apitoken.yml")
config_dir = find_or_create_directory(directory)
"#{config_dir}/#{filename}"
end

def save_token_to_config(config_file_name, token, submission_url, github_username)
config = {
"submission_url" => submission_url,
"personal_access_token" => token,
"github_username" => github_username
}
update_config_file(config_file_name, config)
end

def clear_token_in_config(config_file_name)
if File.exist?(config_file_name)
config = YAML.load_file(config_file_name)
config["personal_access_token"] = nil
update_config_file(config_file_name, config)
end
end
end
end
end
Loading