Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jpignata committed Feb 28, 2016
0 parents commit 1a0f9e8
Show file tree
Hide file tree
Showing 14 changed files with 285 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.bundle
.git
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
contents/*.md
26 changes: 26 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM ruby:2.3.0-slim

ENV LANG C.UTF-8

WORKDIR /usr/src/app

COPY Gemfile /usr/src/app/
COPY Gemfile.lock /usr/src/app/

RUN apt-get update && \
apt-get install -y build-essential && \
bundle && \
apt-get remove -y build-essential

RUN adduser --uid 9000 --disabled-password --quiet --gecos "app" app
COPY . /usr/src/app
RUN chown -R app:app /usr/src/app

USER app

RUN bundle exec rake docs:scrape

VOLUME /code
WORKDIR /code

CMD ["/usr/src/app/bin/codeclimate-markdownlint"]
9 changes: 9 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
source "https://rubygems.org"

gem "mdl", "~> 0.2"
gem "posix-spawn"
gem "rake"

group :development do
gem "rspec"
end
38 changes: 38 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
GEM
remote: https://rubygems.org/
specs:
diff-lcs (1.2.5)
kramdown (1.9.0)
mdl (0.2.1)
kramdown (~> 1.5, >= 1.5.0)
mixlib-cli (~> 1.5, >= 1.5.0)
mixlib-config (~> 2.1, >= 2.1.0)
mixlib-cli (1.5.0)
mixlib-config (2.2.1)
posix-spawn (0.3.11)
rake (10.5.0)
rspec (3.4.0)
rspec-core (~> 3.4.0)
rspec-expectations (~> 3.4.0)
rspec-mocks (~> 3.4.0)
rspec-core (3.4.1)
rspec-support (~> 3.4.0)
rspec-expectations (3.4.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-mocks (3.4.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-support (3.4.1)

PLATFORMS
ruby

DEPENDENCIES
mdl (~> 0.2)
posix-spawn
rake
rspec

BUNDLED WITH
1.10.6
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.PHONY: image test

IMAGE_NAME ?= codeclimate/codeclimate-markdownlint

image:
docker build --rm -t $(IMAGE_NAME) .

test: image
docker run --rm $(IMAGE_NAME) sh -c "cd /usr/src/app && bundle exec rake"
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# codeclimate-markdownlint

Code Climate Engine to run [markdownlint][mdl]

## Installation

```
git clone https://github.com/jpignata/codeclimate-markdownlint
cd codeclimate-markdownlint
make
```

## Usage

**.codeclimate.yml**

```yml
engines:
markdownlint:
enabled: true
```
```
codeclimate analyze
```

[mdl]: https://github.com/mivok/markdownlint
47 changes: 47 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
require "open-uri"
require "mdl/version"
require "rspec/core/rake_task"

RSpec::Core::RakeTask.new(:spec)
task default: :spec

class Content
def initialize(code = nil)
@code = code
@body = ""
end

def <<(line)
body << line
end

def write
if code
IO.write(filename, body.strip)
end
end

private

attr_reader :code, :body

def filename
File.expand_path("contents/#{code}.md", File.dirname(__FILE__))
end
end

namespace :docs do
task :scrape do
rules = open("https://raw.githubusercontent.com/mivok/markdownlint/v#{MarkdownLint::VERSION}/docs/RULES.md")
content = Content.new

rules.each_line do |line|
if line.start_with?("## MD")
content.write
content = Content.new(line[/(MD\d+)/])
end

content << line
end
end
end
16 changes: 16 additions & 0 deletions bin/codeclimate-markdownlint
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env ruby

STDERR.sync = true
STDOUT.sync = true

$:.unshift(File.expand_path("../lib", File.dirname(__FILE__)))

require "cc/engine/markdownlint"

if File.exist?("/config.json")
engine_config = JSON.parse(File.read("/config.json"))
else
engine_config = {}
end

CC::Engine::Markdownlint.new("/code", engine_config, STDOUT).run
Empty file added contents/.gitkeep
Empty file.
77 changes: 77 additions & 0 deletions lib/cc/engine/markdownlint.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
require "json"
require "shellwords"
require "posix/spawn"

module CC
module Engine
class Markdownlint
def initialize(root, engine_config, io)
@root = root
@engine_config = engine_config
@io = io
@contents = {}
end

def run
pid, _, out, err = POSIX::Spawn.popen4("mdl #{include_paths}")
out.each_line do |line|
io.print JSON.dump(issue(line))
io.print "\0"
end
ensure
STDERR.print err.read
[out, err].each(&:close)

Process::waitpid(pid)
end

private

attr_reader :root, :engine_config, :io, :contents

def include_paths
return root unless engine_config.has_key?("include_paths")

markdown_files = engine_config["include_paths"].select do |path|
path.end_with?(".md")
end

Shellwords.join(markdown_files)
end

def issue(line)
match_data = line.match(/(?<filename>[^:]*):(?<line>\d+): (?<code>MD\d+) (?<description>.*)/)
line = match_data[:line].to_i
filename = match_data[:filename].sub(root + "/", "")
content = content(match_data[:code])

{
categories: ["Style"],
check_name: match_data[:code],
content: {
body: content,
},
description: match_data[:description],
location: {
begin: line,
end: line,
path: filename,
},
type: "issue",
remediation_points: 50_000,
severity: "info",
}
end

def content(code)
contents.fetch(code) do
filename = "../../../contents/#{code}.md"
path = File.expand_path(filename, File.dirname(__FILE__))
content = File.read(path)

contents[code] = content
end
end
end
end
end
29 changes: 29 additions & 0 deletions spec/cc/engine/markdownlint_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require "spec_helper"
require "json"
require "cc/engine/markdownlint"

module CC
module Engine
describe Markdownlint do
describe "#run" do
it "returns issues for markdownlint output" do
io = StringIO.new
path = File.expand_path("../../fixtures", File.dirname(__FILE__))
CC::Engine::Markdownlint.new(path, {}, io).run
issues = io.string.split("\0")
issue = JSON.parse(issues.first)

expect(issue["type"]).to eq("issue")
expect(issue["categories"]).to eq(["Style"])
expect(issue["remediation_points"]).to eq(50_000)
expect(issue["description"]).to eq("Header levels should only increment by one level at a time")
expect(issue["check_name"]).to eq("MD001")
expect(issue["content"]["body"]).to include("This rule is triggered when you skip header levels in a markdown document")
expect(issue["location"]["path"]).to eq("FIXTURE.md")
expect(issue["location"]["begin"]).to eq(3)
expect(issue["location"]["end"]).to eq(3)
end
end
end
end
end
3 changes: 3 additions & 0 deletions spec/fixtures/FIXTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Header

### Subheader
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require "rspec"

0 comments on commit 1a0f9e8

Please sign in to comment.