Skip to content

Commit c4b32cb

Browse files
committed
update posts - 2025-05
1 parent 93570b3 commit c4b32cb

8 files changed

+1209
-354
lines changed

package-lock.json

Lines changed: 277 additions & 348 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"devDependencies": {
3-
"@qiita/qiita-cli": "^1.6.1"
3+
"@qiita/qiita-cli": "^1.6.2"
44
}
55
}

public/20241212-b9ef23b3bdf2ee6cfd39.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ tags:
77
- ChatGPT
88
- o1
99
private: false
10-
updated_at: '2024-12-12T19:16:00+09:00'
10+
updated_at: '2025-03-28T14:25:56+09:00'
1111
id: b9ef23b3bdf2ee6cfd39
1212
organization_url_name: haw
1313
slide: false
@@ -17,7 +17,7 @@ ignorePublish: false
1717
### はじめに
1818

1919
現在私は [Haw International](https://www.haw.co.jp/) でソフトウェア技術者として働いています。同社では、社員が新たな挑戦を行える環境が整っています。
20-
その一環として提供される [ChatGPT Plus](https://openai.com/chatgpt) の利用制度を活用し、日々の開発効率を高めています。
20+
その一環として提供される [AI](https://openai.com/chatgpt) の利用制度を活用し、日々の開発効率を高めています。
2121

2222
https://qiita.com/torifukukaiou/items/9ac6c7258c8a1549674a
2323

public/20250111-print-git-repo-like-uithub.md

Lines changed: 193 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ tags:
77
- ChatGPT
88
- uithub
99
private: false
10-
updated_at: '2025-01-14T09:31:00+09:00'
10+
updated_at: '2025-03-28T14:22:24+09:00'
1111
id: af13b34ac636c03d97c5
1212
organization_url_name: haw
1313
slide: false
@@ -328,6 +328,198 @@ list_git_files_with_content_excluding_type() {
328328
list_git_files_with_content_excluding_type '\.md$'
329329
```
330330

331+
## 自分がまとめたスクリプト
332+
333+
参考までに上述の調査の成果をまとめたスクリプトを作ってます。
334+
335+
```bash
336+
#!/usr/bin/env bash
337+
338+
# -----------------------------------------------------------------------------
339+
# Uithub-like Git Repository Explorer
340+
# -----------------------------------------------------------------------------
341+
# Displays a Git repository's structure and file contents in an AI-friendly format.
342+
#
343+
# Features:
344+
# - Displays Git-tracked files with line numbers
345+
# - Shows file structure (up to 2 levels deep)
346+
# - Highlights media files with GitHub raw URLs
347+
# - Ignores blank files and large files (>100KB)
348+
# - Ignores files excluded by .gitignore
349+
# - Ignores common build, cache, and temporary files
350+
# - Keeps .md and .json files (only excludes unnecessary files)
351+
# - Interactive file selection with `fzf` (optional)
352+
#
353+
# Requirements: git, tree, cat, fzf (optional)
354+
#
355+
# Usage:
356+
# ./show_repo.sh # Standard output
357+
# ./show_repo.sh --interactive # Interactive mode (requires fzf)
358+
# -----------------------------------------------------------------------------
359+
360+
set -euo pipefail
361+
362+
# Color codes for output
363+
RED='\033[1;31m'
364+
GREEN='\033[1;32m'
365+
CYAN='\033[1;36m'
366+
YELLOW='\033[1;33m'
367+
RESET='\033[0m'
368+
369+
# Configurable settings
370+
MAX_FILE_SIZE=$((100 * 1024)) # 100KB
371+
TREE_DEPTH=2 # Depth for tree display
372+
373+
# Patterns of files to exclude
374+
EXCLUDE_PATTERNS="\
375+
\.lock$|\
376+
\.o$|\.out$|\.so$|\.a$|\
377+
\.class$|\.jar$|\.war$|\.ear$|\
378+
\.pyc$|\.pyo$|__pycache__/|\
379+
\.beam$|_build/|\
380+
dist/|build/|target/|\.gradle/|\
381+
\.DS_Store$|Thumbs\.db$|\.idea/|\.vscode/|\
382+
node_modules/|bower_components/|\
383+
\.pytest_cache/|\.mypy_cache/|\.cargo/|\
384+
\.log$|\.tmp$|\.swp$"
385+
386+
# Check if inside a Git repository
387+
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
388+
echo -e "${RED}Error: This is not a Git repository.${RESET}" >&2
389+
exit 1
390+
fi
391+
392+
# Get GitHub raw content URL
393+
get_github_url() {
394+
local file="$1"
395+
local repo_url branch
396+
397+
repo_url="$(git config --get remote.origin.url | sed -E 's|[email protected]:|https://github.com/|; s|https://github.com/||; s|\.git$||')"
398+
branch="$(git rev-parse --abbrev-ref HEAD)"
399+
400+
echo "https://raw.githubusercontent.com/${repo_url}/${branch}/${file}"
401+
}
402+
403+
# Check if a file is binary
404+
is_binary() {
405+
case "$1" in
406+
*.png|*.jpg|*.jpeg|*.gif|*.bmp|*.tiff|*.ico|*.svg|*.webp|*.avif|\
407+
*.mp4|*.mkv|*.mov|*.avi|*.wmv|*.flv|*.webm|*.mpeg|*.mpg|*.m4v|*.3gp)
408+
return 0 ;;
409+
*) return 1 ;;
410+
esac
411+
}
412+
413+
# Check if a file is empty (zero bytes or only whitespace)
414+
is_blank_file() {
415+
local file="$1"
416+
417+
# File size is zero? -> Blank
418+
if [[ ! -s "$file" ]]; then
419+
return 0
420+
fi
421+
422+
# Check if the file contains only whitespace
423+
if [[ $(grep -cvP '\S' "$file") -eq 0 ]]; then
424+
return 0
425+
fi
426+
427+
return 1
428+
}
429+
430+
# Get list of Git-tracked files, excluding ignored ones and unnecessary files
431+
get_git_tracked_files() {
432+
git ls-files --exclude-standard -c -o | grep -Ev "${EXCLUDE_PATTERNS}" || true
433+
}
434+
435+
# Display repository structure safely
436+
show_structure() {
437+
echo -e "${CYAN}📁 Repository Structure (Depth: ${TREE_DEPTH}):${RESET}"
438+
439+
# Try tree first, fallback to ls if tree fails
440+
if ! tree -L "${TREE_DEPTH}" 2>/dev/null; then
441+
echo -e "${YELLOW}⚠ 'tree' command failed, falling back to 'ls -R'${RESET}"
442+
ls -R | head -n 50 # Avoid massive output
443+
fi
444+
445+
echo -e "\n---\n"
446+
}
447+
448+
# Process and display file contents
449+
show_files() {
450+
local interactive_mode="${1:-false}"
451+
452+
# Get filtered list of Git-tracked files
453+
mapfile -t files < <(get_git_tracked_files)
454+
455+
if [[ "${interactive_mode}" == "true" && -x "$(command -v fzf)" ]]; then
456+
# Interactive mode: Select files with fzf
457+
selected_file=$(printf "%s\n" "${files[@]}" | fzf --preview "bat --color=always {}" --height=40%)
458+
files=("$selected_file")
459+
fi
460+
461+
for file in "${files[@]}"; do
462+
# Skip large files
463+
if [[ "$(stat -c%s "$file")" -gt "$MAX_FILE_SIZE" ]]; then
464+
continue
465+
fi
466+
467+
# Skip blank files
468+
if is_blank_file "$file"; then
469+
continue
470+
fi
471+
472+
echo -e "\n${GREEN}==> ${file} <==${RESET}"
473+
474+
if is_binary "$file"; then
475+
echo "🔗 $(get_github_url "$file")"
476+
else
477+
cat -n "$file"
478+
fi
479+
480+
echo -e "\n---"
481+
done
482+
}
483+
484+
# Show usage/help text
485+
show_help() {
486+
echo "Usage: $0 [options]"
487+
echo
488+
echo "Options:"
489+
echo " --interactive Enable interactive file selection with fzf"
490+
echo " --help Show this help message"
491+
}
492+
493+
# Main function
494+
main() {
495+
local args=("$@")
496+
497+
# Parse options
498+
for arg in "${args[@]}"; do
499+
case "$arg" in
500+
--help)
501+
show_help
502+
exit 0
503+
;;
504+
--interactive)
505+
INTERACTIVE_MODE=true
506+
;;
507+
*)
508+
echo -e "${RED}Unknown option: $arg${RESET}" >&2
509+
show_help
510+
exit 1
511+
;;
512+
esac
513+
done
514+
515+
# Generate output
516+
show_structure
517+
show_files "${INTERACTIVE_MODE:-false}"
518+
}
519+
520+
main "$@"
521+
```
522+
331523
## おわりに
332524

333525
この記事では、Uithub から着想を得た便利なシェルスクリプトを紹介しました。

public/20250319-terminal-navigation-with-y-and-z.md.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ tags:
77
- zoxide
88
- yazi
99
private: false
10-
updated_at: '2025-03-19T19:46:47+09:00'
10+
updated_at: '2025-03-19T19:49:57+09:00'
1111
id: c11e8e1464e926a04894
12-
organization_url_name: fukuokaex
12+
organization_url_name: haw
1313
slide: false
1414
ignorePublish: false
1515
---

public/20250331-uit.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
---
2+
title: Uithub をヒントにローカルで使えるコード表示ツールを Go で作った
3+
tags:
4+
- Go
5+
- CLI
6+
- AI
7+
- uithub
8+
private: false
9+
updated_at: '2025-03-31T09:27:28+09:00'
10+
id: 58406b1cd34b3dc0ae9e
11+
organization_url_name: haw
12+
slide: false
13+
ignorePublish: false
14+
---
15+
16+
## はじめに
17+
18+
最近、勤務先の支援もあり AI を活用した開発を日常的に行っています。
19+
20+
https://qiita.com/torifukukaiou/items/9ac6c7258c8a1549674a
21+
22+
一方で、テキストエディタはなるべくシンプルに保ちたい気持ちもあり、AI に直接コード補完を任せるのではなく、自分でコードを書いて考える時間も大切にしています。
23+
24+
https://qiita.com/mnishiguchi/items/d67ef4e363e472411b70
25+
26+
そんな中、同僚に教えてもらった [Uithub](https://uithub.com/) という Web サービスがとても便利でした。Git リポジトリ内のディレクトリ構造とファイル内容を AI に扱いやすい形式で表示してくれます。
27+
28+
https://qiita.com/haw_ohnuma/items/3c4f0a764b1cf66bae7b
29+
30+
Uithub のようなツールをローカル環境でも使いたいと思い、自分なりに作ってみました。
31+
32+
https://uithub.com/
33+
34+
35+
36+
---
37+
38+
## シェルスクリプトでの試作
39+
40+
まずはBash スクリプトで Uithub 的な出力を再現してみました。
41+
42+
- Git 管理されているファイルだけを対象にする
43+
- ディレクトリ構造をツリー形式で表示する
44+
- 各ファイルの内容を見やすく出力する(行番号付き)
45+
46+
といったことを実現しています。
47+
48+
詳細は以下の Qiita 記事にまとめています:
49+
50+
https://qiita.com/mnishiguchi/items/af13b34ac636c03d97c5
51+
52+
ある程度満足のいくものができましたが、スクリプトが少し複雑になってきて、保守しにくさを感じるようになりました。テストも書きづらく、ちょっとした変更にも不安が残ります。
53+
54+
---
55+
56+
## Go言語での書き直し
57+
58+
そこで、改めて Go 言語で CLI ツールとして作り直すことにしました。
59+
60+
ちょうどその頃、日頃から愛用しているバージョン管理ツール[asdf](https://github.com/asdf-vm/asdf) が シェルスクリプトから Go に書き直されたことを知りました。たまたま Go を学習中だったこともあり、言語としてGoを選択しました。
61+
62+
CLI フレームワークには、`asdf` でも使われている [urfave/cli/v2](https://github.com/urfave/cli) を採用しました。軽量で直感的な API が特徴で、今回のようなシンプルなツールにはちょうど良い選択肢だと感じています。
63+
64+
ツール名は `uit`としました。
65+
後付ですが、「Uithub-Inspired Tool」とも読めます。
66+
67+
以下のような機能を備えています:
68+
69+
- Git 管理下のファイルのみを対象に、ディレクトリツリーとファイル内容を表示
70+
- 各ファイルの内容には行番号を付与
71+
- バイナリファイルはデフォルトで非表示
72+
- `--max-lines` オプションで、ファイルごとの表示行数を制限
73+
- `--no-tree``--no-content` オプションで、ツリーや内容の表示を省略可能
74+
75+
GitHub リポジトリはこちら: [mnishiguchi/uit](https://github.com/mnishiguchi/uit)
76+
77+
自分で言うのもなんですが、めっちゃ便利です。
78+
79+
---
80+
81+
## おわりに
82+
83+
自分のために作ったツールですが、もし誰かの役に立つことがあれば嬉しいです。
84+
85+
ツール自体も Go の勉強にもなりましたし、「既存の便利なツールの仕組みをローカルで再現してみる」というのは楽しい学びのあるプロジェクトだと感じました。
86+
87+
好奇心を忘れず、AIを超えていきましょう。
88+
89+
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82804/dc1ddba7-ab4c-5e20-1331-143c842be143.jpeg)
90+
![DSC_0082.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82804/f9f1b977-5bc1-4443-9fc1-8351176ee71d.jpeg)
91+
92+
https://www.haw.co.jp/blog/2025/02/10/qiita_advent2024/

0 commit comments

Comments
 (0)