Skip to content

Commit

Permalink
created is-cool-me/json-syntax-check
Browse files Browse the repository at this point in the history
  • Loading branch information
LightHostingFree committed Jan 8, 2024
0 parents commit b6a4d9c
Show file tree
Hide file tree
Showing 18 changed files with 352 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
root = true

[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.yml]
indent_style = space
indent_size = 2

[Makefile]
indent_style = tab
3 changes: 3 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These are supported funding model platforms

github: [limitusus]
17 changes: 17 additions & 0 deletions .github/workflows/ngtest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: JSON check (demo failure-case)

on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: json-syntax-check
uses: ./
with:
pattern: "\\.json"
continue-on-error: true
- name: This test should fail
if: ${{ failure() }}
run: exit 0
13 changes: 13 additions & 0 deletions .github/workflows/oktest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: JSON check (demo)

on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: json-syntax-check
uses: ./
with:
pattern: "ok_[0-9]+\\.json$"
25 changes: 25 additions & 0 deletions .github/workflows/rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: RuboCop
on: [push, pull_request]

jobs:
rubocop:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2
- run: |
gem install bundler
bundle config set --local with 'development'
bundle install
- name: Setup reviewdog
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true'
run: |
mkdir -p $HOME/bin && curl -sfL https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh | sh -s -- -b $HOME/bin
echo ::add-path::$HOME/bin
- name: Run rubocop with reviewdog
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: bundle exec rubocop | reviewdog -reporter=github-pr-review -f=rubocop
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# bundler
.bundle/
vendor/

# rbenv
.ruby-version

# Local test output
test_output
8 changes: 8 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
AllCops:
NewCops: enable

Metrics/MethodLength:
Max: 20

Metrics/AbcSize:
Max: 30
16 changes: 16 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM ruby:3
LABEL maintainer "light <[email protected]>"

ENV DEBUG=0

RUN mkdir -p /data
RUN bundle config --global frozen 1
WORKDIR /usr/src/app

COPY Gemfile Gemfile.lock ./
RUN bundle config set --local without 'development'
RUN bundle install

COPY . .

ENTRYPOINT [ "/usr/src/app/json_syntax_check" ]
7 changes: 7 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

source 'https://rubygems.org'

git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }

gem 'rubocop', '~> 1.4', group: :development
34 changes: 34 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
GEM
remote: https://rubygems.org/
specs:
ast (2.4.2)
json (2.6.3)
parallel (1.23.0)
parser (3.2.2.1)
ast (~> 2.4.1)
rainbow (3.1.1)
regexp_parser (2.8.0)
rexml (3.2.5)
rubocop (1.51.0)
json (~> 2.3)
parallel (~> 1.10)
parser (>= 3.2.0.0)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.28.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.28.1)
parser (>= 3.2.1.0)
ruby-progressbar (1.13.0)
unicode-display_width (2.4.2)

PLATFORMS
ruby

DEPENDENCIES
rubocop (~> 1.4)

BUNDLED WITH
2.4.10
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 light

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
container_name := json-syntax-check

.PHONY: build clean
ALL: build

build:
docker build -t $(container_name):latest .

clean:
docker rmi $(container_name):latest
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# json-syntax-check

Simple JSON syntax checker

![OK case test passing](https://github.com/is-cool-me/json-syntax-check/actions/workflows/oktest.yml/badge.svg)
![NG case test passing](https://github.com/is-cool-me/json-syntax-check/actions/workflows/ngtest.yml/badge.svg)
![rubocop passing](https://github.com/is-cool-me/json-syntax-check/actions/workflows/rubocop.yml/badge.svg)

![Ruby 3](https://img.shields.io/badge/Ruby-3-yellow)

## Inputs

### `pattern`

**Required** file pattern to check syntax. Default is `'\\.json$'`.

## Environment variables

### `BASE`

*Optional* base directory in which to look for files matching `pattern`.

If `BASE` is not set, json-syntax-check will look in `GITHUB_WORKSPACE`.

## Outputs

### `failed_files`

File names whose syntax check failed in JSON list format.

## Example

Your `.github/workflows/jsoncheck.yml` may look like:

```yaml
name: JSON check

on:
push:
paths:
- '**.json'
pull_request:

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: json-syntax-check
uses: is-cool-me/json-syntax-check@v1
with:
pattern: "\\.json$"
```
19 changes: 19 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: 'json-syntax-check ICME'
description: 'Simply check JSON syntax'
author: 'light <[email protected]>'
inputs:
pattern:
description: 'File regex pattern to check syntax'
required: true
default: '\\.json$'
outputs:
failed_files:
description: 'File paths whose syntax check failed'
runs:
using: 'docker'
image: 'Dockerfile'
args:
- ${{ inputs.pattern }}
branding:
icon: bell
color: green
14 changes: 14 additions & 0 deletions docs/TESTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# TESTING

## Local debug

```console
DEBUG=1 GITHUB_WORKSPACE=. BASE=test/ ./json_syntax_check '\.json$'
DEBUG=1 GITHUB_WORKSPACE=. BASE=test/ ./json_syntax_check 'ok_[0-9]+\.json$'
```

## Docker test

```console
docker run --rm -it -v $(pwd)/test/:/data/ json-syntax-check:latest '\.json$'
```
81 changes: 81 additions & 0 deletions json_syntax_check
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

require 'find'
require 'json'

# JSON checker calling module
module JSONChecker
def self.run(argv)
patterns = argv
checker = Checker.new(patterns)
failures = checker.run
File.open(ENV.fetch('GITHUB_OUTPUT', './test_output'), 'a') do |f|
f.puts "failed_files=#{JSON.dump(failures.map(&:file))}"
end
if failures.empty?
puts "No file has JSON syntax error (of #{checker.files.length} files)"
else
puts "Files below has/have JSON syntax error (of #{checker.files.length} files)"
failures.each do |f|
puts "- #{f.file}: #{f.hint}"
end
end
failures.length
end
end

# Syntax failure
class Failure
attr_reader :file, :hint

def initialize(file, hint)
@file = file
@hint = hint
end
end

# JSON checker class
class Checker
def initialize(patterns)
@patterns = patterns.map { |pat| Regexp.compile(pat) }
@files = nil
@base = ENV.fetch('BASE', ENV.fetch('GITHUB_WORKSPACE'))
@debug = ENV.fetch('DEBUG', '0') != '0'
end

def files
return @files unless @files.nil?

@files = []
Find.find(@base) do |file|
next unless File.file?(file)

next unless @patterns.any? { |pat| pat.match?(file) }

@files << file
end
puts "base=#{@base} ptns=#{@patterns} files=#{@files}" if @debug

@files
end

def run
failures = files.map { |f| validate_json(f) }
failures.compact
end

def validate_json(file)
JSON.parse(File.read(file))
rescue JSON::ParserError => e
hint = e.message.lines.first.chomp unless e.message.lines.nil?
hint += "' ..." if e.message.lines.length > 1

hint ||= 'Unknown JSON parse error'
Failure.new(file, hint)
else
nil
end
end

exit JSONChecker.run(ARGV)
4 changes: 4 additions & 0 deletions test/ng_1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"foo": "alice",
"bar": "bob",
}
4 changes: 4 additions & 0 deletions test/ok_1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"foo": "alice",
"bar": "bob"
}

0 comments on commit b6a4d9c

Please sign in to comment.