human_number 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ab664232472a72c0114441a528ec9e72b1287d2cb0123d993b24324aeaa4f6f
4
- data.tar.gz: '080aabbc217c4fc67ca01d4d9aa99791d8826e96bb83c2adb418ac09d7d6e27f'
3
+ metadata.gz: 7e0d600c4f0ff53b38dcd26865c3b55ef28f3a2f22e3ea69cdea9e22b8f81a41
4
+ data.tar.gz: 8da74420bb439d1d5ccc331d9e96b6c0936aefe2f9b5e2df3762201bd5745198
5
5
  SHA512:
6
- metadata.gz: d1ad60597131895ef985c4f513d9f14842fa05b64310e947631dd1f34bdf5eb9c823cce3643534ffb06aa7c93015eec7118a5569c03d76263040c1127274d825
7
- data.tar.gz: e12a574d465e336e25e95151dd007afe9a2065f8fec9652f7a59824fe1094120b75f5c8f715ae2d4948587037fbf5b162a6897cbec0753e6f6848879770133dc
6
+ metadata.gz: 3a2f779396168c7519591e82e4c79358cd84143dea4c8665e13a16d71ed946b9dc2b7d0790daeaac52b083e1c45c13f767910ca498b36f2943fd6e3be1ead350
7
+ data.tar.gz: ac05daeca413e08338aec8b0776accee0abdb3ecfad05cab004d83c31084d4f9faec622e6069d7578256c801882311c6e2f2e64bdaf425711d358ace7339cc1b
data/.rubocop.yml CHANGED
@@ -59,5 +59,3 @@ Metrics/MethodLength:
59
59
 
60
60
  Metrics/ParameterLists:
61
61
  Max: 6
62
-
63
- # RSpec rules removed - using basic RuboCop only
data/BUILD.md ADDED
@@ -0,0 +1,246 @@
1
+ # Build and Publish Guide
2
+
3
+ This project provides three different ways to build and publish the gem, choose the one that best fits your workflow:
4
+
5
+ ## 🔧 Option 1: Rake Tasks (Recommended for Ruby developers)
6
+
7
+ The most Ruby-native approach using rake tasks.
8
+
9
+ ### Available Tasks
10
+ ```bash
11
+ # List all gem-related tasks
12
+ rake -T gem
13
+
14
+ # Run validations only
15
+ rake gem:validate
16
+
17
+ # Build gem with full validations
18
+ rake gem:build
19
+
20
+ # Quick build without validations (for testing)
21
+ rake gem:build_quick
22
+
23
+ # Publish to RubyGems with full validations
24
+ rake gem:publish
25
+
26
+ # Show gem information
27
+ rake gem:info
28
+
29
+ # Clean build artifacts
30
+ rake gem:clean
31
+
32
+ # Bump version interactively and commit
33
+ rake gem:bump
34
+
35
+ # Convenient aliases
36
+ rake build # Same as gem:build
37
+ rake release # Same as gem:publish
38
+ ```
39
+
40
+ ### Examples
41
+ ```bash
42
+ # Full build and publish workflow
43
+ rake gem:validate # Run tests, linting, git checks
44
+ rake gem:build # Build the gem
45
+ rake gem:publish # Publish to RubyGems
46
+
47
+ # Or use the all-in-one command
48
+ rake gem:publish # Does validation + build + publish
49
+
50
+ # Quick development testing
51
+ rake gem:build_quick # Build without validations
52
+ ```
53
+
54
+ ## 🐚 Option 2: Shell Script (Cross-platform compatible)
55
+
56
+ A bash script that works on any Unix-like system.
57
+
58
+ ### Available Commands
59
+ ```bash
60
+ # Show help
61
+ ./scripts/build_and_publish.sh help
62
+
63
+ # Run validations only
64
+ ./scripts/build_and_publish.sh validate
65
+
66
+ # Build gem with full validations
67
+ ./scripts/build_and_publish.sh build
68
+
69
+ # Quick build without validations (for testing)
70
+ ./scripts/build_and_publish.sh build-quick
71
+
72
+ # Publish to RubyGems with full validations
73
+ ./scripts/build_and_publish.sh publish
74
+
75
+ # Show gem information
76
+ ./scripts/build_and_publish.sh info
77
+
78
+ # Clean build artifacts
79
+ ./scripts/build_and_publish.sh clean
80
+
81
+ # Bump version interactively and commit
82
+ ./scripts/build_and_publish.sh bump
83
+ ```
84
+
85
+ ### Examples
86
+ ```bash
87
+ # Full build and publish workflow
88
+ ./scripts/build_and_publish.sh validate # Run all checks
89
+ ./scripts/build_and_publish.sh build # Build the gem
90
+ ./scripts/build_and_publish.sh publish # Publish to RubyGems
91
+
92
+ # Quick development testing
93
+ ./scripts/build_and_publish.sh build-quick
94
+ ```
95
+
96
+ ## ⚙️ Option 3: Makefile (Traditional build tool)
97
+
98
+ Standard make targets for those who prefer Makefiles.
99
+
100
+ ### Available Targets
101
+ ```bash
102
+ # Show help
103
+ make help
104
+
105
+ # Run individual validations
106
+ make test # Run tests only
107
+ make lint # Run RuboCop only
108
+ make validate # Run all validations
109
+
110
+ # Build gem with full validations
111
+ make build
112
+
113
+ # Quick build without validations (for testing)
114
+ make build-quick
115
+
116
+ # Publish to RubyGems with full validations
117
+ make publish
118
+
119
+ # Show gem information
120
+ make info
121
+
122
+ # Clean build artifacts
123
+ make clean
124
+
125
+ # Bump version interactively and commit
126
+ make bump
127
+
128
+ # Install dependencies
129
+ make install
130
+ ```
131
+
132
+ ### Examples
133
+ ```bash
134
+ # Full build and publish workflow
135
+ make validate # Run tests, linting, git checks
136
+ make build # Build the gem
137
+ make publish # Publish to RubyGems
138
+
139
+ # Quick development testing
140
+ make build-quick
141
+ ```
142
+
143
+ ## 🔍 What Each Validation Includes
144
+
145
+ All three build systems perform the same comprehensive validations:
146
+
147
+ ### ✅ Test Validation
148
+ - Runs the complete RSpec test suite
149
+ - Ensures 100% test coverage
150
+ - Validates all functionality works correctly
151
+
152
+ ### ✅ Code Quality Validation
153
+ - Runs RuboCop linting
154
+ - Enforces consistent code style
155
+ - Checks for potential issues
156
+
157
+ ### ✅ Git Validation
158
+ - Ensures working directory is clean (no uncommitted changes)
159
+ - Warns if not on `main` branch (with option to continue)
160
+ - Prevents accidental releases from dirty state
161
+
162
+ ### ✅ Build Validation
163
+ - Verifies gemspec is valid
164
+ - Checks all required files are included
165
+ - Ensures gem can be built successfully
166
+
167
+ ## 📦 Build Artifacts
168
+
169
+ All build methods create gems in the `pkg/` directory:
170
+ - `pkg/human_number-<version>.gem` - The built gem file
171
+
172
+ Use `make clean`, `rake gem:clean`, or `./scripts/build_and_publish.sh clean` to remove build artifacts.
173
+
174
+ ## 🚀 Publishing Process
175
+
176
+ When you run the publish command (any of the three options), it will:
177
+
178
+ 1. **Validate**: Run all tests, linting, and git checks
179
+ 2. **Build**: Create the gem file
180
+ 3. **Tag**: Create a git tag for the version
181
+ 4. **Push**: Push the tag to the remote repository
182
+ 5. **Publish**: Upload the gem to RubyGems.org
183
+
184
+ ## 🔖 Version Management
185
+
186
+ All three build systems include interactive version bumping functionality:
187
+
188
+ ### Version Bump Commands
189
+
190
+ | Tool | Command | Description |
191
+ |------|---------|-------------|
192
+ | **Rake** | `rake gem:bump` | Interactive version bump with commit |
193
+ | **Shell Script** | `./scripts/build_and_publish.sh bump` | Interactive version bump with commit |
194
+ | **Make** | `make bump` | Interactive version bump with commit |
195
+
196
+ ### Version Bump Process
197
+
198
+ When you run any version bump command, it will:
199
+
200
+ 1. **Display Current Version**: Shows the current version from `lib/human_number/version.rb`
201
+ 2. **Interactive Input**: Prompts you to enter the new version
202
+ 3. **Validation**: Ensures semantic versioning format (e.g., `1.2.3` or `1.2.3-alpha.1`)
203
+ 4. **Update File**: Modifies the version file with the new version
204
+ 5. **Git Commit**: Creates a commit with message `chore: bump version to X.Y.Z`
205
+ 6. **Next Steps**: Provides guidance on building and publishing
206
+
207
+ ### Example Workflow
208
+
209
+ ```bash
210
+ # Using rake (recommended for Ruby developers)
211
+ rake gem:bump
212
+ # Current version: 0.1.2
213
+ # Enter new version: 0.2.0
214
+ # ✅ Updated version to 0.2.0
215
+ # ✅ Version bump committed successfully!
216
+
217
+ # Build and publish
218
+ rake gem:publish
219
+ ```
220
+
221
+ ## ⚠️ Prerequisites
222
+
223
+ Before publishing:
224
+
225
+ 1. **RubyGems Account**: Ensure you have a RubyGems.org account
226
+ 2. **API Key**: Configure your RubyGems API key (`gem signin`)
227
+ 3. **Version Bump**: Use interactive version bump commands or manually update `lib/human_number/version.rb`
228
+ 4. **Clean Git**: Commit all changes before publishing (version bump commands handle this automatically)
229
+ 5. **Main Branch**: Recommended to publish from `main` branch
230
+
231
+ ## 🔧 Configuration Changes
232
+
233
+ **Important**: This setup has removed MFA requirement from the gemspec to simplify the publishing process. If you need MFA, you can re-enable it by adding this line to `human_number.gemspec`:
234
+
235
+ ```ruby
236
+ spec.metadata["rubygems_mfa_required"] = "true"
237
+ ```
238
+
239
+ ## 💡 Recommendations
240
+
241
+ - **For Ruby developers**: Use rake tasks (most native)
242
+ - **For CI/CD pipelines**: Use shell script (most portable)
243
+ - **For traditional workflows**: Use Makefile (universal)
244
+ - **For quick testing**: Use the `*-quick` variants to skip validations
245
+
246
+ Choose the tool that best fits your development workflow and team preferences!
data/CHANGELOG.md CHANGED
@@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
13
13
  - **Human-readable number formatting** with intelligent, culturally-appropriate abbreviations
14
14
  - **Three cultural number systems** automatically selected by locale:
15
15
  - **Western System**: K/M/B/T (thousand/million/billion/trillion) for English, German, French, Spanish, Italian, Portuguese, Russian, Dutch, Swedish, Danish, Norwegian
16
- - **East Asian System**: 천/만/억/조 (Korean) and 千/万/億/兆 (Japanese/Chinese) for ko, ja, zh, zh-CN, zh-TW locales
16
+ - **East Asian System**: 만/억/조 (Korean) and 万/億/兆 (Japanese/Chinese) for ko, ja, zh, zh-CN, zh-TW locales
17
17
  - **Indian System**: thousand/lakh/crore for Hindi, Urdu, Bengali, and Indian English (hi, ur, bn, en-IN)
18
18
 
19
19
  #### Currency Formatting
@@ -86,4 +86,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
86
86
  - **Formatters::Currency**: Currency symbol and format string application
87
87
  - **Clean separation**: Number formatting independent of currency concerns
88
88
 
89
- [0.1.0]: https://github.com/yourusername/human_number/releases/tag/v0.1.0
89
+ [0.1.0]: https://github.com/ether-moon/human_number/releases/tag/v0.1.0
data/CLAUDE.md CHANGED
@@ -87,10 +87,10 @@ The gem automatically selects appropriate number systems based on locale:
87
87
  - Used by: English, German, French, Spanish, Italian, Portuguese, Russian, Dutch, Swedish, Danish, Norwegian
88
88
  - Target locales: `%i[en es fr de it pt ru nl sv da no]`
89
89
 
90
- - **East Asian System** (`EastAsianSystem`): 천/만/억/조 or 千/万/億/兆
90
+ - **East Asian System** (`EastAsianSystem`): 만/억/조 or 万/億/兆
91
91
  - Used by: Korean, Japanese, Chinese
92
92
  - Target locales: `%i[ko ja zh zh-CN zh-TW]`
93
- - Units: 천/千 (thousand), 만/万 (ten thousand), 억/億 (hundred million), 조/兆 (trillion)
93
+ - Units: 만/万 (ten thousand), 억/億 (hundred million), 조/兆 (trillion)
94
94
 
95
95
  - **Indian System** (`IndianSystem`): thousand/lakh/crore
96
96
  - Used by: Hindi, Urdu, Bengali, Indian English
@@ -216,4 +216,4 @@ This project is based on the following international standards:
216
216
  - [Microsoft Globalization - Currency Formats](https://learn.microsoft.com/en-us/globalization/locale/currency-formats)
217
217
  - [Unicode CLDR](http://cldr.unicode.org/)
218
218
  - [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217)
219
- - [rails-i18n](https://github.com/svenfuchs/rails-i18n)
219
+ - [rails-i18n](https://github.com/svenfuchs/rails-i18n)
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Your Name
3
+ Copyright (c) 2025 Ether Moon
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/Makefile ADDED
@@ -0,0 +1,142 @@
1
+ # HumanNumber Gem Build and Publish Makefile
2
+
3
+ .PHONY: help build publish build-quick validate clean info test lint bump
4
+
5
+ # Default target
6
+ help:
7
+ @echo "HumanNumber Gem Build and Publish Makefile"
8
+ @echo ""
9
+ @echo "Available targets:"
10
+ @echo " build Build gem with full validations (tests, linting, git checks)"
11
+ @echo " publish Publish gem to RubyGems with full validations"
12
+ @echo " build-quick Build gem without validations (for testing)"
13
+ @echo " validate Run all validations without building"
14
+ @echo " test Run tests only"
15
+ @echo " lint Run RuboCop only"
16
+ @echo " info Show gem and repository information"
17
+ @echo " clean Clean build artifacts"
18
+ @echo " bump Bump version interactively and commit"
19
+ @echo " help Show this help message"
20
+ @echo ""
21
+ @echo "Examples:"
22
+ @echo " make build # Build gem with validations"
23
+ @echo " make publish # Build and publish to RubyGems"
24
+ @echo " make bump # Bump version interactively"
25
+ @echo " make info # Show current gem info"
26
+
27
+ # Run tests
28
+ test:
29
+ @echo "📋 Running tests..."
30
+ @bundle exec rspec
31
+ @echo "✅ All tests passed"
32
+
33
+ # Run linting
34
+ lint:
35
+ @echo "🧹 Running RuboCop..."
36
+ @bundle exec rubocop
37
+ @echo "✅ RuboCop checks passed"
38
+
39
+ # Validate git status
40
+ validate-git:
41
+ @echo "📋 Checking git status..."
42
+ @if [ -n "$$(git status --porcelain)" ]; then \
43
+ echo "❌ Git working directory is not clean. Please commit all changes first."; \
44
+ exit 1; \
45
+ fi
46
+ @echo "✅ Git working directory is clean"
47
+ @current_branch=$$(git rev-parse --abbrev-ref HEAD); \
48
+ if [ "$$current_branch" != "main" ]; then \
49
+ echo "⚠️ Warning: You're on branch '$$current_branch', not 'main'"; \
50
+ read -p "Continue anyway? (y/N): " response; \
51
+ if [ "$$response" != "y" ] && [ "$$response" != "Y" ]; then \
52
+ echo "❌ Aborted by user"; \
53
+ exit 1; \
54
+ fi; \
55
+ fi
56
+ @echo "✅ Git branch check passed"
57
+
58
+ # Run all validations
59
+ validate: test lint validate-git
60
+ @echo "✅ All validations passed!"
61
+
62
+ # Build gem with validations
63
+ build: validate
64
+ @echo "🔨 Building gem..."
65
+ @bundle exec rake build
66
+ @echo "✅ Gem built successfully!"
67
+
68
+ # Build gem without validations (for testing)
69
+ build-quick:
70
+ @echo "🔨 Quick building gem (no validations)..."
71
+ @bundle exec rake build
72
+ @echo "✅ Gem built!"
73
+
74
+ # Publish gem to RubyGems
75
+ publish: validate
76
+ @echo "📦 Publishing gem to RubyGems..."
77
+ @bundle exec rake release
78
+ @echo "✅ Gem published successfully!"
79
+
80
+ # Show gem information
81
+ info:
82
+ @echo "📋 Gem Information:"
83
+ @echo " Name: human_number"
84
+ @echo " Version: $$(ruby -r ./lib/human_number/version -e 'puts HumanNumber::VERSION')"
85
+ @echo " Built gems: $$(ls pkg/*.gem 2>/dev/null || echo 'none')"
86
+ @echo " Git branch: $$(git rev-parse --abbrev-ref HEAD)"
87
+ @git_status=$$(git status --porcelain); \
88
+ if [ -z "$$git_status" ]; then \
89
+ echo " Git status: clean"; \
90
+ else \
91
+ echo " Git status: dirty"; \
92
+ fi
93
+
94
+ # Clean build artifacts
95
+ clean:
96
+ @echo "🧹 Cleaning build artifacts..."
97
+ @rm -rf pkg/
98
+ @echo "✅ Build artifacts cleaned!"
99
+
100
+ # Bump version interactively and commit
101
+ bump:
102
+ @echo "🔖 Version Bump"
103
+ @current_version=$$(ruby -r ./lib/human_number/version -e 'puts HumanNumber::VERSION'); \
104
+ echo "Current version: $$current_version"; \
105
+ echo ""; \
106
+ read -p "Enter new version: " new_version; \
107
+ if [ -z "$$new_version" ]; then \
108
+ echo "❌ No version entered. Aborting."; \
109
+ exit 1; \
110
+ fi; \
111
+ if ! echo "$$new_version" | grep -qE "^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$$"; then \
112
+ echo "❌ Invalid version format. Please use semantic versioning (e.g., 1.2.3 or 1.2.3-alpha.1)"; \
113
+ exit 1; \
114
+ fi; \
115
+ if [ "$$new_version" = "$$current_version" ]; then \
116
+ echo "❌ New version is the same as current version. Aborting."; \
117
+ exit 1; \
118
+ fi; \
119
+ version_file="lib/human_number/version.rb"; \
120
+ sed -i.bak "s/VERSION = \".*\"/VERSION = \"$$new_version\"/" "$$version_file" && rm "$$version_file.bak"; \
121
+ echo "✅ Updated version to $$new_version"; \
122
+ echo ""; \
123
+ echo "📝 Creating version bump commit..."; \
124
+ git add "$$version_file"; \
125
+ commit_message="chore: bump version to $$new_version"; \
126
+ if git commit -m "$$commit_message"; then \
127
+ echo "✅ Version bump committed successfully!"; \
128
+ echo ""; \
129
+ echo "📋 Next steps:"; \
130
+ echo " - Review the changes: git show"; \
131
+ echo " - Build and publish: make publish"; \
132
+ echo " - Push to remote: git push && git push --tags"; \
133
+ else \
134
+ echo "❌ Failed to create commit"; \
135
+ exit 1; \
136
+ fi
137
+
138
+ # Install dependencies
139
+ install:
140
+ @echo "📦 Installing dependencies..."
141
+ @bundle install
142
+ @echo "✅ Dependencies installed!"
data/README.md CHANGED
@@ -5,7 +5,7 @@ HumanNumber is a Ruby gem that implements accurate number formatting based on in
5
5
  ## Features
6
6
 
7
7
  - 🌍 **International Standards Compliance**: Based on Microsoft Globalization and Unicode CLDR standards
8
- - 🔢 **Cultural Number Systems**: Automatic selection of Western (K/M/B/T), East Asian (천/만/억/조), or Indian (lakh/crore) systems
8
+ - 🔢 **Cultural Number Systems**: Automatic selection of Western (K/M/B/T), East Asian (만/억/조), or Indian (lakh/crore) systems
9
9
  - 💰 **Currency Formatting**: ISO 4217 currency codes with native locale precision rules
10
10
  - 🏗️ **Intelligent Abbreviations**: Culturally-appropriate large number simplification
11
11
  - 🔧 **Rails Integration**: Complete compatibility with Rails I18n infrastructure
@@ -34,7 +34,7 @@ HumanNumber.human_number(50_000, locale: :ko) #=> "5만"
34
34
 
35
35
  # Currency formatting
36
36
  HumanNumber.currency(1234.56, currency_code: 'USD', locale: :en) #=> "$1,234.56"
37
- HumanNumber.human_currency(1_234_567, currency_code: 'USD', locale: :en) #=> "$1.2M"
37
+ HumanNumber.human_currency(1_234_567, currency_code: 'USD', locale: :en) #=> "$1M"
38
38
  ```
39
39
 
40
40
  ## Installation
@@ -71,17 +71,17 @@ HumanNumber.human_number(1_234_567) #=> "1.2M"
71
71
  HumanNumber.human_number(50_000, locale: :ko) #=> "5만"
72
72
  HumanNumber.human_number(50_000, locale: :ja) #=> "5万"
73
73
 
74
- # Precision control (default: max_digits: 2)
75
- HumanNumber.human_number(1_234_567, max_digits: 1) #=> "1M"
76
- HumanNumber.human_number(1_234_567, max_digits: 3) #=> "1.23M"
77
- HumanNumber.human_number(1_234_567, max_digits: nil) #=> "1M 234K 567"
74
+ # Significant digits control (default: max_digits: 2)
75
+ HumanNumber.human_number(1_234_567, max_digits: 1) #=> "1M" # 1 significant digit
76
+ HumanNumber.human_number(1_234_567, max_digits: 3) #=> "1.23M" # 3 significant digits
77
+ HumanNumber.human_number(1_234_567, max_digits: nil) #=> "1M 234K 567" # Complete breakdown
78
78
 
79
79
  # Unit preferences (Western locales only)
80
80
  HumanNumber.human_number(1_000_000, abbr_units: true) #=> "1M"
81
81
  HumanNumber.human_number(1_000_000, abbr_units: false) #=> "1 million"
82
82
 
83
83
  # Minimum thresholds
84
- HumanNumber.human_number(5_000, min_unit: 10_000) #=> "5000"
84
+ HumanNumber.human_number(5_000, min_unit: 10_000) #=> "5,000"
85
85
  HumanNumber.human_number(50_000, min_unit: 10_000) #=> "50K"
86
86
 
87
87
  # Zero trimming (default: true)
@@ -115,7 +115,7 @@ HumanNumber.currency(1234.56, currency_code: 'JPY', locale: :en) #=> "1,235円"
115
115
  Human-readable currency formatting with cultural abbreviations.
116
116
 
117
117
  ```ruby
118
- HumanNumber.human_currency(1_234_567, currency_code: 'USD', locale: :en) #=> "$1.2M"
118
+ HumanNumber.human_currency(1_234_567, currency_code: 'USD', locale: :en) #=> "$1M"
119
119
  HumanNumber.human_currency(50_000, currency_code: 'KRW', locale: :ko) #=> "5만원"
120
120
 
121
121
  # Combined options
@@ -129,7 +129,7 @@ In Rails applications, helper methods are automatically available:
129
129
 
130
130
  ```erb
131
131
  <%= human_number(1_234_567) %> <!-- 1.2M -->
132
- <%= human_currency(1_234_567, currency_code: 'USD') %> <!-- $1.2M -->
132
+ <%= human_currency(1_234_567, currency_code: 'USD') %> <!-- $1M -->
133
133
  <%= currency(1234.56, currency_code: 'USD') %> <!-- $1,234.56 -->
134
134
 
135
135
  <!-- With options -->
@@ -155,12 +155,12 @@ HumanNumber.human_number(1_000_000_000, locale: :en) #=> "1B"
155
155
  **Used by:** Korean (ko), Japanese (ja), Chinese (zh, zh-CN, zh-TW)
156
156
 
157
157
  ```ruby
158
- HumanNumber.human_number(1_234_567, locale: :ko) #=> "123만"
159
- HumanNumber.human_number(1_234_567, locale: :ja) #=> "123万"
158
+ HumanNumber.human_number(1_234_567, locale: :ko) #=> "120만"
159
+ HumanNumber.human_number(1_234_567, locale: :ja) #=> "120万"
160
160
  HumanNumber.human_number(100_000_000, locale: :ko) #=> "1억"
161
161
  ```
162
162
 
163
- **Units:** 천/千 (thousand), 만/万 (ten thousand), 억/億 (hundred million), 조/兆 (trillion)
163
+ **Units:** 만/万 (ten thousand), 억/億 (hundred million), 조/兆 (trillion)
164
164
 
165
165
  ### Indian System (lakh/crore)
166
166
  **Used by:** Hindi (hi), Urdu (ur), Bengali (bn), Indian English (en-IN)
@@ -277,7 +277,7 @@ $ rake # Runs both spec and rubocop
277
277
 
278
278
  ## Contributing
279
279
 
280
- 1. Fork it (https://github.com/yourusername/human_number/fork)
280
+ 1. Fork it (https://github.com/ether-moon/human_number/fork)
281
281
  2. Create your feature branch (`git checkout -b feature/my-new-feature`)
282
282
  3. Commit your changes (`git commit -am 'Add some feature'`)
283
283
  4. Push to the branch (`git push origin feature/my-new-feature`)
@@ -320,4 +320,4 @@ See [CHANGELOG.md](CHANGELOG.md) for details.
320
320
 
321
321
  ## Issues
322
322
 
323
- Please report bugs and feature requests at [GitHub Issues](https://github.com/yourusername/human_number/issues).
323
+ Please report bugs and feature requests at [GitHub Issues](https://github.com/ether-moon/human_number/issues).
data/Rakefile CHANGED
@@ -10,3 +10,138 @@ require "rubocop/rake_task"
10
10
  RuboCop::RakeTask.new
11
11
 
12
12
  task default: %i[spec rubocop]
13
+
14
+ # Gem build and publish tasks
15
+ namespace :gem do
16
+ desc "Run all pre-publish validations"
17
+ task :validate do
18
+ puts "🔍 Running pre-publish validations..."
19
+
20
+ # Run tests
21
+ puts "\n📋 Running tests..."
22
+ Rake::Task[:spec].invoke
23
+
24
+ # Run linting
25
+ puts "\n🧹 Running RuboCop..."
26
+ Rake::Task[:rubocop].invoke
27
+
28
+ # Check git status
29
+ puts "\n📋 Checking git status..."
30
+ unless `git status --porcelain`.strip.empty?
31
+ abort "❌ Git working directory is not clean. Please commit all changes first."
32
+ end
33
+
34
+ # Check if we're on main branch
35
+ current_branch = `git rev-parse --abbrev-ref HEAD`.strip
36
+ unless current_branch == "main"
37
+ puts "⚠️ Warning: You're on branch '#{current_branch}', not 'main'"
38
+ print "Continue anyway? (y/N): "
39
+ response = $stdin.gets.chomp.downcase
40
+ abort "❌ Aborted by user" unless %w[y yes].include?(response)
41
+ end
42
+
43
+ puts "✅ All validations passed!"
44
+ end
45
+
46
+ desc "Build the gem"
47
+ task build: :validate do
48
+ puts "\n🔨 Building gem..."
49
+ Rake::Task["build"].invoke
50
+ puts "✅ Gem built successfully!"
51
+ end
52
+
53
+ desc "Publish gem to RubyGems (with validations)"
54
+ task publish: :validate do
55
+ puts "\n📦 Publishing gem to RubyGems..."
56
+
57
+ # Build and push
58
+ Rake::Task["release"].invoke
59
+ puts "✅ Gem published successfully!"
60
+ end
61
+
62
+ desc "Quick build without validations (for testing)"
63
+ task :build_quick do
64
+ puts "🔨 Quick building gem..."
65
+ Rake::Task["build"].invoke
66
+ puts "✅ Gem built!"
67
+ end
68
+
69
+ desc "Clean build artifacts"
70
+ task :clean do
71
+ puts "🧹 Cleaning build artifacts..."
72
+ FileUtils.rm_rf("pkg")
73
+ puts "✅ Build artifacts cleaned!"
74
+ end
75
+
76
+ desc "Show gem info"
77
+ task :info do
78
+ require_relative "lib/human_number/version"
79
+ puts "\n📋 Gem Information:"
80
+ puts " Name: human_number"
81
+ puts " Version: #{HumanNumber::VERSION}"
82
+ puts " Built gems: #{Dir.glob("pkg/*.gem").join(", ")}"
83
+ puts " Git branch: #{`git rev-parse --abbrev-ref HEAD`.strip}"
84
+ puts " Git status: #{`git status --porcelain`.strip.empty? ? "clean" : "dirty"}"
85
+ end
86
+
87
+ desc "Bump version interactively and commit"
88
+ task :bump do
89
+ require_relative "lib/human_number/version"
90
+
91
+ puts "🔖 Version Bump"
92
+ puts "Current version: #{HumanNumber::VERSION}"
93
+ puts ""
94
+
95
+ # Get new version from user
96
+ print "Enter new version: "
97
+ new_version = $stdin.gets.chomp.strip
98
+
99
+ if new_version.empty?
100
+ puts "❌ No version entered. Aborting."
101
+ exit 1
102
+ end
103
+
104
+ # Validate version format (basic semver check)
105
+ unless new_version.match?(/^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?$/)
106
+ puts "❌ Invalid version format. Please use semantic versioning (e.g., 1.2.3 or 1.2.3-alpha.1)"
107
+ exit 1
108
+ end
109
+
110
+ # Check if version is different
111
+ if new_version == HumanNumber::VERSION
112
+ puts "❌ New version is the same as current version. Aborting."
113
+ exit 1
114
+ end
115
+
116
+ # Update version file
117
+ version_file = "lib/human_number/version.rb"
118
+ version_content = File.read(version_file)
119
+ new_content = version_content.gsub(/VERSION = ".*"/, "VERSION = \"#{new_version}\"")
120
+
121
+ File.write(version_file, new_content)
122
+ puts "✅ Updated version to #{new_version}"
123
+
124
+ # Create commit
125
+ puts "\n📝 Creating version bump commit..."
126
+ system("git add #{version_file}")
127
+ commit_message = "chore: bump version to #{new_version}"
128
+
129
+ if system("git commit -m '#{commit_message}'")
130
+ puts "✅ Version bump committed successfully!"
131
+ puts "\n📋 Next steps:"
132
+ puts " - Review the changes: git show"
133
+ puts " - Build and publish: rake gem:publish"
134
+ puts " - Push to remote: git push && git push --tags"
135
+ else
136
+ puts "❌ Failed to create commit"
137
+ exit 1
138
+ end
139
+ end
140
+ end
141
+
142
+ # Convenient aliases
143
+ desc "Build and publish gem (same as gem:publish)"
144
+ task release: "gem:publish"
145
+
146
+ desc "Build gem only (same as gem:build)"
147
+ task build: "gem:build"
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/human_number/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "human_number"
7
+ spec.version = HumanNumber::VERSION
8
+ spec.authors = ["Ether Moon"]
9
+ spec.email = ["ethermoon42@gmail.com"]
10
+
11
+ spec.summary = "International standard-based number formatting for Ruby applications"
12
+ spec.description = "HumanNumber implements accurate number formatting based on international standards " \
13
+ "including Microsoft Globalization documentation and Unicode CLDR. Provides human-readable " \
14
+ "number formats with precise locale-specific decimal separators, thousand separators, " \
15
+ "currency formats, and cultural number conventions."
16
+ spec.homepage = "https://github.com/ether-moon/human_number"
17
+ spec.license = "MIT"
18
+ spec.required_ruby_version = ">= 3.1.0"
19
+
20
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
21
+ spec.metadata["homepage_uri"] = spec.homepage
22
+ spec.metadata["source_code_uri"] = "https://github.com/ether-moon/human_number"
23
+ spec.metadata["changelog_uri"] = "https://github.com/ether-moon/human_number/blob/main/CHANGELOG.md"
24
+ spec.metadata["rubygems_mfa_required"] = "true"
25
+
26
+ # Specify which files should be added to the gem when it is released.
27
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
28
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
29
+ `git ls-files -z`.split("\x0").reject do |f|
30
+ (f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
31
+ end
32
+ end
33
+ spec.bindir = "exe"
34
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
35
+ spec.require_paths = ["lib"]
36
+
37
+ # Runtime dependencies
38
+ spec.add_dependency "actionview", ">= 5.2"
39
+ spec.add_dependency "i18n", ">= 1.6", "< 2"
40
+ spec.add_dependency "rails-i18n", ">= 5.1"
41
+ end
@@ -27,7 +27,7 @@ module HumanNumber
27
27
  # @param number [Numeric] Number to format
28
28
  # @param locale [Symbol, String] Locale for unit system selection
29
29
  # @param abbr_units [Boolean] Use abbreviated symbols vs full words
30
- # @param max_digits [Integer, nil] Max digits after decimal, nil for complete mode
30
+ # @param max_digits [Integer, nil] Maximum significant digits to display, nil for complete mode
31
31
  # @param min_unit [Integer, nil] Minimum unit threshold for abbreviation
32
32
  # @param trim_zeros [Boolean] Remove trailing decimal zeros
33
33
  # @return [String] Formatted number string
@@ -80,14 +80,9 @@ module HumanNumber
80
80
  }.freeze
81
81
  end
82
82
 
83
- # Default options for currency number formatting (tighter display)
84
- def default_currency_number_options
85
- {
86
- abbr_units: true,
87
- max_digits: 1,
88
- min_unit: nil,
89
- trim_zeros: true,
90
- }.freeze
83
+ # Format numbers below min_unit threshold with locale-appropriate delimiters
84
+ def format_below_min_unit(number, locale)
85
+ number_with_delimiter(number, locale: locale) || number.to_s
91
86
  end
92
87
 
93
88
  private
@@ -121,6 +116,9 @@ module HumanNumber
121
116
  def format_number(number, locale:, abbr_units: true, min_unit: nil, max_digits: 2, trim_zeros: true)
122
117
  return ZERO_STRING if number.zero?
123
118
 
119
+ # Check if number meets minimum unit threshold for human formatting
120
+ return Number.format_below_min_unit(number, locale) if min_unit && number.abs < min_unit
121
+
124
122
  parts = if max_digits.nil?
125
123
  format_in_complete_mode(number, locale, abbr_units, min_unit)
126
124
  else
@@ -132,22 +130,20 @@ module HumanNumber
132
130
  finalize_result(number, parts)
133
131
  end
134
132
 
135
- def format_in_complete_mode(number, locale, abbr_units, min_unit)
133
+ def format_in_complete_mode(number, locale, abbr_units, _min_unit)
136
134
  # Complete mode shows all units: "1M 234K 567"
137
135
  unit_breakdown = break_down_into_all_units(number)
138
- units_above_threshold = filter_by_minimum_unit_threshold(unit_breakdown, min_unit)
139
- return nil if units_above_threshold.empty?
136
+ return nil if unit_breakdown.empty?
140
137
 
141
- format_all_unit_parts(units_above_threshold, locale, abbr_units)
138
+ format_all_unit_parts(unit_breakdown, locale, abbr_units)
142
139
  end
143
140
 
144
- def format_in_abbreviated_mode(number, locale, abbr_units, max_digits, trim_zeros, min_unit)
141
+ def format_in_abbreviated_mode(number, locale, abbr_units, max_digits, trim_zeros, _min_unit)
145
142
  # Abbreviated mode shows single largest unit: "1.2M"
146
143
  unit_breakdown = break_down_into_largest_unit(number)
147
- units_above_threshold = filter_by_minimum_unit_threshold(unit_breakdown, min_unit)
148
- return nil if units_above_threshold.empty?
144
+ return nil if unit_breakdown.empty?
149
145
 
150
- format_abbreviated_unit_parts(units_above_threshold, locale, abbr_units, max_digits, trim_zeros)
146
+ format_abbreviated_unit_parts(unit_breakdown, locale, abbr_units, max_digits, trim_zeros)
151
147
  end
152
148
 
153
149
  private
@@ -204,10 +200,18 @@ module HumanNumber
204
200
 
205
201
  # Format unit parts for abbreviated display (e.g., "1.2M")
206
202
  def format_abbreviated_unit_parts(breakdown, locale, abbr_units, max_digits, trim_zeros)
203
+ # Check if we're in human formatting mode (any non-:units parts exist)
204
+ human_formatting_applied = breakdown.any? { |unit_info| unit_info[:unit_key] != :units }
205
+
207
206
  breakdown.map do |unit_info|
208
207
  if unit_info[:unit_key] == :units
209
- # Raw numbers don't need significant digits rounding
210
- format_raw_number_count(unit_info[:count], max_digits, trim_zeros)
208
+ if human_formatting_applied
209
+ # Part of human formatting - no delimiters
210
+ unit_info[:count].to_s
211
+ else
212
+ # Numbers below minimum unit threshold - apply locale formatting
213
+ Number.format_below_min_unit(unit_info[:count], locale)
214
+ end
211
215
  else
212
216
  # Format with unit symbol (e.g., "1.2" + "M" = "1.2M")
213
217
  format_number_with_unit_symbol(unit_info, locale, abbr_units, max_digits, trim_zeros)
@@ -271,10 +275,13 @@ module HumanNumber
271
275
  return handle_edge_cases(number, digits) if should_handle_edge_case?(number, digits)
272
276
 
273
277
  abs_num = number.abs
274
- int_digits = count_integer_digits(abs_num.to_i)
275
278
 
276
- result = calculate_significant_digits_result(abs_num, digits, int_digits)
277
- apply_sign(number, result)
279
+ # Simple significant digits rounding using scientific notation
280
+ magnitude = Math.log10(abs_num).floor
281
+ scale_factor = 10**(digits - 1 - magnitude)
282
+
283
+ rounded = (abs_num * scale_factor).round / scale_factor.to_f
284
+ apply_sign(number, rounded)
278
285
  end
279
286
 
280
287
  def should_handle_edge_case?(number, digits)
@@ -287,14 +294,6 @@ module HumanNumber
287
294
  number
288
295
  end
289
296
 
290
- def calculate_significant_digits_result(abs_num, digits, int_digits)
291
- if int_digits >= digits
292
- truncate_to_digits(abs_num.to_i, digits)
293
- else
294
- round_with_decimals(abs_num, digits, int_digits)
295
- end
296
- end
297
-
298
297
  def apply_sign(original_number, result)
299
298
  original_number.negative? ? -result : result
300
299
  end
@@ -303,15 +302,6 @@ module HumanNumber
303
302
  int_part.zero? ? SINGLE_DIGIT_LIMIT : int_part.to_s.length
304
303
  end
305
304
 
306
- def truncate_to_digits(int_part, digits)
307
- int_part.to_s[0, digits].to_i.to_f
308
- end
309
-
310
- def round_with_decimals(abs_num, digits, int_digits)
311
- decimal_places = digits - int_digits
312
- (abs_num * (10**decimal_places)).round / (10**decimal_places).to_f
313
- end
314
-
315
305
  # Look up the localized symbol for a unit (e.g., 'M' for million)
316
306
  def lookup_unit_symbol(locale, unit_key, abbr_units)
317
307
  section = abbr_units ? I18N_ABBR_UNITS_SECTION : I18N_UNITS_SECTION
@@ -391,10 +381,18 @@ module HumanNumber
391
381
 
392
382
  # Format unit parts for complete display (e.g., "1M 234K 567")
393
383
  def format_all_unit_parts(breakdown, locale, abbr_units)
384
+ # Check if we're in human formatting mode (any non-:units parts exist)
385
+ human_formatting_applied = breakdown.any? { |unit_info| unit_info[:unit_key] != :units }
386
+
394
387
  breakdown.map do |unit_info|
395
388
  if unit_info[:unit_key] == :units
396
- # Raw numbers shown as integers in complete mode
397
- unit_info[:count].to_i.to_s
389
+ if human_formatting_applied
390
+ # Part of human formatting - no delimiters
391
+ unit_info[:count].to_i.to_s
392
+ else
393
+ # Numbers below minimum unit threshold - apply locale formatting
394
+ Number.format_below_min_unit(unit_info[:count].to_i, locale)
395
+ end
398
396
  else
399
397
  # Format each unit part with its symbol
400
398
  format_complete_unit_with_symbol(unit_info, locale, abbr_units)
@@ -418,7 +416,6 @@ module HumanNumber
418
416
  { key: :trillion, divisor: 1_000_000_000_000 },
419
417
  { key: :hundred_million, divisor: 100_000_000 },
420
418
  { key: :ten_thousand, divisor: 10_000 },
421
- { key: :thousand, divisor: 1_000 },
422
419
  ].freeze
423
420
 
424
421
  class << self
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HumanNumber
4
- VERSION = "0.1.2"
4
+ VERSION = "0.1.4"
5
5
  end
data/lib/human_number.rb CHANGED
@@ -26,7 +26,7 @@ module HumanNumber
26
26
  # This method provides culturally-appropriate number formatting with automatic
27
27
  # unit system selection based on locale:
28
28
  # - **Western locales**: K/M/B/T (thousand/million/billion/trillion)
29
- # - **East Asian locales**: 천/만/억/조 or 千/万/億/兆
29
+ # - **East Asian locales**: 만/억/조 or 万/億/兆
30
30
  # - **Indian locales**: thousand/lakh/crore
31
31
  #
32
32
  # @param number [Numeric] The number to format
@@ -160,7 +160,7 @@ module HumanNumber
160
160
  # HumanNumber.human_currency(50000, currency_code: 'KRW', locale: :ko) #=> "5만원"
161
161
  #
162
162
  # @example Precision control
163
- # HumanNumber.human_currency(1234567, currency_code: 'USD', locale: :en, max_digits: 2) #=> "$1.23M"
163
+ # HumanNumber.human_currency(1234567, currency_code: 'USD', locale: :en, max_digits: 2) #=> "$1.2M"
164
164
  # HumanNumber.human_currency(1234567, currency_code: 'USD', locale: :en, max_digits: nil) #=> "$1M 234K 567"
165
165
  #
166
166
  # @example Unit preferences
@@ -179,7 +179,7 @@ module HumanNumber
179
179
  validate_currency_code!(currency_code)
180
180
  validate_locale!(locale)
181
181
 
182
- final_options = Formatters::Number.default_currency_number_options.merge(options)
182
+ final_options = Formatters::Number.default_options.merge(options)
183
183
 
184
184
  formatted_number = Formatters::Number.format(number, locale:, **final_options)
185
185
  Formatters::Currency.format(formatted_number, currency_code:, locale:)
@@ -0,0 +1,204 @@
1
+ #!/bin/bash
2
+
3
+ # HumanNumber Gem Build and Publish Script
4
+ # Usage: ./scripts/build_and_publish.sh [build|publish|info|clean]
5
+
6
+ set -e # Exit on any error
7
+
8
+ # Colors for output
9
+ RED='\033[0;31m'
10
+ GREEN='\033[0;32m'
11
+ YELLOW='\033[1;33m'
12
+ BLUE='\033[0;34m'
13
+ NC='\033[0m' # No Color
14
+
15
+ # Helper functions
16
+ log_info() {
17
+ echo -e "${BLUE}ℹ️ $1${NC}"
18
+ }
19
+
20
+ log_success() {
21
+ echo -e "${GREEN}✅ $1${NC}"
22
+ }
23
+
24
+ log_warning() {
25
+ echo -e "${YELLOW}⚠️ $1${NC}"
26
+ }
27
+
28
+ log_error() {
29
+ echo -e "${RED}❌ $1${NC}"
30
+ exit 1
31
+ }
32
+
33
+ # Validation functions
34
+ validate_git_status() {
35
+ log_info "Checking git status..."
36
+ if [ -n "$(git status --porcelain)" ]; then
37
+ log_error "Git working directory is not clean. Please commit all changes first."
38
+ fi
39
+ log_success "Git working directory is clean"
40
+ }
41
+
42
+ validate_git_branch() {
43
+ log_info "Checking git branch..."
44
+ current_branch=$(git rev-parse --abbrev-ref HEAD)
45
+ if [ "$current_branch" != "main" ]; then
46
+ log_warning "You're on branch '$current_branch', not 'main'"
47
+ read -p "Continue anyway? (y/N): " -n 1 -r
48
+ echo
49
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
50
+ log_error "Aborted by user"
51
+ fi
52
+ fi
53
+ log_success "Git branch check passed"
54
+ }
55
+
56
+ run_tests() {
57
+ log_info "Running tests..."
58
+ if ! bundle exec rspec; then
59
+ log_error "Tests failed"
60
+ fi
61
+ log_success "All tests passed"
62
+ }
63
+
64
+ run_linting() {
65
+ log_info "Running RuboCop..."
66
+ if ! bundle exec rubocop; then
67
+ log_error "RuboCop checks failed"
68
+ fi
69
+ log_success "RuboCop checks passed"
70
+ }
71
+
72
+ validate_all() {
73
+ echo "🔍 Running pre-publish validations..."
74
+ run_tests
75
+ run_linting
76
+ validate_git_status
77
+ validate_git_branch
78
+ log_success "All validations passed!"
79
+ }
80
+
81
+ build_gem() {
82
+ log_info "Building gem..."
83
+ if ! bundle exec rake build; then
84
+ log_error "Gem build failed"
85
+ fi
86
+ log_success "Gem built successfully!"
87
+ }
88
+
89
+ publish_gem() {
90
+ log_info "Publishing gem to RubyGems..."
91
+ if ! bundle exec rake release; then
92
+ log_error "Gem publish failed"
93
+ fi
94
+ log_success "Gem published successfully!"
95
+ }
96
+
97
+ show_info() {
98
+ echo "📋 Gem Information:"
99
+ echo " Name: human_number"
100
+ echo " Version: $(ruby -r ./lib/human_number/version -e 'puts HumanNumber::VERSION')"
101
+ echo " Built gems: $(ls pkg/*.gem 2>/dev/null || echo 'none')"
102
+ echo " Git branch: $(git rev-parse --abbrev-ref HEAD)"
103
+ echo " Git status: $([ -z "$(git status --porcelain)" ] && echo 'clean' || echo 'dirty')"
104
+ }
105
+
106
+ clean_artifacts() {
107
+ log_info "Cleaning build artifacts..."
108
+ rm -rf pkg/
109
+ log_success "Build artifacts cleaned!"
110
+ }
111
+
112
+ version_bump() {
113
+ echo "🔖 Version Bump"
114
+ current_version=$(ruby -r ./lib/human_number/version -e 'puts HumanNumber::VERSION')
115
+ echo "Current version: $current_version"
116
+ echo ""
117
+
118
+ # Get new version from user
119
+ read -p "Enter new version: " new_version
120
+
121
+ if [ -z "$new_version" ]; then
122
+ log_error "No version entered. Aborting."
123
+ fi
124
+
125
+ # Validate version format (basic semver check)
126
+ if ! echo "$new_version" | grep -qE "^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?$"; then
127
+ log_error "Invalid version format. Please use semantic versioning (e.g., 1.2.3 or 1.2.3-alpha.1)"
128
+ fi
129
+
130
+ # Check if version is different
131
+ if [ "$new_version" = "$current_version" ]; then
132
+ log_error "New version is the same as current version. Aborting."
133
+ fi
134
+
135
+ # Update version file
136
+ version_file="lib/human_number/version.rb"
137
+ sed -i.bak "s/VERSION = \".*\"/VERSION = \"$new_version\"/" "$version_file" && rm "$version_file.bak"
138
+ log_success "Updated version to $new_version"
139
+
140
+ # Create commit
141
+ log_info "Creating version bump commit..."
142
+ git add "$version_file"
143
+ commit_message="chore: bump version to $new_version"
144
+
145
+ if git commit -m "$commit_message"; then
146
+ log_success "Version bump committed successfully!"
147
+ echo ""
148
+ echo "📋 Next steps:"
149
+ echo " - Review the changes: git show"
150
+ echo " - Build and publish: $0 publish"
151
+ echo " - Push to remote: git push && git push --tags"
152
+ else
153
+ log_error "Failed to create commit"
154
+ fi
155
+ }
156
+
157
+ # Main script logic
158
+ case "${1:-help}" in
159
+ "build")
160
+ validate_all
161
+ build_gem
162
+ ;;
163
+ "publish")
164
+ validate_all
165
+ publish_gem
166
+ ;;
167
+ "build-quick")
168
+ log_info "Quick building gem (no validations)..."
169
+ build_gem
170
+ ;;
171
+ "info")
172
+ show_info
173
+ ;;
174
+ "clean")
175
+ clean_artifacts
176
+ ;;
177
+ "validate")
178
+ validate_all
179
+ ;;
180
+ "bump")
181
+ version_bump
182
+ ;;
183
+ "help"|*)
184
+ echo "HumanNumber Gem Build and Publish Script"
185
+ echo ""
186
+ echo "Usage: $0 [command]"
187
+ echo ""
188
+ echo "Commands:"
189
+ echo " build Build gem with full validations (tests, linting, git checks)"
190
+ echo " publish Publish gem to RubyGems with full validations"
191
+ echo " build-quick Build gem without validations (for testing)"
192
+ echo " validate Run all validations without building"
193
+ echo " info Show gem and repository information"
194
+ echo " clean Clean build artifacts"
195
+ echo " bump Bump version interactively and commit"
196
+ echo " help Show this help message"
197
+ echo ""
198
+ echo "Examples:"
199
+ echo " $0 build # Build gem with validations"
200
+ echo " $0 publish # Build and publish to RubyGems"
201
+ echo " $0 bump # Bump version interactively"
202
+ echo " $0 info # Show current gem info"
203
+ ;;
204
+ esac
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: human_number
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
- - Your Name
7
+ - Ether Moon
8
8
  bindir: exe
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
@@ -62,17 +62,19 @@ description: HumanNumber implements accurate number formatting based on internat
62
62
  human-readable number formats with precise locale-specific decimal separators, thousand
63
63
  separators, currency formats, and cultural number conventions.
64
64
  email:
65
- - your.email@example.com
65
+ - ethermoon42@gmail.com
66
66
  executables: []
67
67
  extensions: []
68
68
  extra_rdoc_files: []
69
69
  files:
70
70
  - ".rspec"
71
71
  - ".rubocop.yml"
72
+ - BUILD.md
72
73
  - CHANGELOG.md
73
74
  - CLAUDE.md
74
75
  - Gemfile
75
76
  - LICENSE
77
+ - Makefile
76
78
  - README.md
77
79
  - Rakefile
78
80
  - config/locales/bn.yml
@@ -89,6 +91,7 @@ files:
89
91
  - config/locales/zh-CN.yml
90
92
  - config/locales/zh-TW.yml
91
93
  - config/locales/zh.yml
94
+ - human_number.gemspec
92
95
  - lib/human_number.rb
93
96
  - lib/human_number/formatters/currency.rb
94
97
  - lib/human_number/formatters/number.rb
@@ -96,14 +99,15 @@ files:
96
99
  - lib/human_number/rails/helpers.rb
97
100
  - lib/human_number/railtie.rb
98
101
  - lib/human_number/version.rb
99
- homepage: https://github.com/yourusername/human_number
102
+ - scripts/build_and_publish.sh
103
+ homepage: https://github.com/ether-moon/human_number
100
104
  licenses:
101
105
  - MIT
102
106
  metadata:
103
107
  allowed_push_host: https://rubygems.org
104
- homepage_uri: https://github.com/yourusername/human_number
105
- source_code_uri: https://github.com/yourusername/human_number
106
- changelog_uri: https://github.com/yourusername/human_number/blob/main/CHANGELOG.md
108
+ homepage_uri: https://github.com/ether-moon/human_number
109
+ source_code_uri: https://github.com/ether-moon/human_number
110
+ changelog_uri: https://github.com/ether-moon/human_number/blob/main/CHANGELOG.md
107
111
  rubygems_mfa_required: 'true'
108
112
  rdoc_options: []
109
113
  require_paths: