normalizeurl2025 0.0.1
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 +7 -0
- data/Gemfile +7 -0
- data/README.md +278 -0
- data/Rakefile +10 -0
- data/lib/normalizeurl2025/normalizer.rb +165 -0
- data/lib/normalizeurl2025/version.rb +3 -0
- data/lib/normalizeurl2025.rb +10 -0
- data/normalizeurl2025.gemspec +30 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 074cfe360aac260e52d0aa43406d0ba34be9d0d8cb38255b2f683d8d667aac99
|
4
|
+
data.tar.gz: 5f7c9faee5ec6add114898108cd650d8aee674d1d752e3a51a48993f3dd868ce
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bdef572d7b2135a420d3e07b4fa6b4e57ac5a9b3e33dab3485d149dd2da1877bad5f15d8aac1aef6c18dbeb8a7d921eef5069e9bee6ec1f712388c4385e2277f
|
7
|
+
data.tar.gz: b9580b5c71d3ef21f5a3f08f2b65859433499a0637f8581be39175d3389a6132809ab232a514e59f29110c3043a361ed8a9572de654f0c6427589a47b2517e90
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,278 @@
|
|
1
|
+
# NormalizeURL 2025
|
2
|
+
|
3
|
+
A Ruby library for normalizing URLs by removing tracking parameters, session IDs, and other extraneous elements whilst preserving important parameters.
|
4
|
+
|
5
|
+
NormalizeURL 2025 creates a canonical representation of URLs that can be used for deduplication, caching keys, or comparison purposes and was developed initially to deduplicate URLs found in RSS feeds.
|
6
|
+
|
7
|
+
> [!IMPORTANT]
|
8
|
+
> The normalized URLs are intended for creating unique representations and may not always remain functional URLs.
|
9
|
+
|
10
|
+
> [!NOTE]
|
11
|
+
> The library has such a silly name because RubyGems refused to let me use the available name of 'normalizeurl' due to an ancient gem with a similar name. Rather than putting 'lol' or 'poo' on the end, you get 2025 instead.
|
12
|
+
|
13
|
+
**Important**:
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
For your `Gemfile`:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem 'normalizeurl2025'
|
21
|
+
```
|
22
|
+
|
23
|
+
And then execute:
|
24
|
+
|
25
|
+
$ bundle install
|
26
|
+
|
27
|
+
Or install it yourself as:
|
28
|
+
|
29
|
+
$ gem install normalizeurl2025
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
### Basic Usage
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
require 'normalizeurl2025'
|
37
|
+
|
38
|
+
# Simple normalization
|
39
|
+
url = "https://example.com/page?utm_source=google&utm_medium=cpc&id=123"
|
40
|
+
normalized = Normalizeurl2025.normalize(url)
|
41
|
+
# => "https://example.com/page?id=123"
|
42
|
+
|
43
|
+
# Remove tracking parameters whilst preserving important ones
|
44
|
+
youtube_url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ&utm_source=twitter&t=42"
|
45
|
+
normalized = Normalizeurl2025.normalize(youtube_url)
|
46
|
+
# => "https://youtube.com/watch?t=42&v=dQw4w9WgXcQ"
|
47
|
+
```
|
48
|
+
|
49
|
+
### Configuration Options
|
50
|
+
|
51
|
+
NormalizeURL 2025 accepts various options to customize the normalization behaviour:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
# Default options
|
55
|
+
options = {
|
56
|
+
remove_tracking_params: true, # Remove UTM and other tracking parameters
|
57
|
+
remove_trailing_slash: true, # Remove trailing slashes from paths
|
58
|
+
downcase_hostname: true, # Convert hostname to lowercase
|
59
|
+
remove_www: false, # Remove 'www.' prefix from hostname
|
60
|
+
remove_fragment: true, # Remove URL fragments (#section)
|
61
|
+
custom_tracking_params: [], # Additional tracking parameters to remove
|
62
|
+
preserve_params: {} # Domain-specific parameters to preserve
|
63
|
+
}
|
64
|
+
|
65
|
+
normalized = Normalizeurl2025.normalize(url, options)
|
66
|
+
```
|
67
|
+
|
68
|
+
### Examples
|
69
|
+
|
70
|
+
#### Removing Tracking Parameters
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
# UTM parameters are removed
|
74
|
+
url = "https://example.com/article?utm_source=newsletter&utm_campaign=spring2024&id=456"
|
75
|
+
Normalizeurl2025.normalize(url)
|
76
|
+
# => "https://example.com/article?id=456"
|
77
|
+
|
78
|
+
# Google Click ID and Facebook Click ID are removed
|
79
|
+
url = "https://shop.example.com/product?gclid=abc123&fbclid=def456&product_id=789"
|
80
|
+
Normalizeurl2025.normalize(url)
|
81
|
+
# => "https://shop.example.com/product?product_id=789"
|
82
|
+
|
83
|
+
# Session IDs and tracking pixels are removed
|
84
|
+
url = "https://site.com/page?PHPSESSID=abc123&_ga=GA1.2.123456&content=article"
|
85
|
+
Normalizeurl2025.normalize(url)
|
86
|
+
# => "https://site.com/page?content=article"
|
87
|
+
```
|
88
|
+
|
89
|
+
#### Preserving Important Parameters
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
# YouTube video parameters are preserved
|
93
|
+
url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ&utm_source=email&t=120&list=PLxyz"
|
94
|
+
Normalizeurl2025.normalize(url)
|
95
|
+
# => "https://youtube.com/watch?list=PLxyz&t=120&v=dQw4w9WgXcQ"
|
96
|
+
|
97
|
+
# Amazon product parameters are preserved
|
98
|
+
url = "https://amazon.com/dp/B08N5WRWNW?tag=mysite-20&utm_source=blog&keywords=ruby"
|
99
|
+
Normalizeurl2025.normalize(url)
|
100
|
+
# => "https://amazon.com/dp/B08N5WRWNW?keywords=ruby&tag=mysite-20"
|
101
|
+
|
102
|
+
# Search engine queries are preserved
|
103
|
+
url = "https://google.com/search?q=ruby+gems&utm_source=referral&hl=en"
|
104
|
+
Normalizeurl2025.normalize(url)
|
105
|
+
# => "https://google.com/search?q=ruby+gems"
|
106
|
+
```
|
107
|
+
|
108
|
+
#### URL Structure Normalization
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
# Hostname is lowercased and www is optionally removed
|
112
|
+
url = "HTTPS://WWW.EXAMPLE.COM/Path/?utm_source=email"
|
113
|
+
Normalizeurl2025.normalize(url)
|
114
|
+
# => "https://www.example.com/Path"
|
115
|
+
|
116
|
+
# Remove www prefix
|
117
|
+
url = "https://www.example.com/page?id=123"
|
118
|
+
Normalizeurl2025.normalize(url, remove_www: true)
|
119
|
+
# => "https://example.com/page?id=123"
|
120
|
+
|
121
|
+
# Trailing slashes are removed (except root)
|
122
|
+
url = "https://example.com/path/to/page/?utm_medium=social"
|
123
|
+
Normalizeurl2025.normalize(url)
|
124
|
+
# => "https://example.com/path/to/page?utm_medium=social"
|
125
|
+
|
126
|
+
# Fragments are removed by default
|
127
|
+
url = "https://example.com/page#section?utm_source=twitter"
|
128
|
+
Normalizeurl2025.normalize(url)
|
129
|
+
# => "https://example.com/page"
|
130
|
+
|
131
|
+
# Keep fragments if needed
|
132
|
+
url = "https://example.com/page#section?utm_source=twitter"
|
133
|
+
Normalizeurl2025.normalize(url, remove_fragment: false)
|
134
|
+
# => "https://example.com/page#section"
|
135
|
+
```
|
136
|
+
|
137
|
+
#### Query Parameter Sorting
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
# Parameters are sorted alphabetically for consistency
|
141
|
+
url = "https://example.com/search?z=last&a=first&m=middle&utm_source=email"
|
142
|
+
Normalizeurl2025.normalize(url)
|
143
|
+
# => "https://example.com/search?a=first&m=middle&z=last"
|
144
|
+
```
|
145
|
+
|
146
|
+
#### Custom Configuration
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
# Add custom tracking parameters to remove
|
150
|
+
options = {
|
151
|
+
custom_tracking_params: ['my_tracker', 'internal_ref', 'campaign_id']
|
152
|
+
}
|
153
|
+
url = "https://example.com/page?my_tracker=abc&internal_ref=xyz&id=123&campaign_id=spring"
|
154
|
+
Normalizeurl2025.normalize(url, options)
|
155
|
+
# => "https://example.com/page?id=123"
|
156
|
+
|
157
|
+
# Preserve custom parameters for specific domains
|
158
|
+
options = {
|
159
|
+
preserve_params: {
|
160
|
+
'mysite.com' => ['special_param', 'user_pref'],
|
161
|
+
'shop.example.com' => ['affiliate_id', 'discount_code']
|
162
|
+
}
|
163
|
+
}
|
164
|
+
url = "https://mysite.com/page?special_param=value&utm_source=email&user_pref=dark"
|
165
|
+
Normalizeurl2025.normalize(url, options)
|
166
|
+
# => "https://mysite.com/page?special_param=value&user_pref=dark"
|
167
|
+
|
168
|
+
# Subdomain matching works automatically
|
169
|
+
url = "https://blog.mysite.com/post?special_param=test&utm_campaign=launch"
|
170
|
+
Normalizeurl2025.normalize(url, options)
|
171
|
+
# => "https://blog.mysite.com/post?special_param=test"
|
172
|
+
```
|
173
|
+
|
174
|
+
#### Error Handling
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
# Invalid URLs are returned unchanged
|
178
|
+
Normalizeurl2025.normalize("not-a-url")
|
179
|
+
# => "not-a-url"
|
180
|
+
|
181
|
+
# Nil and empty strings return nil
|
182
|
+
Normalizeurl2025.normalize(nil)
|
183
|
+
# => nil
|
184
|
+
```
|
185
|
+
|
186
|
+
## Default Behaviour
|
187
|
+
|
188
|
+
### Tracking Parameters Removed
|
189
|
+
|
190
|
+
NormalizeURL 2025 removes these common tracking parameters by default:
|
191
|
+
|
192
|
+
**UTM Parameters:**
|
193
|
+
- `utm_source`, `utm_medium`, `utm_campaign`, `utm_term`, `utm_content`
|
194
|
+
- `utm_name`, `utm_cid`, `utm_reader`, `utm_viz_id`, `utm_pubreferrer`, `utm_swu`
|
195
|
+
|
196
|
+
**Click IDs:**
|
197
|
+
- `gclid` (Google Ads), `fbclid` (Facebook), `msclkid` (Microsoft Advertising)
|
198
|
+
- `yclid` (Yandex), `rb_clickid` (Rakuten)
|
199
|
+
|
200
|
+
**Analytics & Tracking:**
|
201
|
+
- `_ga`, `_gl` (Google Analytics)
|
202
|
+
- `mc_cid`, `mc_eid` (Mailchimp)
|
203
|
+
- `s_cid` (Adobe Analytics)
|
204
|
+
- `_openstat` (OpenStat)
|
205
|
+
- `ck_subscriber_id` (Kit / ConvertKit)
|
206
|
+
|
207
|
+
**Session & User IDs:**
|
208
|
+
- `PHPSESSID`, `JSESSIONID`, `ASPSESSIONID`
|
209
|
+
- `sid`, `sessionid`, `session_id`
|
210
|
+
- `subscriber_id`, `ig_rid` (Instagram)
|
211
|
+
- `oly_anon_id`, `oly_enc_id` (Optimizely)
|
212
|
+
- `wickedid`, `vero_conv`, `vero_id`
|
213
|
+
|
214
|
+
**Referrer & Source Tracking:**
|
215
|
+
- `ref`, `referer`, `referrer`, `source`, `src`
|
216
|
+
- `campaign`, `__s`
|
217
|
+
|
218
|
+
### Parameters Preserved by Domain
|
219
|
+
|
220
|
+
Certain parameters are automatically preserved for specific domains:
|
221
|
+
|
222
|
+
- **YouTube** (`youtube.com`, `youtu.be`): `v` (video ID), `t` (timestamp), `list` (playlist), `index`
|
223
|
+
- **Amazon** (`amazon.com`, `amazon.co.uk`): `keywords`, `tag`
|
224
|
+
- **eBay** (`ebay.com`, `ebay.co.uk`): `hash`
|
225
|
+
- **Google** (`google.com`, `google.co.uk`): `q` (search query)
|
226
|
+
- **Bing** (`bing.com`): `q` (search query)
|
227
|
+
- **DuckDuckGo** (`duckduckgo.com`): `q` (search query)
|
228
|
+
- **Stack Overflow** (`stackoverflow.com`): `answertab`
|
229
|
+
- **Vimeo** (`vimeo.com`): `h_original`
|
230
|
+
|
231
|
+
### URL Transformations
|
232
|
+
|
233
|
+
1. **Scheme**: Converted to lowercase (`HTTP` → `http`)
|
234
|
+
2. **Hostname**: Converted to lowercase (`Example.COM` → `example.com`)
|
235
|
+
3. **WWW prefix**: Optionally removed (`www.example.com` → `example.com`)
|
236
|
+
4. **Path**:
|
237
|
+
- Trailing slashes removed (except root path)
|
238
|
+
- Empty paths become `/`
|
239
|
+
5. **Query parameters**:
|
240
|
+
- Tracking parameters filtered out
|
241
|
+
- Remaining parameters sorted alphabetically
|
242
|
+
- Empty query strings removed entirely
|
243
|
+
6. **Fragments**: Removed by default (`#section` removed)
|
244
|
+
|
245
|
+
## Advanced Usage
|
246
|
+
|
247
|
+
### Batch Processing
|
248
|
+
|
249
|
+
```ruby
|
250
|
+
urls = [
|
251
|
+
"https://example.com/page1?utm_source=email",
|
252
|
+
"https://example.com/page2?gclid=abc123",
|
253
|
+
"https://example.com/page3?fbclid=def456"
|
254
|
+
]
|
255
|
+
|
256
|
+
normalized_urls = urls.map { |url| Normalizeurl2025.normalize(url) }
|
257
|
+
# => ["https://example.com/page1", "https://example.com/page2", "https://example.com/page3"]
|
258
|
+
```
|
259
|
+
|
260
|
+
### Creating Consistent Cache Keys
|
261
|
+
|
262
|
+
```ruby
|
263
|
+
def cache_key_for_url(url)
|
264
|
+
normalized = Normalizeurl2025.normalize(url)
|
265
|
+
Digest::MD5.hexdigest(normalized)
|
266
|
+
end
|
267
|
+
|
268
|
+
cache_key_for_url("https://example.com/article?utm_source=twitter&id=123")
|
269
|
+
# => "a1b2c3d4e5f6..." (consistent hash regardless of tracking params)
|
270
|
+
```
|
271
|
+
|
272
|
+
## Contributing
|
273
|
+
|
274
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/peterc/normalizeurl2025.
|
275
|
+
|
276
|
+
## Licence
|
277
|
+
|
278
|
+
The gem is available as open source under the terms of the [MIT Licence](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
3
|
+
module Normalizeurl2025
|
4
|
+
class Normalizer
|
5
|
+
# Parameters that are commonly used for tracking and should be removed
|
6
|
+
DEFAULT_TRACKING_PARAMS = %w[
|
7
|
+
utm_source utm_medium utm_campaign utm_term utm_content
|
8
|
+
utm_name utm_cid utm_reader utm_viz_id utm_pubreferrer utm_swu
|
9
|
+
gclid fbclid msclkid
|
10
|
+
ck_subscriber_id
|
11
|
+
ck_subscriber
|
12
|
+
_ga _gl
|
13
|
+
mc_cid mc_eid
|
14
|
+
PHPSESSID JSESSIONID ASPSESSIONID
|
15
|
+
sid sessionid session_id
|
16
|
+
ref referer referrer
|
17
|
+
source src
|
18
|
+
campaign
|
19
|
+
yclid
|
20
|
+
_openstat
|
21
|
+
rb_clickid
|
22
|
+
s_cid
|
23
|
+
vero_conv vero_id
|
24
|
+
wickedid
|
25
|
+
oly_anon_id oly_enc_id
|
26
|
+
__s
|
27
|
+
subscriber_id
|
28
|
+
ig_rid
|
29
|
+
].freeze
|
30
|
+
|
31
|
+
# Parameters that should be preserved for certain domains
|
32
|
+
PRESERVE_PARAMS = {
|
33
|
+
'youtube.com' => %w[v t list index],
|
34
|
+
'youtu.be' => %w[v t],
|
35
|
+
'vimeo.com' => %w[h_original],
|
36
|
+
'amazon.com' => %w[keywords tag],
|
37
|
+
'amazon.co.uk' => %w[keywords tag],
|
38
|
+
'ebay.com' => %w[hash],
|
39
|
+
'ebay.co.uk' => %w[hash],
|
40
|
+
'stackoverflow.com' => %w[answertab],
|
41
|
+
'google.com' => %w[q],
|
42
|
+
'google.co.uk' => %w[q],
|
43
|
+
'bing.com' => %w[q],
|
44
|
+
'duckduckgo.com' => %w[q]
|
45
|
+
}.freeze
|
46
|
+
|
47
|
+
def initialize(options = {})
|
48
|
+
@remove_tracking_params = options.fetch(:remove_tracking_params, true)
|
49
|
+
@remove_trailing_slash = options.fetch(:remove_trailing_slash, true)
|
50
|
+
@downcase_hostname = options.fetch(:downcase_hostname, true)
|
51
|
+
@remove_www = options.fetch(:remove_www, false)
|
52
|
+
@remove_fragment = options.fetch(:remove_fragment, true)
|
53
|
+
@custom_tracking_params = options.fetch(:custom_tracking_params, [])
|
54
|
+
@preserve_params = options.fetch(:preserve_params, {})
|
55
|
+
end
|
56
|
+
|
57
|
+
def normalize(url)
|
58
|
+
return nil if url.nil? || url.strip.empty?
|
59
|
+
|
60
|
+
begin
|
61
|
+
uri = URI.parse(url.strip)
|
62
|
+
rescue URI::InvalidURIError
|
63
|
+
return url
|
64
|
+
end
|
65
|
+
|
66
|
+
# Only process HTTP/HTTPS URLs
|
67
|
+
return url unless %w[http https].include?(uri.scheme&.downcase)
|
68
|
+
|
69
|
+
normalize_scheme!(uri)
|
70
|
+
normalize_hostname!(uri)
|
71
|
+
normalize_path!(uri)
|
72
|
+
normalize_query!(uri)
|
73
|
+
normalize_fragment!(uri)
|
74
|
+
|
75
|
+
uri.to_s
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def normalize_scheme!(uri)
|
81
|
+
uri.scheme = uri.scheme.downcase if uri.scheme
|
82
|
+
end
|
83
|
+
|
84
|
+
def normalize_hostname!(uri)
|
85
|
+
return unless uri.host
|
86
|
+
|
87
|
+
if @downcase_hostname
|
88
|
+
uri.host = uri.host.downcase
|
89
|
+
end
|
90
|
+
|
91
|
+
if @remove_www && uri.host.start_with?('www.')
|
92
|
+
uri.host = uri.host[4..-1]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def normalize_path!(uri)
|
97
|
+
return unless uri.path
|
98
|
+
|
99
|
+
# Remove trailing slash unless it's the root path
|
100
|
+
if @remove_trailing_slash && uri.path != '/' && uri.path.end_with?('/')
|
101
|
+
uri.path = uri.path.chomp('/')
|
102
|
+
end
|
103
|
+
|
104
|
+
# Ensure root path is present
|
105
|
+
uri.path = '/' if uri.path.empty?
|
106
|
+
end
|
107
|
+
|
108
|
+
def normalize_query!(uri)
|
109
|
+
return unless uri.query && @remove_tracking_params
|
110
|
+
|
111
|
+
params = URI.decode_www_form(uri.query)
|
112
|
+
|
113
|
+
# Get domain-specific parameters to preserve
|
114
|
+
domain_preserve_params = get_preserve_params_for_domain(uri.host)
|
115
|
+
|
116
|
+
# Filter out tracking parameters
|
117
|
+
filtered_params = params.reject do |key, _value|
|
118
|
+
should_remove_param?(key, domain_preserve_params)
|
119
|
+
end
|
120
|
+
|
121
|
+
if filtered_params.empty?
|
122
|
+
uri.query = nil
|
123
|
+
else
|
124
|
+
# Sort parameters for consistency
|
125
|
+
uri.query = URI.encode_www_form(filtered_params.sort)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def normalize_fragment!(uri)
|
130
|
+
uri.fragment = nil if @remove_fragment
|
131
|
+
end
|
132
|
+
|
133
|
+
def get_preserve_params_for_domain(host)
|
134
|
+
return [] unless host
|
135
|
+
|
136
|
+
# Check for exact domain match first
|
137
|
+
preserved = PRESERVE_PARAMS[host] || []
|
138
|
+
|
139
|
+
# Check for subdomain matches
|
140
|
+
PRESERVE_PARAMS.each do |domain, params|
|
141
|
+
if host.end_with?(".#{domain}")
|
142
|
+
preserved.concat(params)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Add custom preserve params for this domain
|
147
|
+
if @preserve_params[host]
|
148
|
+
preserved.concat(@preserve_params[host])
|
149
|
+
end
|
150
|
+
|
151
|
+
preserved.uniq
|
152
|
+
end
|
153
|
+
|
154
|
+
def should_remove_param?(param_name, preserve_params)
|
155
|
+
param_lower = param_name.downcase
|
156
|
+
|
157
|
+
# Don't remove if it's in the preserve list
|
158
|
+
return false if preserve_params.any? { |p| p.downcase == param_lower }
|
159
|
+
|
160
|
+
# Remove if it's a tracking parameter
|
161
|
+
tracking_params = DEFAULT_TRACKING_PARAMS + @custom_tracking_params
|
162
|
+
tracking_params.any? { |tp| tp.downcase == param_lower }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative "lib/normalizeurl2025/version"
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "normalizeurl2025"
|
5
|
+
spec.version = Normalizeurl2025::VERSION
|
6
|
+
spec.authors = ["Peter Cooper"]
|
7
|
+
spec.email = ["git@peterc.org"]
|
8
|
+
|
9
|
+
spec.summary = "A Ruby library for normalizing URLs"
|
10
|
+
spec.description = "Normalizes URLs by removing tracking parameters, session IDs, and other extraneous elements whilst preserving important parameters"
|
11
|
+
spec.homepage = "https://github.com/peterc/normalizeurl2025"
|
12
|
+
spec.license = "MIT"
|
13
|
+
spec.required_ruby_version = ">= 3.0.0"
|
14
|
+
|
15
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
16
|
+
spec.metadata["source_code_uri"] = "https://github.com/peterc/normalizeurl2025"
|
17
|
+
|
18
|
+
# Specify which files should be added to the gem when it is released.
|
19
|
+
spec.files = Dir.chdir(__dir__) do
|
20
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
21
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
spec.bindir = "exe"
|
25
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
26
|
+
spec.require_paths = ["lib"]
|
27
|
+
|
28
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
29
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: normalizeurl2025
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Peter Cooper
|
8
|
+
bindir: exe
|
9
|
+
cert_chain: []
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: minitest
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '5.0'
|
19
|
+
type: :development
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '5.0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rake
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '13.0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '13.0'
|
40
|
+
description: Normalizes URLs by removing tracking parameters, session IDs, and other
|
41
|
+
extraneous elements whilst preserving important parameters
|
42
|
+
email:
|
43
|
+
- git@peterc.org
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- Gemfile
|
49
|
+
- README.md
|
50
|
+
- Rakefile
|
51
|
+
- lib/normalizeurl2025.rb
|
52
|
+
- lib/normalizeurl2025/normalizer.rb
|
53
|
+
- lib/normalizeurl2025/version.rb
|
54
|
+
- normalizeurl2025.gemspec
|
55
|
+
homepage: https://github.com/peterc/normalizeurl2025
|
56
|
+
licenses:
|
57
|
+
- MIT
|
58
|
+
metadata:
|
59
|
+
homepage_uri: https://github.com/peterc/normalizeurl2025
|
60
|
+
source_code_uri: https://github.com/peterc/normalizeurl2025
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.0.0
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
requirements: []
|
75
|
+
rubygems_version: 3.6.7
|
76
|
+
specification_version: 4
|
77
|
+
summary: A Ruby library for normalizing URLs
|
78
|
+
test_files: []
|