apt-spy2 0.7.2 → 0.8.0
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 +4 -4
- data/.github/workflows/codeql-analysis.yml +70 -0
- data/.github/workflows/pr.yml +19 -4
- data/.github/workflows/release.yml +22 -0
- data/Dockerfile +9 -5
- data/Gemfile +2 -0
- data/Gemfile.lock +30 -6
- data/Makefile +21 -3
- data/README.md +9 -2
- data/Rakefile +10 -17
- data/apt-spy2.gemspec +22 -17
- data/bin/apt-spy2 +3 -2
- data/lib/apt/spy2/country.rb +8 -9
- data/lib/apt/spy2/downloader.rb +14 -17
- data/lib/apt/spy2/launchpad.rb +5 -6
- data/lib/apt/spy2/request.rb +30 -0
- data/lib/apt/spy2/ubuntu_mirrors.rb +5 -7
- data/lib/apt/spy2/url.rb +28 -0
- data/lib/apt/spy2/version.rb +3 -1
- data/lib/apt/spy2/writer.rb +17 -20
- data/lib/apt/spy2.rb +70 -61
- data/test_helper.rb +30 -0
- data/tests/country_test.rb +7 -5
- data/tests/downloader_test.rb +18 -0
- data/tests/launchpad_test.rb +7 -3
- data/tests/ubuntu_mirrors_test.rb +15 -0
- data/tests/url_test.rb +23 -0
- data/tests/writer_test.rb +27 -0
- metadata +49 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 456003f4c6ac4e210a1cd7ebe44888b8a58d3b9fac87d1b68f03e9b3d8c45bdf
|
4
|
+
data.tar.gz: 907656e6cf49fe081152826de58348ff75d3f2ff1014f5af854dfb24f86e421d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a2c12f506751914dc44243f88ecef036e7a5ca41cab0f6595c70e4c61d7d68e3da6cc304f9879a8b4f8b36fd2daa96b664a8fd91cf5a5a9cf64a06c2723cd10
|
7
|
+
data.tar.gz: '0815dfcb1e3b857aac1a30a8d0cee549e3c4a8a95ee0213e227b6747bb88939813118fbbaffc3d44ed1de663963c2ab22d7a7f03f552d4cbcd2e744183461fcb'
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# For most projects, this workflow file will not need changing; you simply need
|
2
|
+
# to commit it to your repository.
|
3
|
+
#
|
4
|
+
# You may wish to alter this file to override the set of languages analyzed,
|
5
|
+
# or to provide custom queries or build logic.
|
6
|
+
#
|
7
|
+
# ******** NOTE ********
|
8
|
+
# We have attempted to detect the languages in your repository. Please check
|
9
|
+
# the `language` matrix defined below to confirm you have the correct set of
|
10
|
+
# supported CodeQL languages.
|
11
|
+
#
|
12
|
+
name: "CodeQL"
|
13
|
+
|
14
|
+
on:
|
15
|
+
push:
|
16
|
+
branches: [ master ]
|
17
|
+
pull_request:
|
18
|
+
# The branches below must be a subset of the branches above
|
19
|
+
branches: [ master ]
|
20
|
+
schedule:
|
21
|
+
- cron: '43 11 * * 5'
|
22
|
+
|
23
|
+
jobs:
|
24
|
+
analyze:
|
25
|
+
name: Analyze
|
26
|
+
runs-on: ubuntu-latest
|
27
|
+
permissions:
|
28
|
+
actions: read
|
29
|
+
contents: read
|
30
|
+
security-events: write
|
31
|
+
|
32
|
+
strategy:
|
33
|
+
fail-fast: false
|
34
|
+
matrix:
|
35
|
+
language: [ 'ruby' ]
|
36
|
+
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
37
|
+
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
38
|
+
|
39
|
+
steps:
|
40
|
+
- name: Checkout repository
|
41
|
+
uses: actions/checkout@v2
|
42
|
+
|
43
|
+
# Initializes the CodeQL tools for scanning.
|
44
|
+
- name: Initialize CodeQL
|
45
|
+
uses: github/codeql-action/init@v1
|
46
|
+
with:
|
47
|
+
languages: ${{ matrix.language }}
|
48
|
+
# If you wish to specify custom queries, you can do so here or in a config file.
|
49
|
+
# By default, queries listed here will override any specified in a config file.
|
50
|
+
# Prefix the list here with "+" to use these queries and those in the config file.
|
51
|
+
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
52
|
+
|
53
|
+
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
54
|
+
# If this step fails, then you should remove it and run the build manually (see below)
|
55
|
+
- name: Autobuild
|
56
|
+
uses: github/codeql-action/autobuild@v1
|
57
|
+
|
58
|
+
# ℹ️ Command-line programs to run using the OS shell.
|
59
|
+
# 📚 https://git.io/JvXDl
|
60
|
+
|
61
|
+
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
62
|
+
# and modify them (or add more) to build your code if your project
|
63
|
+
# uses a compiled language
|
64
|
+
|
65
|
+
#- run: |
|
66
|
+
# make bootstrap
|
67
|
+
# make release
|
68
|
+
|
69
|
+
- name: Perform CodeQL Analysis
|
70
|
+
uses: github/codeql-action/analyze@v1
|
data/.github/workflows/pr.yml
CHANGED
@@ -11,11 +11,12 @@ jobs:
|
|
11
11
|
strategy:
|
12
12
|
matrix:
|
13
13
|
ruby-version:
|
14
|
+
- '3.2'
|
15
|
+
- '3.1'
|
14
16
|
- '3.0'
|
15
|
-
- 2.7
|
16
|
-
- 2.6
|
17
|
+
- '2.7'
|
17
18
|
steps:
|
18
|
-
- uses: actions/checkout@
|
19
|
+
- uses: actions/checkout@v3
|
19
20
|
- uses: ruby/setup-ruby@v1
|
20
21
|
with:
|
21
22
|
ruby-version: ${{ matrix.ruby-version }}
|
@@ -24,9 +25,23 @@ jobs:
|
|
24
25
|
- run: bundle exec rake build
|
25
26
|
- run: ls -lah ./pkg/apt-spy2*
|
26
27
|
- run: gem install pkg/apt-spy2*
|
27
|
-
- run: apt-spy2
|
28
|
+
- run: apt-spy2 check
|
28
29
|
- uses: coverallsapp/github-action@master
|
29
30
|
with:
|
30
31
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
31
32
|
|
33
|
+
test_strict:
|
34
|
+
runs-on: ubuntu-latest
|
35
|
+
steps:
|
36
|
+
- uses: actions/checkout@v3
|
37
|
+
- uses: ruby/setup-ruby@v1
|
38
|
+
with:
|
39
|
+
ruby-version: 3.2
|
40
|
+
- run: bundle install
|
41
|
+
- run: bundle exec rake test
|
42
|
+
- run: bundle exec rake build
|
43
|
+
- run: ls -lah ./pkg/apt-spy2*
|
44
|
+
- run: gem install pkg/apt-spy2*
|
45
|
+
- run: apt-spy2 check --strict
|
46
|
+
|
32
47
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
---
|
2
|
+
name: release
|
3
|
+
|
4
|
+
on:
|
5
|
+
push:
|
6
|
+
tags:
|
7
|
+
- 'v*'
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
publish:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
steps:
|
13
|
+
- uses: actions/checkout@v2
|
14
|
+
- uses: ruby/setup-ruby@v1
|
15
|
+
with:
|
16
|
+
ruby-version: 3.0
|
17
|
+
- run: bundle install
|
18
|
+
- uses: cadwallion/publish-rubygems-action@master
|
19
|
+
env:
|
20
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
21
|
+
RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
|
22
|
+
RELEASE_COMMAND: bundle exec rake release
|
data/Dockerfile
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
-
FROM ubuntu:
|
1
|
+
FROM ubuntu:22.10
|
2
2
|
|
3
|
-
RUN apt
|
4
|
-
&& apt
|
5
|
-
|
6
|
-
|
3
|
+
RUN apt update -y \
|
4
|
+
&& apt install -y \
|
5
|
+
ruby3.0 \
|
6
|
+
ruby-dev \
|
7
|
+
ruby-bundler \
|
8
|
+
git \
|
9
|
+
lsb-release \
|
10
|
+
build-essential
|
7
11
|
|
8
12
|
WORKDIR /work
|
9
13
|
COPY . /work
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,23 +1,45 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
apt-spy2 (0.
|
4
|
+
apt-spy2 (0.8.0)
|
5
5
|
colored (>= 1.2)
|
6
6
|
json
|
7
|
-
nokogiri (
|
7
|
+
nokogiri (~> 1.14.1)
|
8
8
|
thor (>= 0.18.1)
|
9
9
|
|
10
10
|
GEM
|
11
11
|
remote: https://rubygems.org/
|
12
12
|
specs:
|
13
|
+
ast (2.4.2)
|
13
14
|
colored (1.2)
|
14
15
|
docile (1.4.0)
|
15
|
-
json (2.6.
|
16
|
+
json (2.6.3)
|
17
|
+
mini_portile2 (2.8.1)
|
16
18
|
minitest (5.15.0)
|
17
|
-
nokogiri (1.
|
19
|
+
nokogiri (1.14.1)
|
20
|
+
mini_portile2 (~> 2.8.0)
|
18
21
|
racc (~> 1.4)
|
19
|
-
|
22
|
+
parallel (1.22.1)
|
23
|
+
parser (3.2.1.0)
|
24
|
+
ast (~> 2.4.1)
|
25
|
+
racc (1.6.2)
|
26
|
+
rainbow (3.1.1)
|
20
27
|
rake (13.0.6)
|
28
|
+
regexp_parser (2.7.0)
|
29
|
+
rexml (3.2.5)
|
30
|
+
rubocop (1.45.1)
|
31
|
+
json (~> 2.3)
|
32
|
+
parallel (~> 1.10)
|
33
|
+
parser (>= 3.2.0.0)
|
34
|
+
rainbow (>= 2.2.2, < 4.0)
|
35
|
+
regexp_parser (>= 1.8, < 3.0)
|
36
|
+
rexml (>= 3.2.5, < 4.0)
|
37
|
+
rubocop-ast (>= 1.24.1, < 2.0)
|
38
|
+
ruby-progressbar (~> 1.7)
|
39
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
40
|
+
rubocop-ast (1.24.1)
|
41
|
+
parser (>= 3.1.1.0)
|
42
|
+
ruby-progressbar (1.11.0)
|
21
43
|
simplecov (0.21.2)
|
22
44
|
docile (~> 1.1)
|
23
45
|
simplecov-html (~> 0.11)
|
@@ -25,7 +47,8 @@ GEM
|
|
25
47
|
simplecov-html (0.12.3)
|
26
48
|
simplecov-lcov (0.8.0)
|
27
49
|
simplecov_json_formatter (0.1.3)
|
28
|
-
thor (1.1
|
50
|
+
thor (1.2.1)
|
51
|
+
unicode-display_width (2.4.2)
|
29
52
|
|
30
53
|
PLATFORMS
|
31
54
|
ruby
|
@@ -35,6 +58,7 @@ DEPENDENCIES
|
|
35
58
|
bundler (~> 2.0)
|
36
59
|
minitest (~> 5.15.0)
|
37
60
|
rake
|
61
|
+
rubocop
|
38
62
|
simplecov (~> 0.18)
|
39
63
|
simplecov-lcov (~> 0.8.0)
|
40
64
|
|
data/Makefile
CHANGED
@@ -1,11 +1,29 @@
|
|
1
|
+
.PHONY: clean install release docker-build docker-run
|
2
|
+
|
3
|
+
IMAGE?=lagged/apt-spy2:dev
|
4
|
+
|
5
|
+
container:=apt-spy2
|
6
|
+
|
7
|
+
clean:
|
8
|
+
docker rm -f $(container) || true
|
9
|
+
|
1
10
|
install:
|
2
11
|
bundle install --path ./vendor/bundle
|
3
12
|
|
4
13
|
release:
|
5
14
|
bundle exec rake release
|
6
15
|
|
16
|
+
lint:
|
17
|
+
bundle exec rubocop .
|
18
|
+
|
19
|
+
test: install
|
20
|
+
bundle exec rake test
|
21
|
+
|
7
22
|
docker-build:
|
8
|
-
docker build -t
|
23
|
+
docker build -t $(IMAGE) .
|
9
24
|
|
10
|
-
docker-run: docker-build
|
11
|
-
docker run -it
|
25
|
+
docker-run: clean docker-build
|
26
|
+
docker run --rm -it \
|
27
|
+
--name $(container) \
|
28
|
+
-v $(CURDIR):/work \
|
29
|
+
$(IMAGE) bash
|
data/README.md
CHANGED
@@ -44,13 +44,14 @@ $ apt-spy2 list --launchpad --country=Germany
|
|
44
44
|
|
45
45
|
### check command
|
46
46
|
|
47
|
-
`check` works like `list`, but also determines if the servers returned are working. It supports
|
47
|
+
`check` works like `list`, but also determines if the servers returned are working. It supports the flag `--launchpad` as well and additionally a flag `--strict` which checks if a mirror carries a certain release and distribution.
|
48
48
|
|
49
49
|
```
|
50
50
|
$ apt-spy2 check
|
51
51
|
...
|
52
|
-
$ apt-spy2
|
52
|
+
$ apt-spy2 check --launchpad --country=US
|
53
53
|
...
|
54
|
+
$ apt-spy2 check --strict
|
54
55
|
```
|
55
56
|
|
56
57
|
### fix command
|
@@ -81,3 +82,9 @@ Generally, `apt-spy2` plays especially nice in a non-interactive environment and
|
|
81
82
|
## License
|
82
83
|
|
83
84
|
[New BSD License](http://opensource.org/licenses/BSD-2-Clause)
|
85
|
+
|
86
|
+
### Release (procedure)
|
87
|
+
|
88
|
+
- update version in `lib/apt/spy2/version.rb`
|
89
|
+
- `bundle install`
|
90
|
+
- `git commit -a -m 'New release' && git tag -a vVERSION && git push --tags`
|
data/Rakefile
CHANGED
@@ -1,24 +1,17 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rake/testtask'
|
5
5
|
|
6
6
|
Encoding.default_external = Encoding::UTF_8
|
7
7
|
Encoding.default_internal = Encoding::UTF_8
|
8
8
|
|
9
|
-
|
9
|
+
Rake::TestTask.new do |t|
|
10
10
|
ENV['COVERAGE'] = 'true'
|
11
|
+
t.pattern = 'tests/*_test.rb'
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
c.single_report_path = './coverage/lcov.info'
|
17
|
-
end
|
18
|
-
SimpleCov.start
|
19
|
-
|
20
|
-
$LOAD_PATH.unshift('lib', 'tests')
|
21
|
-
Dir.glob('./tests/*_test.rb') do |f|
|
22
|
-
require f
|
23
|
-
end
|
13
|
+
# $LOAD_PATH.unshift('lib', 'tests')
|
14
|
+
# Dir.glob('./tests/*_test.rb').sort.each do |f|
|
15
|
+
# require f
|
16
|
+
# end
|
24
17
|
end
|
data/apt-spy2.gemspec
CHANGED
@@ -1,31 +1,36 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# require 'English'
|
4
|
+
lib = File.expand_path('lib', __dir__)
|
3
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
6
|
require 'apt/spy2/version'
|
5
7
|
|
6
8
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
9
|
+
spec.name = 'apt-spy2'
|
8
10
|
spec.version = Apt::Spy2::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.description =
|
12
|
-
spec.summary =
|
13
|
-
spec.homepage =
|
11
|
+
spec.authors = ['till']
|
12
|
+
spec.email = ['till@php.net']
|
13
|
+
spec.description = 'Keep your /etc/apt/sources.list up to date'
|
14
|
+
spec.summary = 'apt-spy2, or apt-spy for ubuntu'
|
15
|
+
spec.homepage = 'https://github.com/lagged/apt-spy2'
|
14
16
|
spec.license = 'BSD-2-Clause'
|
15
17
|
|
16
|
-
spec.
|
18
|
+
spec.required_ruby_version = '>= 2.7', '< 3.3'
|
19
|
+
|
20
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
17
21
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
22
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
23
|
+
spec.require_paths = ['lib']
|
20
24
|
|
21
|
-
spec.add_dependency 'thor', '>= 0.18.1'
|
22
25
|
spec.add_dependency 'colored', '>= 1.2'
|
23
26
|
spec.add_dependency 'json'
|
24
|
-
spec.add_dependency 'nokogiri', '
|
27
|
+
spec.add_dependency 'nokogiri', '~> 1.14.1'
|
28
|
+
spec.add_dependency 'thor', '>= 0.18.1'
|
25
29
|
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
30
|
-
spec.add_development_dependency
|
30
|
+
spec.add_development_dependency 'bundler', '~> 2.0'
|
31
|
+
spec.add_development_dependency 'minitest', '~> 5.15.0'
|
32
|
+
spec.add_development_dependency 'rake'
|
33
|
+
spec.add_development_dependency 'rubocop'
|
34
|
+
spec.add_development_dependency 'simplecov', '~> 0.18'
|
35
|
+
spec.add_development_dependency 'simplecov-lcov', '~> 0.8.0'
|
31
36
|
end
|
data/bin/apt-spy2
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'apt/spy2'
|
4
5
|
require 'colored'
|
@@ -8,7 +9,7 @@ Encoding.default_internal = Encoding::UTF_8
|
|
8
9
|
|
9
10
|
begin
|
10
11
|
AptSpy2.start
|
11
|
-
rescue =>
|
12
|
-
puts
|
12
|
+
rescue StandardError => e
|
13
|
+
puts e.to_s.white_on_red
|
13
14
|
exit 1
|
14
15
|
end
|
data/lib/apt/spy2/country.rb
CHANGED
@@ -1,33 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Apt
|
2
4
|
module Spy2
|
5
|
+
# lookup a country based on code
|
3
6
|
class Country
|
4
|
-
|
5
7
|
def initialize(country_database)
|
6
8
|
@database = country_database
|
7
9
|
end
|
8
10
|
|
9
11
|
def to_country_name(code)
|
10
12
|
code = code.upcase
|
11
|
-
return capitalize(code) unless code.length == 2
|
13
|
+
return capitalize!(code) unless code.length == 2
|
12
14
|
|
13
15
|
File.open(@database).each do |line|
|
14
16
|
country, tld = line.split(';', 2)
|
15
17
|
tld.gsub!(/\n/, '')
|
16
18
|
|
17
|
-
if code == tld
|
18
|
-
return capitalize(country)
|
19
|
-
end
|
20
|
-
|
19
|
+
return capitalize!(country) if code == tld
|
21
20
|
end
|
22
21
|
|
23
22
|
raise "Could not look up: #{code}"
|
24
23
|
end
|
25
24
|
|
26
25
|
private
|
27
|
-
def capitalize(str)
|
28
|
-
return str.split(" ").map(&:capitalize).join(" ")
|
29
|
-
end
|
30
26
|
|
27
|
+
def capitalize!(str)
|
28
|
+
str.split(' ').map(&:capitalize).join(' ')
|
29
|
+
end
|
31
30
|
end
|
32
31
|
end
|
33
32
|
end
|
data/lib/apt/spy2/downloader.rb
CHANGED
@@ -1,30 +1,27 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'apt/spy2/request'
|
2
4
|
|
3
5
|
module Apt
|
4
6
|
module Spy2
|
7
|
+
# download url (e.g. mirror list or launchpad page)
|
5
8
|
class Downloader
|
6
|
-
|
7
|
-
def initialize(url = nil)
|
8
|
-
@url = url if !url.nil?
|
9
|
-
end
|
10
|
-
|
11
9
|
def do_download(url = nil)
|
12
|
-
|
10
|
+
raise 'Please supply a url.' if url.nil?
|
13
11
|
|
14
|
-
|
12
|
+
req = Apt::Spy2::Request.new(url)
|
15
13
|
|
16
14
|
begin
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
15
|
+
response = req.get
|
16
|
+
return response.body if response.code == '200'
|
17
|
+
|
18
|
+
raise "The URL #{@url} does not exist." if response.code == '404'
|
19
|
+
|
20
|
+
raise "Status code: #{response.code}"
|
21
|
+
rescue StandardError => e
|
22
|
+
raise e
|
25
23
|
end
|
26
24
|
end
|
27
|
-
|
28
25
|
end
|
29
26
|
end
|
30
27
|
end
|
data/lib/apt/spy2/launchpad.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'nokogiri'
|
2
4
|
|
3
5
|
module Apt
|
4
6
|
module Spy2
|
7
|
+
# parse launchpad output
|
5
8
|
class Launchpad
|
6
|
-
|
7
9
|
def initialize(download)
|
8
10
|
@launchpad = download
|
9
11
|
end
|
10
12
|
|
11
|
-
def
|
12
|
-
|
13
|
+
def mirrors(country)
|
13
14
|
mirrors = []
|
14
15
|
|
15
16
|
document = Nokogiri::HTML(@launchpad)
|
@@ -27,10 +28,8 @@ module Apt
|
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
30
|
-
|
31
|
-
|
31
|
+
mirrors
|
32
32
|
end
|
33
|
-
|
34
33
|
end
|
35
34
|
end
|
36
35
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'net/https'
|
5
|
+
require 'uri'
|
6
|
+
|
7
|
+
module Apt
|
8
|
+
module Spy2
|
9
|
+
# make requests
|
10
|
+
class Request
|
11
|
+
def initialize(url)
|
12
|
+
uri = URI(url)
|
13
|
+
|
14
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
15
|
+
http.use_ssl = true if uri.scheme == 'https'
|
16
|
+
|
17
|
+
@http = http
|
18
|
+
@request_uri = uri.request_uri
|
19
|
+
end
|
20
|
+
|
21
|
+
def get
|
22
|
+
@http.request(Net::HTTP::Get.new(@request_uri))
|
23
|
+
end
|
24
|
+
|
25
|
+
def head
|
26
|
+
@http.request(Net::HTTP::Head.new(@request_uri))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,19 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Apt
|
2
4
|
module Spy2
|
5
|
+
# wraps around the \n delimited list of mirrors
|
3
6
|
class UbuntuMirrors
|
4
|
-
|
5
7
|
def initialize(download)
|
6
8
|
@ubuntu_mirrors = download
|
7
9
|
end
|
8
10
|
|
9
|
-
def
|
10
|
-
|
11
|
+
def mirrors(_country)
|
11
12
|
mirrors = @ubuntu_mirrors
|
12
|
-
mirrors
|
13
|
-
return mirrors
|
14
|
-
|
13
|
+
mirrors.split(/\n/)
|
15
14
|
end
|
16
|
-
|
17
15
|
end
|
18
16
|
end
|
19
17
|
end
|
data/lib/apt/spy2/url.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Apt
|
4
|
+
module Spy2
|
5
|
+
# build mirror url
|
6
|
+
class Url
|
7
|
+
def initialize(strict)
|
8
|
+
@strict = strict
|
9
|
+
end
|
10
|
+
|
11
|
+
def adjust!(mirror)
|
12
|
+
return mirror unless @strict
|
13
|
+
|
14
|
+
"#{mirror}dists/#{release}/Contents-#{arch}.gz"
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def arch
|
20
|
+
`dpkg --print-architecture`.strip
|
21
|
+
end
|
22
|
+
|
23
|
+
def release
|
24
|
+
`lsb_release -c`.split(' ')[1].strip
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/apt/spy2/version.rb
CHANGED
data/lib/apt/spy2/writer.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'colored'
|
2
4
|
require 'json'
|
3
5
|
|
4
6
|
module Apt
|
5
7
|
module Spy2
|
8
|
+
# abstracted puts or json
|
6
9
|
class Writer
|
7
10
|
def initialize(format)
|
8
|
-
|
9
|
-
if !["json", "shell"].include?(format)
|
10
|
-
raise "Unknown format: #{format}"
|
11
|
-
end
|
11
|
+
raise "Unknown format: #{format}" unless %w[json shell].include?(format)
|
12
12
|
|
13
13
|
@format = format
|
14
14
|
@complete = []
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
17
|
+
def complete(complete)
|
18
18
|
@complete = complete
|
19
19
|
end
|
20
20
|
|
@@ -24,32 +24,29 @@ module Apt
|
|
24
24
|
return
|
25
25
|
end
|
26
26
|
|
27
|
-
print "Mirror: #{data[
|
27
|
+
print "Mirror: #{data['mirror']} - "
|
28
28
|
|
29
|
-
case data[
|
30
|
-
when
|
31
|
-
puts data[
|
32
|
-
when
|
33
|
-
puts data[
|
34
|
-
when
|
35
|
-
puts data[
|
29
|
+
case data['status']
|
30
|
+
when 'up'
|
31
|
+
puts data['status'].upcase.green
|
32
|
+
when 'down'
|
33
|
+
puts data['status'].upcase.red
|
34
|
+
when 'broken'
|
35
|
+
puts data['status'].upcase.yellow
|
36
36
|
else
|
37
|
-
puts "Unknown status: #{data[
|
37
|
+
puts "Unknown status: #{data['status']}".white_on_red
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
def json?
|
42
|
-
if @format == 'json'
|
43
|
-
return true
|
44
|
-
end
|
42
|
+
return true if @format == 'json'
|
45
43
|
|
46
|
-
|
44
|
+
false
|
47
45
|
end
|
48
46
|
|
49
|
-
def to_json
|
47
|
+
def to_json(*_args)
|
50
48
|
JSON.generate(@complete)
|
51
49
|
end
|
52
|
-
|
53
50
|
end
|
54
51
|
end
|
55
52
|
end
|
data/lib/apt/spy2.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'thor'
|
2
4
|
require 'open-uri'
|
3
5
|
require 'colored'
|
@@ -7,116 +9,126 @@ require 'apt/spy2/country'
|
|
7
9
|
require 'apt/spy2/downloader'
|
8
10
|
require 'apt/spy2/ubuntu_mirrors'
|
9
11
|
require 'apt/spy2/launchpad'
|
12
|
+
require 'apt/spy2/request'
|
13
|
+
require 'apt/spy2/url'
|
10
14
|
|
15
|
+
# apt-spy2 command interface
|
11
16
|
class AptSpy2 < Thor
|
12
|
-
package_name
|
17
|
+
package_name 'apt-spy2'
|
18
|
+
class_option :country, default: 'mirrors'
|
19
|
+
class_option :launchpad, type: :boolean, banner: "Use launchpad's mirror list"
|
13
20
|
|
14
|
-
desc
|
15
|
-
option :
|
16
|
-
option :
|
17
|
-
option :launchpad, :type => :boolean, :banner => "Use launchpad's mirror list"
|
21
|
+
desc 'fix', 'Set the closest/fastest mirror'
|
22
|
+
option :commit, type: :boolean
|
23
|
+
option :strict, type: :boolean
|
18
24
|
def fix
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
update(working[0])
|
25
|
+
mirrors = retrieve(options[:country], use_launchpad?(options))
|
26
|
+
working = filter(mirrors, options[:strict], false)
|
27
|
+
print 'The closest mirror is: '
|
28
|
+
puts (working[0]).to_s.bold.magenta
|
29
|
+
unless options[:commit]
|
30
|
+
puts 'Run with --commit to adjust /etc/apt/sources.list'.yellow
|
31
|
+
return
|
27
32
|
end
|
33
|
+
|
34
|
+
puts 'Updating /etc/apt/sources.list'.yellow
|
35
|
+
update(working[0])
|
28
36
|
end
|
29
37
|
|
30
|
-
desc
|
31
|
-
option :
|
32
|
-
option :
|
33
|
-
option :
|
34
|
-
option :launchpad, :type => :boolean, :banner => "Use launchpad's mirror list"
|
38
|
+
desc 'check', 'Evaluate mirrors'
|
39
|
+
option :output, type: :boolean, default: true
|
40
|
+
option :format, default: 'shell'
|
41
|
+
option :strict, type: :boolean
|
35
42
|
def check
|
36
|
-
|
37
43
|
@writer = Apt::Spy2::Writer.new(options[:format])
|
38
44
|
|
39
45
|
mirrors = retrieve(options[:country], use_launchpad?(options))
|
40
|
-
filter(mirrors, options[:output])
|
46
|
+
filter(mirrors, options[:strict], options[:output])
|
41
47
|
|
42
48
|
puts @writer.to_json if @writer.json?
|
43
49
|
end
|
44
50
|
|
45
|
-
desc
|
46
|
-
option :
|
47
|
-
option :format, :default => "shell"
|
48
|
-
option :launchpad, :type => :boolean, :banner => "Use launchpad's mirror list"
|
51
|
+
desc 'list', 'List the currently available mirrors'
|
52
|
+
option :format, default: 'shell'
|
49
53
|
def list
|
50
54
|
mirrors = retrieve(options[:country], use_launchpad?(options))
|
51
55
|
|
52
56
|
@writer = Apt::Spy2::Writer.new(options[:format])
|
53
57
|
|
54
|
-
@writer.
|
58
|
+
@writer.complete(mirrors)
|
55
59
|
|
56
60
|
puts @writer.to_json if @writer.json?
|
57
|
-
puts mirrors
|
61
|
+
puts mirrors unless @writer.json?
|
58
62
|
end
|
59
63
|
|
60
|
-
desc
|
64
|
+
desc 'version', 'Show which version of apt-spy2 is installed'
|
61
65
|
def version
|
62
66
|
puts Apt::Spy2::VERSION
|
63
67
|
exit
|
64
68
|
end
|
65
69
|
|
66
70
|
private
|
67
|
-
def retrieve(country = "mirrors", launchpad = false)
|
68
71
|
|
72
|
+
def retrieve(country = 'mirrors', launchpad = false)
|
69
73
|
downloader = Apt::Spy2::Downloader.new
|
70
74
|
|
71
|
-
if launchpad
|
72
|
-
csv_path = File.expand_path(File.dirname(__FILE__)
|
75
|
+
if launchpad
|
76
|
+
csv_path = File.expand_path("#{File.dirname(__FILE__)}/../../var/country-names.txt")
|
73
77
|
country = Apt::Spy2::Country.new(csv_path)
|
74
78
|
name = country.to_country_name(options[:country])
|
75
79
|
|
76
80
|
launchpad = Apt::Spy2::Launchpad.new(downloader.do_download('https://launchpad.net/ubuntu/+archivemirrors'))
|
77
|
-
return launchpad.
|
81
|
+
return launchpad.mirrors(name)
|
78
82
|
end
|
79
83
|
|
80
84
|
country.upcase! if country.length == 2
|
81
85
|
|
82
86
|
ubuntu_mirrors = Apt::Spy2::UbuntuMirrors.new(downloader.do_download("http://mirrors.ubuntu.com/#{country}.txt"))
|
83
|
-
|
84
|
-
return mirrors
|
85
|
-
|
87
|
+
ubuntu_mirrors.mirrors(country)
|
86
88
|
end
|
87
89
|
|
88
|
-
|
89
|
-
def filter(mirrors, output = true)
|
90
|
+
def filter(mirrors, strict = false, output = true)
|
90
91
|
# f me :)
|
91
92
|
|
92
93
|
working_mirrors = []
|
93
94
|
|
95
|
+
url = Apt::Spy2::Url.new(strict)
|
96
|
+
|
94
97
|
mirrors.each do |mirror|
|
95
|
-
data = {
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
data["status"] = "down"
|
105
|
-
end
|
98
|
+
data = { 'mirror' => mirror }
|
99
|
+
|
100
|
+
check = url.adjust!(mirror)
|
101
|
+
|
102
|
+
status = broken?(check)
|
103
|
+
|
104
|
+
data['status'] = status
|
105
|
+
|
106
|
+
working_mirrors << mirror if status == 'up'
|
106
107
|
|
107
108
|
@writer.echo(data) if output
|
108
109
|
end
|
109
110
|
|
110
|
-
|
111
|
+
working_mirrors
|
112
|
+
end
|
113
|
+
|
114
|
+
def broken?(url)
|
115
|
+
begin
|
116
|
+
req = Apt::Spy2::Request.new(url)
|
117
|
+
response = req.head
|
118
|
+
return 'up' if response.code == '200'
|
119
|
+
|
120
|
+
return 'broken' if response.code == '404'
|
121
|
+
rescue StandardError
|
122
|
+
# connection errors, ssl errors, etc.
|
123
|
+
end
|
111
124
|
|
125
|
+
'down'
|
112
126
|
end
|
113
127
|
|
114
|
-
private
|
115
128
|
def update(mirror)
|
116
|
-
|
117
129
|
t = Time.now
|
118
|
-
r = `lsb_release -c`.split(
|
119
|
-
sources = "## Updated on #{t
|
130
|
+
r = `lsb_release -c`.split(' ')[1]
|
131
|
+
sources = "## Updated on #{t} by apt-spy2\n"
|
120
132
|
sources << "deb #{mirror} #{r} main restricted universe multiverse\n"
|
121
133
|
sources << "deb #{mirror} #{r}-updates main restricted universe multiverse\n"
|
122
134
|
sources << "deb #{mirror} #{r}-backports main restricted universe multiverse\n"
|
@@ -129,26 +141,23 @@ class AptSpy2 < Thor
|
|
129
141
|
File.open(apt_sources, 'w') do |f|
|
130
142
|
f.write(sources)
|
131
143
|
end
|
132
|
-
rescue
|
144
|
+
rescue StandardError
|
133
145
|
msg = "Failed updating #{apt_sources}!"
|
134
|
-
msg <<
|
146
|
+
msg << 'You probably need sudo!'
|
135
147
|
raise msg
|
136
148
|
end
|
137
149
|
|
138
150
|
puts "Updated '#{apt_sources}' with #{mirror}".green
|
139
|
-
puts
|
151
|
+
puts 'Run `apt-get update` to update'.black_on_yellow
|
140
152
|
end
|
141
153
|
|
142
|
-
private
|
143
154
|
def use_launchpad?(options)
|
144
|
-
|
145
|
-
return false
|
146
|
-
end
|
155
|
+
return false unless options[:launchpad]
|
147
156
|
|
148
157
|
if options[:country] && options[:country] == 'mirrors'
|
149
|
-
raise
|
158
|
+
raise 'Please supply a `--country=foo`. Launchpad cannot guess!'
|
150
159
|
end
|
151
160
|
|
152
|
-
|
161
|
+
true
|
153
162
|
end
|
154
163
|
end
|
data/test_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'simplecov'
|
4
|
+
require 'simplecov-lcov'
|
5
|
+
|
6
|
+
if ENV['CI']
|
7
|
+
SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter
|
8
|
+
SimpleCov::Formatter::LcovFormatter.config do |c|
|
9
|
+
c.output_directory = './coverage'
|
10
|
+
c.report_with_single_file = true
|
11
|
+
c.single_report_path = './coverage/lcov.info'
|
12
|
+
end
|
13
|
+
else
|
14
|
+
SimpleCov.formatter SimpleCov::Formatter::MultiFormatter.new([
|
15
|
+
SimpleCov::Formatter::SimpleFormatter,
|
16
|
+
SimpleCov::Formatter::HTMLFormatter
|
17
|
+
])
|
18
|
+
end
|
19
|
+
|
20
|
+
SimpleCov.profiles.define 'apt-spy2' do
|
21
|
+
add_filter '/tests/'
|
22
|
+
add_filter '/pkg/'
|
23
|
+
add_filter '/vendor/'
|
24
|
+
add_filter '/var'
|
25
|
+
|
26
|
+
add_group 'lib', 'lib/apt'
|
27
|
+
add_group 'bin', 'bin'
|
28
|
+
end
|
29
|
+
SimpleCov.start 'apt-spy2'
|
30
|
+
require 'minitest/autorun'
|
data/tests/country_test.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../test_helper'
|
4
|
+
require_relative '../lib/apt/spy2/country'
|
5
|
+
|
6
|
+
# test the name resolution
|
3
7
|
class CountryTest < Minitest::Test
|
4
8
|
def setup
|
5
|
-
@country_list = File.expand_path(File.dirname(__FILE__)
|
9
|
+
@country_list = File.expand_path("#{File.dirname(__FILE__)}/../var/country-names.txt")
|
6
10
|
end
|
7
11
|
|
8
|
-
def test_tld_to_name
|
9
|
-
|
12
|
+
def test_tld_to_name
|
10
13
|
# fixtures for people who don't want to read about rails
|
11
14
|
data = {
|
12
15
|
'de' => 'Germany',
|
@@ -22,6 +25,5 @@ class CountryTest < Minitest::Test
|
|
22
25
|
data.each_pair do |code, expected|
|
23
26
|
assert_equal(expected, c.to_country_name(code))
|
24
27
|
end
|
25
|
-
|
26
28
|
end
|
27
29
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../test_helper'
|
4
|
+
require_relative '../lib/apt/spy2/downloader'
|
5
|
+
|
6
|
+
# this is an integration test (needs interwebs)
|
7
|
+
class DownloaderTest < Minitest::Test
|
8
|
+
def test_do
|
9
|
+
downloader = Apt::Spy2::Downloader.new
|
10
|
+
data = downloader.do_download('http://mirrors.ubuntu.com/DE.txt')
|
11
|
+
assert(!data.empty?, 'There should have been a response, unless the mirrors are down.')
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_do_wrong_countrys
|
15
|
+
downloader = Apt::Spy2::Downloader.new
|
16
|
+
assert_raises(RuntimeError) { downloader.do_download('http://mirrors.ubuntu.com/de.txt') }
|
17
|
+
end
|
18
|
+
end
|
data/tests/launchpad_test.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative '../test_helper'
|
4
|
+
require_relative '../lib/apt/spy2/launchpad'
|
5
|
+
|
6
|
+
# test to confirm launchpad format (HTML) is parsed
|
3
7
|
class LaunchpadTest < Minitest::Test
|
4
8
|
def setup
|
5
|
-
@download_fixture = File.read(File.expand_path(File.dirname(__FILE__)
|
9
|
+
@download_fixture = File.read(File.expand_path("#{File.dirname(__FILE__)}/fixtures/launchpad.html"))
|
6
10
|
end
|
7
11
|
|
8
12
|
def test_german_mirrors
|
9
13
|
lp = Apt::Spy2::Launchpad.new(@download_fixture)
|
10
|
-
mirrors = lp.
|
14
|
+
mirrors = lp.mirrors('Germany')
|
11
15
|
assert_equal(false, mirrors.empty?)
|
12
16
|
end
|
13
17
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../test_helper'
|
4
|
+
require_relative '../lib/apt/spy2/ubuntu_mirrors'
|
5
|
+
|
6
|
+
# test to confirm launchpad format (HTML) is parsed
|
7
|
+
class UbuntuMirrorsTest < Minitest::Test
|
8
|
+
def test_mirrors
|
9
|
+
expected = ['http://example.org', 'http://example.de']
|
10
|
+
fixture = expected.join("\n")
|
11
|
+
|
12
|
+
m = Apt::Spy2::UbuntuMirrors.new(fixture)
|
13
|
+
assert_equal(expected, m.mirrors('country'))
|
14
|
+
end
|
15
|
+
end
|
data/tests/url_test.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../test_helper'
|
4
|
+
require_relative '../lib/apt/spy2/url'
|
5
|
+
|
6
|
+
# test to check request lib
|
7
|
+
class UrlTest < Minitest::Test
|
8
|
+
def test_non_strict
|
9
|
+
expected = 'http://example.org'
|
10
|
+
|
11
|
+
url = Apt::Spy2::Url.new(false)
|
12
|
+
assert_equal(expected, url.adjust!(expected))
|
13
|
+
end
|
14
|
+
|
15
|
+
# def strict
|
16
|
+
# skip "Test only runs on ubuntu" if OS.unix? and not OS.mac?
|
17
|
+
|
18
|
+
# expected = 'http://example.org'
|
19
|
+
|
20
|
+
# url = Apt::Spy2::Url.new(true)
|
21
|
+
# assert_not_equal(expected, url.mirror)
|
22
|
+
# end
|
23
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../test_helper'
|
4
|
+
require_relative '../lib/apt/spy2/writer'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
# test to check request lib
|
8
|
+
class WriterTest < Minitest::Test
|
9
|
+
def test_json
|
10
|
+
fixture = { 'mirror': 'http://example.org', 'status': 'up' }
|
11
|
+
|
12
|
+
w = Apt::Spy2::Writer.new('json')
|
13
|
+
w.echo(fixture)
|
14
|
+
|
15
|
+
# json string
|
16
|
+
j = w.to_json
|
17
|
+
|
18
|
+
assert_equal(true, w.json?)
|
19
|
+
assert_equal(true, j.is_a?(String))
|
20
|
+
assert_equal(true, JSON.parse(j).is_a?(Array))
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_no_json
|
24
|
+
w = Apt::Spy2::Writer.new('shell')
|
25
|
+
assert_equal(false, w.json?)
|
26
|
+
end
|
27
|
+
end
|
metadata
CHANGED
@@ -1,77 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: apt-spy2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- till
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: colored
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '1.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: '1.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: json
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: nokogiri
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 1.14.1
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 1.14.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: thor
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
62
|
-
- - "<"
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: '1.13'
|
61
|
+
version: 0.18.1
|
65
62
|
type: :runtime
|
66
63
|
prerelease: false
|
67
64
|
version_requirements: !ruby/object:Gem::Requirement
|
68
65
|
requirements:
|
69
66
|
- - ">="
|
70
67
|
- !ruby/object:Gem::Version
|
71
|
-
version:
|
72
|
-
- - "<"
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: '1.13'
|
68
|
+
version: 0.18.1
|
75
69
|
- !ruby/object:Gem::Dependency
|
76
70
|
name: bundler
|
77
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,6 +80,20 @@ dependencies:
|
|
86
80
|
- - "~>"
|
87
81
|
- !ruby/object:Gem::Version
|
88
82
|
version: '2.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: minitest
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 5.15.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 5.15.0
|
89
97
|
- !ruby/object:Gem::Dependency
|
90
98
|
name: rake
|
91
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -101,19 +109,19 @@ dependencies:
|
|
101
109
|
- !ruby/object:Gem::Version
|
102
110
|
version: '0'
|
103
111
|
- !ruby/object:Gem::Dependency
|
104
|
-
name:
|
112
|
+
name: rubocop
|
105
113
|
requirement: !ruby/object:Gem::Requirement
|
106
114
|
requirements:
|
107
|
-
- - "
|
115
|
+
- - ">="
|
108
116
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
117
|
+
version: '0'
|
110
118
|
type: :development
|
111
119
|
prerelease: false
|
112
120
|
version_requirements: !ruby/object:Gem::Requirement
|
113
121
|
requirements:
|
114
|
-
- - "
|
122
|
+
- - ">="
|
115
123
|
- !ruby/object:Gem::Version
|
116
|
-
version:
|
124
|
+
version: '0'
|
117
125
|
- !ruby/object:Gem::Dependency
|
118
126
|
name: simplecov
|
119
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -152,7 +160,9 @@ extra_rdoc_files: []
|
|
152
160
|
files:
|
153
161
|
- ".dockerignore"
|
154
162
|
- ".github/dependabot.yml"
|
163
|
+
- ".github/workflows/codeql-analysis.yml"
|
155
164
|
- ".github/workflows/pr.yml"
|
165
|
+
- ".github/workflows/release.yml"
|
156
166
|
- ".gitignore"
|
157
167
|
- ".ruby_version"
|
158
168
|
- CONTRIBUTING.md
|
@@ -169,12 +179,19 @@ files:
|
|
169
179
|
- lib/apt/spy2/country.rb
|
170
180
|
- lib/apt/spy2/downloader.rb
|
171
181
|
- lib/apt/spy2/launchpad.rb
|
182
|
+
- lib/apt/spy2/request.rb
|
172
183
|
- lib/apt/spy2/ubuntu_mirrors.rb
|
184
|
+
- lib/apt/spy2/url.rb
|
173
185
|
- lib/apt/spy2/version.rb
|
174
186
|
- lib/apt/spy2/writer.rb
|
187
|
+
- test_helper.rb
|
175
188
|
- tests/country_test.rb
|
189
|
+
- tests/downloader_test.rb
|
176
190
|
- tests/fixtures/launchpad.html
|
177
191
|
- tests/launchpad_test.rb
|
192
|
+
- tests/ubuntu_mirrors_test.rb
|
193
|
+
- tests/url_test.rb
|
194
|
+
- tests/writer_test.rb
|
178
195
|
- var/country-names.txt
|
179
196
|
homepage: https://github.com/lagged/apt-spy2
|
180
197
|
licenses:
|
@@ -188,14 +205,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
188
205
|
requirements:
|
189
206
|
- - ">="
|
190
207
|
- !ruby/object:Gem::Version
|
191
|
-
version: '
|
208
|
+
version: '2.7'
|
209
|
+
- - "<"
|
210
|
+
- !ruby/object:Gem::Version
|
211
|
+
version: '3.3'
|
192
212
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
193
213
|
requirements:
|
194
214
|
- - ">="
|
195
215
|
- !ruby/object:Gem::Version
|
196
216
|
version: '0'
|
197
217
|
requirements: []
|
198
|
-
rubygems_version: 3.2
|
218
|
+
rubygems_version: 3.4.2
|
199
219
|
signing_key:
|
200
220
|
specification_version: 4
|
201
221
|
summary: apt-spy2, or apt-spy for ubuntu
|