Merge branch 'master' into no-hardlinks

This commit is contained in:
t-mangoe 2022-03-26 16:25:05 +09:00
commit 67459d0ef9
17 changed files with 138 additions and 278 deletions

View file

@ -9,20 +9,25 @@ name: Ruby
on:
push:
branches: [ master ]
branches: [ main ]
pull_request:
branches: [ master ]
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
matrix:
ruby-version: ['2.6', '2.7', '3.0']
ruby-version: ['2.6', '2.7', '3.0', '3.1']
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v2
- name: Shellcheck
if: matrix.os == 'ubuntu-latest'
run: shellcheck test/run test/checks
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
@ -32,3 +37,26 @@ jobs:
run: bundle exec rake
- name: Run checks
run: test/run
publish:
needs: test
runs-on: ubuntu-latest
if: success() && github.event_name == 'push'
steps:
- uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.1'
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
- name: Publish to RubyGems
run: |
mkdir -p $HOME/.gem
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
chmod 0600 $HOME/.gem/credentials
bundle exec rake publish
env:
GEM_HOST_API_KEY: "${{ secrets.RUBYGEMS_API_KEY }}"

View file

@ -10,7 +10,7 @@ AllCops:
- 'profile/*'
DisplayCopNames: true
NewCops: enable
TargetRubyVersion: 2.5
TargetRubyVersion: 2.6
# Preferred codebase style ---------------------------------------------
@ -58,7 +58,7 @@ Metrics/ClassLength:
Max: 350
Metrics/ParameterLists:
Max: 15
Max: 16
Naming/FileName:
Enabled: false

View file

@ -117,7 +117,7 @@ Man pages have been added. Checkout `man colorls`.
[(Back to top)](#table-of-contents)
1. Install Ruby (preferably, version >= 2.5)
1. Install Ruby (preferably, version >= 2.6)
2. [Download](https://www.nerdfonts.com/font-downloads) and install a Nerd Font. Have a look at the [Nerd Font README](https://github.com/ryanoasis/nerd-fonts/blob/master/readme.md) for installation instructions.
*Note for `iTerm2` users - Please enable the Nerd Font at iTerm2 > Preferences > Profiles > Text > Non-ASCII font > Hack Regular Nerd Font Complete.*

View file

@ -20,7 +20,7 @@ file 'man/colorls.1' => ['man/colorls.1.ronn', 'lib/colorls/flags.rb'] do
flags = ColorLS::Flags.new
attributes = {
date: Date.iso8601(`git log -1 --pretty=format:%cI -- man/colorls.1`),
date: Date.iso8601(`git log -1 --pretty=format:%cI -- lib/colorls/flags.rb`),
manual: 'colorls Manual',
organization: "colorls #{ColorLS::VERSION}"
}
@ -40,9 +40,11 @@ OPTION
File.write('man/colorls.1', doc.convert('roff'))
end
directory 'zsh'
desc 'Build the Zsh completion file'
file 'zsh/_colorls' => ['lib/colorls/flags.rb'] do
file 'zsh/_colorls' => %w[zsh lib/colorls/flags.rb] do
ruby "exe/colorls '--*-completion-zsh=colorls' > zsh/_colorls"
end
task default: %w[spec rubocop]
task default: %w[spec rubocop man/colorls.1 zsh/_colorls]

View file

@ -27,13 +27,13 @@ POST_INSTALL_MESSAGE = %(
# rubocop:disable Metrics/BlockLength
Gem::Specification.new do |spec|
is_tagged = ENV['TRAVIS_TAG'] == "v#{ColorLS::VERSION}"
is_origin = ENV['TRAVIS_REPO_SLUG'] == 'athityakumar/colorls'
build_number = ENV['TRAVIS_BUILD_NUMBER']
is_tagged = ENV['GITHUB_REF'] == "refs/tags/v#{ColorLS::VERSION}"
is_origin = ENV['GITHUB_REPOSITORY_OWNER'] == 'athityakumar'
build_number = ENV['GITHUB_RUN_NUMBER']
spec.name = 'colorls'
spec.version = if build_number && is_origin && !is_tagged
# Prereleasing on Travis CI
# Prereleasing on Github
digits = ColorLS::VERSION.to_s.split '.'
digits[-1] = digits[-1].to_s.succ
@ -47,12 +47,12 @@ Gem::Specification.new do |spec|
spec.homepage = 'https://github.com/athityakumar/colorls'
spec.license = 'MIT'
spec.required_ruby_version = '>= 2.5.0'
spec.required_ruby_version = '>= 2.6.0'
spec.files = IO.popen(
spec.files = %w[man/colorls.1 man/colorls.1 zsh/_colorls] + IO.popen(
%w[git ls-files -z], external_encoding: Encoding::ASCII_8BIT
).read.split("\x0").reject do |f|
f.match(%r{^(test|spec|features)/})
f.match(%r{^(test|spec|features|[.]github)/})
end
spec.bindir = 'exe'
@ -79,7 +79,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'rubocop', '~> 1.22.0'
spec.add_development_dependency 'rubocop-performance', '~> 1.13.0'
spec.add_development_dependency 'rubocop-rake', '~> 0.5'
spec.add_development_dependency 'rubocop-rspec', '~> 2.0'
spec.add_development_dependency 'rubocop-rspec', '~> 2.9.0'
spec.add_development_dependency 'rubygems-tasks', '~> 0'
spec.add_development_dependency 'simplecov', '~> 0.21.2'
end

View file

@ -26,8 +26,8 @@ module ColorLS
class Core
def initialize(all: false, sort: false, show: false,
mode: nil, git_status: false, almost_all: false, colors: [], group: nil,
reverse: false, hyperlink: false, tree_depth: nil,
mode: nil, show_git: false, almost_all: false, colors: [], group: nil,
reverse: false, hyperlink: false, tree_depth: nil, show_inode: false,
indicator_style: 'slash', long_style_options: {})
@count = {folders: 0, recognized_files: 0, unrecognized_files: 0}
@all = all
@ -38,13 +38,17 @@ module ColorLS
@group = group
@show = show
@one_per_line = mode == :one_per_line
@show_inode = show_inode
init_long_format(mode,long_style_options)
@tree = {mode: mode == :tree, depth: tree_depth}
@horizontal = mode == :horizontal
@git_status = init_git_status(git_status)
@show_git = show_git
@git_status = init_git_status(show_git)
@time_style = long_style_options.key?(:time_style) ? long_style_options[:time_style] : ''
@indicator_style = indicator_style
@hard_links_count = long_style_options.key?(:hard_links_count) ? long_style_options[:hard_links_count] : true
# how much characters an item occupies besides its name
@additional_chars_per_item = 12 + (@show_git ? 4 : 0) + (@show_inode ? 10 : 0)
init_colors colors
@ -78,16 +82,24 @@ module ColorLS
ls
end
def display_report
puts <<~REPORT
def display_report(report_mode)
if report_mode == :short
puts <<~REPORT
Found #{@count.values.sum} items in total.
\s\s\s\sFolders: #{@count[:folders]}, Files: #{@count[:recognized_files] + @count[:unrecognized_files]}.
REPORT
.colorize(@colors[:report])
else
puts <<~REPORT
\tFolders\t\t\t: #{@count[:folders]}
\tRecognized files\t: #{@count[:recognized_files]}
\tUnrecognized files\t: #{@count[:unrecognized_files]}
REPORT
.colorize(@colors[:report])
Found #{@count.values.sum} items in total.
\tFolders\t\t\t: #{@count[:folders]}
\tRecognized files\t: #{@count[:recognized_files]}
\tUnrecognized files\t: #{@count[:unrecognized_files]}
REPORT
.colorize(@colors[:report])
end
end
private
@ -142,11 +154,8 @@ module ColorLS
end
end
# how much characters an item occupies besides its name
CHARS_PER_ITEM = 12
def item_widths
@contents.map { |item| Unicode::DisplayWidth.of(item.show) + CHARS_PER_ITEM }
@contents.map { |item| Unicode::DisplayWidth.of(item.show) + @additional_chars_per_item }
end
def filter_hidden_contents
@ -291,6 +300,12 @@ module ColorLS
end
end
def inode(content)
return '' unless @show_inode
content.stats.ino.to_s.rjust(10).colorize(@colors[:inode])
end
def long_info(content)
return '' unless @long
@ -323,14 +338,14 @@ module ColorLS
def fetch_string(content, key, color, increment)
@count[increment] += 1
value = increment == :folders ? @folders[key] : @files[key]
logo = value.gsub(/\\u[\da-f]{4}/i) { |m| [m[-4..-1].to_i(16)].pack('U') }
logo = value.gsub(/\\u[\da-f]{4}/i) { |m| [m[-4..].to_i(16)].pack('U') }
name = content.show
name = make_link(content) if @hyperlink
name += content.directory? && @indicator_style != 'none' ? '/' : ' '
entry = "#{out_encode(logo)} #{out_encode(name)}"
entry = entry.bright if !content.directory? && content.executable?
"#{long_info(content)} #{git_info(content)} #{entry.colorize(color)}#{symlink_info(content)}"
"#{inode(content)} #{long_info(content)} #{git_info(content)} #{entry.colorize(color)}#{symlink_info(content)}"
end
def ls_line(chunk, widths)
@ -340,7 +355,7 @@ module ColorLS
entry = fetch_string(content, *options(content))
line << (' ' * padding)
line << ' ' << entry.encode(Encoding.default_external, undef: :replace)
padding = widths[i] - Unicode::DisplayWidth.of(content.show) - CHARS_PER_ITEM
padding = widths[i] - Unicode::DisplayWidth.of(content.show) - @additional_chars_per_item
end
print line << "\n"
end

View file

@ -11,7 +11,7 @@ module ColorLS
@light_colors = false
@opts = default_opts
@show_report = false
@report_mode = false
@exit_status_code = 0
parse_options
@ -88,7 +88,7 @@ module ColorLS
$stderr.puts "#{dir}: #{e}".colorize(:red)
end
core.display_report if @show_report
core.display_report(@report_mode) if @report_mode
@exit_status_code
end
@ -102,9 +102,10 @@ module ColorLS
mode: STDOUT.tty? ? :vertical : :one_per_line, # rubocop:disable Style/GlobalStdStream
all: false,
almost_all: false,
git_status: false,
show_git: false,
colors: [],
tree_depth: 3,
show_inode: false,
indicator_style: 'slash',
long_style_options: {}
}
@ -139,9 +140,13 @@ module ColorLS
options.on('-A', '--almost-all', 'do not list . and ..') { @opts[:almost_all] = true }
options.on('-d', '--dirs', 'show only directories') { @opts[:show] = :dirs }
options.on('-f', '--files', 'show only files') { @opts[:show] = :files }
options.on('--gs', '--git-status', 'show git status for each file') { @opts[:git_status] = true }
options.on('--report', 'show brief report') { @show_report = true }
options.on('--gs', '--git-status', 'show git status for each file') { @opts[:show_git] = true }
options.on('-p', 'append / indicator to directories') { @opts[:indicator_style] = 'slash' }
options.on('-i', '--inode', 'show inode number') { @opts[:show_inode] = true }
options.on('--report=[WORD]', %w[short long], 'show report: short, long (default if omitted)') do |word|
word ||= :long
@report_mode = word.to_sym
end
options.on(
'--indicator-style=[STYLE]',
%w[none slash], 'append indicator with style STYLE to entry names: none, slash (-p) (default)'

View file

@ -5,6 +5,9 @@ require 'set'
module ColorLS
module Git
EMPTY_SET = Set.new.freeze
private_constant :EMPTY_SET
def self.status(repo_path)
prefix, success = git_prefix(repo_path)
@ -13,10 +16,11 @@ module ColorLS
prefix_path = Pathname.new(prefix)
git_status = Hash.new { |hash, key| hash[key] = Set.new }
git_status_default = EMPTY_SET
git_subdir_status(repo_path) do |mode, file|
if file == prefix
git_status.default = Set[mode].freeze
git_status_default = Set[mode].freeze
else
path = Pathname.new(file).relative_path_from(prefix_path)
git_status[path.descend.first.cleanpath.to_s].add(mode)
@ -25,7 +29,7 @@ module ColorLS
warn "git status failed in #{repo_path}" unless $CHILD_STATUS.success?
git_status.default = Set.new.freeze if git_status.default.nil?
git_status.default = git_status_default
git_status.freeze
end

View file

@ -36,6 +36,7 @@ tree: cyan
empty: yellow
error: red
normal: darkkhaki
inode: moccasin
# Git
addition: chartreuse

View file

@ -36,6 +36,7 @@ tree: cyan
empty: yellow
error: red
normal: black
inode: black
# Git
addition: chartreuse

View file

@ -1,175 +0,0 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "COLORLS" "1" "January 2021" "colorls 1.4.4" "colorls Manual"
.
.SH "NAME"
\fBcolorls\fR \- list directory contents with colors and icons
.
.SH "SYNOPSIS"
\fBcolorls\fR [OPTION]\.\.\. [FILE]\.\.\.
.
.br
.
.SH "DESCRIPTION"
List information about the given FILEs\. Uses different colors and icons for known file types\.
.
.P
By default, the output is sorted alphabetically\.
.
.P
Mandatory arguments to long options are mandatory for short options too\.
.
.SH "OPTIONS"
.
.TP
\fB\-a\fR, \fB\-\-all\fR
do not ignore entries starting with \.
.
.TP
\fB\-A\fR, \fB\-\-almost\-all\fR
do not list \. and \.\.
.
.TP
\fB\-d\fR, \fB\-\-dirs\fR
show only directories
.
.TP
\fB\-f\fR, \fB\-\-files\fR
show only files
.
.TP
\fB\-\-gs\fR, \fB\-\-git\-status\fR
show git status for each file
.
.TP
\fB\-\-report\fR
show brief report
.
.TP
\fB\-\-format\fR
use format: across (\-x), horizontal (\-x), long (\-l), single\-column (\-1), vertical (\-C)
.
.TP
\fB\-1\fR
list one file per line
.
.TP
\fB\-\-tree\fR
shows tree view of the directory
.
.TP
\fB\-x\fR
list entries by lines instead of by columns
.
.TP
\fB\-C\fR
list entries by columns instead of by lines
.
.TP
\fB\-l\fR, \fB\-\-long\fR
use a long listing format
.
.TP
\fB\-o\fR
use a long listing format without group information
.
.TP
\fB\-g\fR
use a long listing format without owner information
.
.TP
\fB\-G\fR, \fB\-\-no\-group\fR
show no group information in a long listing
.
.TP
\fB\-\-sd\fR, \fB\-\-sort\-dirs\fR, \fB\-\-group\-directories\-first\fR
sort directories first
.
.TP
\fB\-\-sf\fR, \fB\-\-sort\-files\fR
sort files first
.
.TP
\fB\-t\fR
sort by modification time, newest first
.
.TP
\fB\-U\fR
do not sort; list entries in directory order
.
.TP
\fB\-S\fR
sort by file size, largest first
.
.TP
\fB\-X\fR
sort by file extension
.
.TP
\fB\-\-sort\fR
sort by WORD instead of name: none, size (\-S), time (\-t), extension (\-X)
.
.TP
\fB\-r\fR, \fB\-\-reverse\fR
reverse order while sorting
.
.TP
\fB\-h\fR, \fB\-\-human\-readable\fR:
.
.TP
\fB\-\-color\fR
colorize the output: auto, always (default if omitted), never
.
.TP
\fB\-\-light\fR
use light color scheme
.
.TP
\fB\-\-dark\fR
use dark color scheme
.
.TP
\fB\-\-hyperlink\fR:
.
.TP
\fB\-\-help\fR
prints this help
.
.TP
\fB\-\-version\fR
show version
.
.SH "EXAMPLES"
.
.TP
show the given file:
.
.IP
\fBcolorls README\.md\fR
.
.TP
show matching files and list matching directories:
.
.IP
\fBcolorls *\fR
.
.TP
filter output by a regular expression:
.
.IP
\fBcolorls | grep PATTERN\fR
.
.TP
several short options can be combined:
.
.IP
\fBcolorls \-d \-l \-a\fR
.
.br
\fBcolorls \-dla\fR
.
.SH "AUTHOR"
Written by Athitya Kumar\.

View file

@ -20,9 +20,12 @@ RSpec.describe ColorLS::Flags do
end.not_to output(/((r|-).*(w|-).*(x|-).*){3}/).to_stdout
}
it('does not display hidden files') { expect { subject }.not_to output(/\.hidden-file/).to_stdout }
it('does not show a report') { expect { subject }.not_to output(/Found \d+ contents/).to_stdout }
it('displays dirs & files alphabetically') { expect { subject }.to output(/a-file.+symlinks.+z-file/m).to_stdout }
it('does not display hidden files') { expect { subject }.not_to output(/\.hidden-file/).to_stdout }
it('displays dirs & files alphabetically') { expect { subject }.to output(/a-file.+symlinks.+z-file/m).to_stdout }
it 'does not show a report' do
expect { subject }.not_to output(/(Found \d+ items in total\.)|(Folders: \d+, Files: \d+\.)/).to_stdout
end
it 'displays multiple files per line' do
allow($stdout).to receive(:tty?).and_return(true)
@ -352,11 +355,27 @@ RSpec.describe ColorLS::Flags do
end
end
context 'with unrecognized files' do
let(:args) { ['--report', FIXTURES] }
context 'with --report flag' do
let(:args) { ['--report', '--report=long', FIXTURES] }
it 'shows a report with unrecognized files' do
expect { subject }.to output(/Unrecognized files\s+: 3/).to_stdout
it 'shows a report with recognized and unrecognized files' do
expect { subject }.to output(/Recognized files\s+: 3\n.+Unrecognized files\s+: 3/).to_stdout
end
end
context 'with --report=short flag' do
let(:args) { ['--report=short', FIXTURES] }
it 'shows a brief report' do
expect { subject }.to output(/Folders: \d+, Files: \d+\./).to_stdout
end
end
context 'with --inode flag' do
let(:args) { ['--inode', FIXTURES] }
it 'shows inode number' do
expect { subject }.to output(/\d{7,}/).to_stdout
end
end

View file

@ -17,7 +17,7 @@ RSpec.describe ColorLS::Yaml do
let(:checker) { YamlSortChecker.new("#{base_directory}/#{filename}.yaml") }
it 'is sorted correctly' do
expect(checker.sorted?(sort_type)).to eq true
expect(checker.sorted?(sort_type)).to be true
end
end
end

View file

@ -4,6 +4,6 @@ require 'spec_helper'
RSpec.describe ColorLS do
it 'has a version number' do
expect(ColorLS::VERSION).not_to be nil
expect(ColorLS::VERSION).not_to be_nil
end
end

View file

@ -34,6 +34,10 @@ OK colorls --color=never
OK colorls --color=always
OK colorls --tree spec
OK colorls --tree=1
OK colorls --report
OK colorls --report=long
OK colorls --report=short
OK colorls --inode
LC_ALL=C OK colorls spec/fixtures/
LC_ALL=C OK colorls --git spec/fixtures/

View file

@ -1,6 +1,10 @@
#! /usr/bin/env bash
set -eEuCo pipefail
set -EuCo pipefail
if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
set -e
fi
declare RED=$'\033[31m'
declare GREEN=$'\033[32m'
@ -53,7 +57,7 @@ function XFAIL() {
echo "$RED" "FAIL$RESET - $* (unexpected success, ${BASH_SOURCE[1]}:${BASH_LINENO[0]})" >&2
else
ret=$?
if [[ -v expected && $expected -ne $ret ]]; then
if [[ -n "$expected" && $expected -ne $ret ]]; then
((++ERRORS))
echo "$RED" "FAIL$RESET - $* (expected: $expected got $ret, ${BASH_SOURCE[1]}:${BASH_LINENO[0]})" >&2
@ -99,4 +103,5 @@ function summary() {
trap summary EXIT
# shellcheck source=test/checks
source "$(dirname "${BASH_SOURCE[0]}")/checks"

View file

@ -1,49 +0,0 @@
#compdef colorls
typeset -A opt_args
local context state line
_arguments -s -S \
"-a[do not ignore entries starting with .]" \
"--all[do not ignore entries starting with .]" \
"-A[do not list . and ..]" \
"--almost-all[do not list . and ..]" \
"-d[show only directories]" \
"--dirs[show only directories]" \
"-f[show only files]" \
"--files[show only files]" \
"--gs[show git status for each file]" \
"--git-status[show git status for each file]" \
"--report[show brief report]" \
"--format[use format: across (-x), horizontal (-x), long (-l), single-column (-1), vertical (-C)]" \
"-1[list one file per line]" \
"--tree[shows tree view of the directory]" \
"-x[list entries by lines instead of by columns]" \
"-C[list entries by columns instead of by lines]" \
"-l[use a long listing format]" \
"--long[use a long listing format]" \
"-o[use a long listing format without group information]" \
"-g[use a long listing format without owner information]" \
"-G[show no group information in a long listing]" \
"--no-group[show no group information in a long listing]" \
"--sd[sort directories first]" \
"--sort-dirs[sort directories first]" \
"--group-directories-first[sort directories first]" \
"--sf[sort files first]" \
"--sort-files[sort files first]" \
"-t[sort by modification time, newest first]" \
"-U[do not sort; list entries in directory order]" \
"-S[sort by file size, largest first]" \
"-X[sort by file extension]" \
"--sort[sort by WORD instead of name: none, size (-S), time (-t), extension (-X)]" \
"-r[reverse order while sorting]" \
"--reverse[reverse order while sorting]" \
"-h[]" \
"--human-readable[]" \
"--color[colorize the output: auto, always (default if omitted), never]" \
"--light[use light color scheme]" \
"--dark[use dark color scheme]" \
"--hyperlink[]" \
"--help[prints this help]" \
"--version[show version]" \
'*:file:_files' && return 0