Skip to content
Merged
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
20 changes: 20 additions & 0 deletions .github/typocop/setting.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Configuration for Typocop - a GitHub Action for checking typos in pull requests

# 'excludes' section allows you to specify files and folders to exclude
# from the typo-checking process. You can list specific files or use glob
# patterns to exclude entire directories.

excludes: # Folders and files to exclude from typo checks
# Example: Exclude a specific file (e.g., 'exclude.rb' in the 'excludes' folder)
- excludes/exclude.rb
# Example: Exclude all files in the 'test' folder inside the 'excludes' directory
- excludes/test/*

# 'skips' section defines a list of words, file names, or patterns
# for which Typocop will skip checking for typos. This is useful for common
# terms or abbreviations you don't want to be flagged as typos.

skips: # Words or patterns to skip typo-checking
- rspec
# Example: Skip checking for the word 'elligible' (common in testing setups)
- elligible
1 change: 1 addition & 0 deletions .github/workflows/typocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }}
pull_request_id: ${{ github.event.pull_request.number }}
github_base_ref: ${{ github.base_ref }}
setting: .github/typocop/setting.yml
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,29 @@ This GitHub Action automatically checks for typos in the files changed in a pull
github_token: ${{ secrets.GITHUB_TOKEN }}
pull_request_id: ${{ github.event.pull_request.number }}
github_base_ref: ${{ github.base_ref }}
setting: .github/typocop/setting.yml # Optional: Path to your custom settings file
```

2. Create a new Pull Request (PR) to trigger the action.
2. Customize settings (optional):

By default, Typocop uses predefined settings, but you can create a custom settings file in your repository. For example, create .github/typocop/setting.yml to specify exclusion rules and skip lists.

Example `.github/typocop/setting.yml`:

```yaml
excludes: # Files and directories to exclude
- excludes/exclude.rb
- excludes/test/*

skips: # Words or patterns to skip during typo detection
- rspec
- eligible
```

- **excludes**: Specifies files or directories to exclude from typo checking.
- **skips**: Specifies words or patterns to skip checking (useful for technical terms or domain-specific language).

3. Create a new Pull Request (PR) to trigger the action.
2. **Using Typocop command line**

```bash
Expand All @@ -71,7 +91,7 @@ We welcome contributions to this project! To contribute:
- Hoang Duc Quan ([BlazingRockStorm](https://github.com/BlazingRockStorm))

## References
- [Crate CI - Typos](https://github.com/crate-ci/typos)
- [Typo Checker](https://github.com/datpmt/typo_checker)
- [Pronto Labs](https://github.com/prontolabs/pronto)

## License
Expand Down
17 changes: 5 additions & 12 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,14 @@ inputs:
github_base_ref:
description: 'GitHub Base Ref'
required: true
setting:
description: 'Path to the custom setting.yml file for Typocop'
required: false
default: '.github/typocop/setting.yml

runs:
using: 'composite'
steps:
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.14.0-alpha.1'

- name: Install typos
run: |
python3 -m pip install --upgrade pip
pip install typos
shell: bash

- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
Expand All @@ -43,7 +36,7 @@ runs:

- name: Run Typocop
run: |
typocop execute
typocop execute --config ${{ inputs.setting }}
env:
GITHUB_TOKEN: ${{ inputs.github_token }}
PULL_REQUEST_ID: ${{ inputs.pull_request_id }}
Expand Down
9 changes: 9 additions & 0 deletions excludes/exclude.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
def greeting(name)
puts "Hello, #{name}! Welocome to the Ruby typos test."
puts 'languege' # typo
puts 'knowlege' # typo
puts 'knowlege: languege' # typo
puts 'welcom'
end

greeting('Alice')
9 changes: 9 additions & 0 deletions excludes/include.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
def greeting(name)
puts "Hello, #{name}! Welocome to the Ruby typos test."
puts 'languege' # typo
puts 'knowlege' # typo
puts 'knowlege: languege' # typo
puts 'welcom'
end

greeting('Alice')
3 changes: 3 additions & 0 deletions excludes/test/exclude.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
var languege = 'en' // typo
console.log(languege) // typo
console.log('welcom') // typo
26 changes: 26 additions & 0 deletions excludes/test/exclude.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
def greet(name):
print(f"Hello, {name}! Welcome to Python programming.")

def factorial(n):
if n == 0 or n == 1:
return 1
else:
result = 1
for i in range(2, n + 1):
result *= i
return result

numbers = [5, 3, 8, 10]

for number in numbers:
print(f"Factorial of {number} is: {factorial(number)}")

user_name = input("Enter your name: ")

greet(user_name)

age = int(input("Enter your age: "))
if age >= 18:
print("You are elligible for an adult privilege.") # typo
else:
print("You are underage, so no adult privileges for you.")
47 changes: 11 additions & 36 deletions lib/typocop.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,52 +9,27 @@
require 'typocop/cops'
require 'typocop/patch'
require 'typocop/repo'
require 'typo_checker'

GITHUB_TOKEN = ENV['GITHUB_TOKEN'] || ''
PULL_ID = ENV['PULL_REQUEST_ID']
GITHUB_BASE_REF = ENV['GITHUB_BASE_REF'] || 'main'
BASE_BRANCH = GITHUB_BASE_REF.start_with?('origin/') ? GITHUB_BASE_REF : "origin/#{GITHUB_BASE_REF}"

module Typocop
def self.execute
typo_outputs = `typos --format brief`
typo_outputs = typo_outputs.split("\n")

if typo_outputs.empty?
puts 'No typo output.'
def self.execute(settings)
excludes = settings.excludes
skips = settings.skips
typo_checker = TypoChecker::Checker.new(excludes, skips, stdoutput = false)
found_typos = typo_checker.scan_repo('.')

if found_typos.empty?
puts 'No typos.'
else
result = typo_outputs.each_with_object({}) do |output, hash|
path, line, _column, typo_detail = output.split(':')
typo_match = /`(.*?)` -> `(.*?)`/.match(typo_detail)
incorrect_word, correct_word = typo_match ? typo_match.captures : []

path = path.start_with?('./') ? path[2..] : path
line = line.to_i

hash[path] ||= {}

hash[path][:typos] ||= []

existing_entry = hash[path][:typos].find { |typo| typo[:line] == line }

if existing_entry
existing_entry[:typos] << { incorrect_word: incorrect_word, correct_word: correct_word }
else
hash[path][:typos] << { line: line, typos: [{ incorrect_word: incorrect_word, correct_word: correct_word }] }
end
end

result = result.map do |path, data|
data[:typos].map do |entry|
{ path: path, line: entry[:line], typos: entry[:typos] }
end
end.flatten

cops = Cops.new(result)
cops_data = cops.cops
cops = Cops.new(found_typos)
repo = Repo.new
client = Client.new(repo)
client.execute(cops_data)
client.execute(cops.cops)
end
end
end
6 changes: 5 additions & 1 deletion lib/typocop/cli.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
require 'thor'
require_relative 'settings'

module Typocop
class CLI < Thor
require 'typocop'
method_option :config, type: :string, default: '.github/typocop/setting.yml', aliases: '-c', desc: 'Load setting.'

desc 'execute', 'Run typocop'
def execute
Typocop.execute
settings = Settings.new(options[:config])
Typocop.execute(settings)
end
end
end
24 changes: 24 additions & 0 deletions lib/typocop/settings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
require 'yaml'

module Typocop
class Settings
attr_reader :excludes, :skips

def initialize(setting_path)
@settings = load_settings(setting_path)
@excludes = @settings['excludes'] || []
@skips = @settings['skips'] || []
end

private

def load_settings(setting_path)
begin
YAML.load_file(setting_path)
rescue StandardError => e
puts "Error loading YAML file: #{e.message}"
return {}
end
end
end
end
5 changes: 5 additions & 0 deletions lib/typocop/version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

module Typocop
VERSION = '0.1.2'
end
7 changes: 5 additions & 2 deletions typocop.gemspec
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
require_relative 'lib/typocop/version'

Gem::Specification.new do |s|
s.name = 'typocop'
s.version = '0.1.1'
s.version = Typocop::VERSION
s.summary = 'Comment on PRs with typos or approvals'
s.description = "Typocop integrates with GitHub Actions to automatically comment on pull requests when typos are detected or when a PR is approved, based on [Crate CI's Typos](https://github.com/crate-ci/typos)."
s.description = 'Typocop integrates with GitHub Actions to automatically comment on pull requests when typos are detected or when a PR is approved).'
s.authors = ['datpmt']
s.email = 'datpmt.2k@gmail.com'
s.files = Dir['CHANGELOG.md', 'LICENSE', 'README.md', 'lib/**/*', 'bin/*']
Expand All @@ -16,6 +18,7 @@ Gem::Specification.new do |s|
s.add_dependency 'octokit', '9.2.0'
s.add_dependency 'rugged', '~> 1.6.3'
s.add_dependency 'thor', '~> 1.3.2'
s.add_dependency 'typo_checker'
s.executables = %w[typocop]
s.files.each do |file|
next unless file.start_with?('bin/')
Expand Down
Loading