inqlude 0.0.8 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/Gemfile +3 -0
- data/README +35 -1
- data/TODO +50 -15
- data/inqlude.gemspec +7 -2
- data/lib/cli.rb +70 -6
- data/lib/creator.rb +32 -8
- data/lib/git_hub_tool.rb +92 -0
- data/lib/inqlude.rb +7 -0
- data/lib/kde_frameworks_creator.rb +173 -0
- data/lib/kde_frameworks_release.rb +61 -0
- data/lib/library.rb +26 -1
- data/lib/manifest.rb +43 -0
- data/lib/manifest_handler.rb +59 -17
- data/lib/rpm_manifestizer.rb +2 -2
- data/lib/settings.rb +21 -10
- data/lib/verifier.rb +29 -18
- data/lib/version.rb +1 -1
- data/lib/view.rb +55 -10
- data/manifest-format.md +27 -12
- data/schema/generic-manifest-v1 +54 -0
- data/schema/proprietary-release-manifest-v1 +63 -0
- data/schema/release-manifest-v1 +73 -0
- data/spec/creator_spec.rb +94 -34
- data/spec/data/awesomelib/awesomelib.2013-09-08.manifest +14 -6
- data/spec/data/bleedingedge/bleedingedge.2012-01-01.manifest +3 -2
- data/spec/data/commercial/commercial.manifest +13 -0
- data/spec/data/karchive-generic.manifest +22 -0
- data/spec/data/karchive-release-beta.manifest +29 -0
- data/spec/data/karchive-release.manifest +29 -0
- data/spec/data/karchive-release2.manifest +29 -0
- data/spec/data/karchive.authors +10 -0
- data/spec/data/karchive.readme +35 -0
- data/spec/data/kservice-generic.manifest +22 -0
- data/spec/data/kservice.readme +9 -0
- data/spec/data/newlib/newlib.manifest +13 -0
- data/spec/data/proprietarylib/proprietarylib.2013-12-22.manifest +16 -0
- data/spec/data/rendertest-generic.manifest +20 -0
- data/spec/data/testcontent +1 -0
- data/spec/kde_frameworks_creator_spec.rb +263 -0
- data/spec/kde_frameworks_release_spec.rb +72 -0
- data/spec/library_spec.rb +54 -2
- data/spec/manifest_handler_spec.rb +102 -8
- data/spec/manifest_spec.rb +63 -0
- data/spec/rpm_manifestizer_spec.rb +2 -2
- data/spec/settings_spec.rb +53 -4
- data/spec/spec_helper.rb +40 -1
- data/spec/verifier_spec.rb +53 -22
- data/spec/view_spec.rb +145 -0
- data/view/all.html.haml +24 -0
- data/view/commercial.html.haml +17 -0
- data/view/contribute.html.haml +7 -3
- data/view/development.html.haml +36 -0
- data/view/favicon.ico +0 -0
- data/view/group.html.haml +20 -0
- data/view/index.html.haml +11 -1
- data/view/layout.html.haml +0 -5
- data/view/library.html.haml +4 -4
- data/view/public/inqlude.css +2 -2
- data/view/unreleased.html.haml +18 -0
- metadata +172 -97
- data/view/edge.html.haml +0 -9
@@ -0,0 +1,73 @@
|
|
1
|
+
{
|
2
|
+
"id": "http://inqlude.org/schema/release-manifest-v1#",
|
3
|
+
"$schema": "http://json-schema.org/draft-04/schema#",
|
4
|
+
"title": "Inqlude Release Manifest Schema",
|
5
|
+
"type": "object",
|
6
|
+
"properties": {
|
7
|
+
"name": {
|
8
|
+
"type": "string"
|
9
|
+
},
|
10
|
+
"release_date": {
|
11
|
+
"type": "string"
|
12
|
+
},
|
13
|
+
"version": {
|
14
|
+
"type": "string"
|
15
|
+
},
|
16
|
+
"summary": {
|
17
|
+
"type": "string"
|
18
|
+
},
|
19
|
+
"urls": {
|
20
|
+
"type": "object",
|
21
|
+
"properties": {
|
22
|
+
"homepage": {
|
23
|
+
"type": "string"
|
24
|
+
},
|
25
|
+
"download": {
|
26
|
+
"type": "string"
|
27
|
+
}
|
28
|
+
},
|
29
|
+
"required": [ "homepage" ]
|
30
|
+
},
|
31
|
+
"licenses": {
|
32
|
+
"type": "array",
|
33
|
+
"items": {
|
34
|
+
"type": "string"
|
35
|
+
},
|
36
|
+
"minItems": 1
|
37
|
+
},
|
38
|
+
"description": {
|
39
|
+
"type": "string"
|
40
|
+
},
|
41
|
+
"authors": {
|
42
|
+
"type": "array",
|
43
|
+
"items": {
|
44
|
+
"type": "string"
|
45
|
+
}
|
46
|
+
},
|
47
|
+
"maturity": {
|
48
|
+
"type": "string"
|
49
|
+
},
|
50
|
+
"platforms": {
|
51
|
+
"type": "array",
|
52
|
+
"items": {
|
53
|
+
"type": "string"
|
54
|
+
},
|
55
|
+
"minItems": 1
|
56
|
+
},
|
57
|
+
"packages": {
|
58
|
+
"type": "object",
|
59
|
+
"properties": {
|
60
|
+
"source": {
|
61
|
+
"type": "string"
|
62
|
+
}
|
63
|
+
},
|
64
|
+
"required": [ "source" ]
|
65
|
+
},
|
66
|
+
"group": {
|
67
|
+
"type": "string"
|
68
|
+
}
|
69
|
+
},
|
70
|
+
"required": [ "$schema", "name", "release_date", "version", "summary",
|
71
|
+
"urls", "licenses", "description", "maturity", "platforms",
|
72
|
+
"packages" ]
|
73
|
+
}
|
data/spec/creator_spec.rb
CHANGED
@@ -2,6 +2,10 @@ require File.expand_path('../spec_helper', __FILE__)
|
|
2
2
|
|
3
3
|
describe Creator do
|
4
4
|
|
5
|
+
include GivenFilesystemSpecHelpers
|
6
|
+
|
7
|
+
use_given_filesystem
|
8
|
+
|
5
9
|
let(:settings) do
|
6
10
|
s = Settings.new
|
7
11
|
s.manifest_path = File.expand_path('spec/data/')
|
@@ -9,18 +13,6 @@ describe Creator do
|
|
9
13
|
s
|
10
14
|
end
|
11
15
|
|
12
|
-
let(:filename) do
|
13
|
-
File.expand_path('../data/awesomelib/awesomelib.2013-10-01.manifest', __FILE__)
|
14
|
-
end
|
15
|
-
|
16
|
-
let(:new_filename) do
|
17
|
-
File.expand_path('../data/newawesomelib/newawesomelib.2013-09-01.manifest', __FILE__)
|
18
|
-
end
|
19
|
-
|
20
|
-
let(:new_dirname) do
|
21
|
-
File.expand_path('../data/newawesomelib', __FILE__)
|
22
|
-
end
|
23
|
-
|
24
16
|
it "checks directory" do
|
25
17
|
c = Creator.new settings, "xxx"
|
26
18
|
expect{ c.validate_directory }.to raise_error(StandardError)
|
@@ -30,62 +22,130 @@ describe Creator do
|
|
30
22
|
end
|
31
23
|
|
32
24
|
it "creates updated manifest" do
|
25
|
+
settings.manifest_path = given_directory do
|
26
|
+
given_directory "awesomelib" do
|
27
|
+
manifest_filename = given_file "awesomelib.2013-09-08.manifest",
|
28
|
+
:from => "awesomelib/awesomelib.2013-09-08.manifest"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
manifest_filename = File.join( settings.manifest_path, "awesomelib",
|
32
|
+
"awesomelib.2013-10-01.manifest" )
|
33
|
+
|
33
34
|
c = Creator.new settings, "awesomelib"
|
34
35
|
|
35
|
-
File.exists?(
|
36
|
+
expect( File.exists?(manifest_filename) ).to be false
|
36
37
|
|
37
38
|
c.update "1.0", "2013-10-01"
|
38
39
|
|
39
|
-
File.exists?(
|
40
|
+
expect( File.exists?(manifest_filename) ).to be true
|
40
41
|
|
41
42
|
mh = ManifestHandler.new settings
|
42
43
|
mh.read_remote
|
43
44
|
|
44
|
-
mh.libraries.count.
|
45
|
+
expect(mh.libraries.count).to eq 1
|
45
46
|
m = mh.manifest "awesomelib"
|
46
|
-
m["name"].
|
47
|
-
m["version"].
|
48
|
-
m["release_date"].
|
49
|
-
m["summary"].
|
47
|
+
expect(m["name"]).to eq "awesomelib"
|
48
|
+
expect(m["version"]).to eq "1.0"
|
49
|
+
expect(m["release_date"]).to eq "2013-10-01"
|
50
|
+
expect(m["summary"]).to eq "Awesome library"
|
50
51
|
|
51
|
-
mh.manifests.count.
|
52
|
+
expect(mh.manifests.count).to eq 2
|
52
53
|
mh.manifests.each do |manifest|
|
53
|
-
manifest
|
54
|
+
if manifest["schema_type"] == "generic"
|
55
|
+
if manifest["name"] == "commercial"
|
56
|
+
expect(manifest.keys.count).to eq 13
|
57
|
+
else
|
58
|
+
expect(manifest.keys.count).to eq 12
|
59
|
+
end
|
60
|
+
elsif manifest["schema_type"] == "proprietary-release"
|
61
|
+
expect(manifest.keys.count).to eq 15
|
62
|
+
else
|
63
|
+
expect(manifest.keys.count).to eq 17
|
64
|
+
end
|
54
65
|
end
|
55
66
|
|
56
|
-
m = JSON File.read(
|
57
|
-
m.keys.count.
|
67
|
+
m = JSON File.read(manifest_filename)
|
68
|
+
expect(m.keys.count).to eq 13
|
58
69
|
end
|
59
70
|
|
60
71
|
it "creates new manifest" do
|
72
|
+
settings.manifest_path = given_directory do
|
73
|
+
given_directory "newawesomelib"
|
74
|
+
end
|
75
|
+
manifest_filename = File.join( settings.manifest_path, "newawesomelib",
|
76
|
+
"newawesomelib.2013-09-01.manifest" )
|
77
|
+
|
61
78
|
c = Creator.new settings, "newawesomelib"
|
62
|
-
File.exists?(
|
79
|
+
expect(File.exists?(manifest_filename)).to be false
|
63
80
|
|
64
81
|
c.create "edge", "2013-09-01"
|
65
82
|
|
66
|
-
File.exists?(
|
83
|
+
expect(File.exists?(manifest_filename)).to be true
|
67
84
|
|
68
85
|
mh = ManifestHandler.new settings
|
69
86
|
mh.read_remote
|
70
87
|
|
71
|
-
mh.libraries.count.
|
88
|
+
expect(mh.libraries.count).to eq 1
|
72
89
|
m = mh.manifest "newawesomelib"
|
73
|
-
m["name"].
|
74
|
-
m["version"].
|
75
|
-
m["release_date"].
|
90
|
+
expect(m["name"]).to eq "newawesomelib"
|
91
|
+
expect(m["version"]).to eq "edge"
|
92
|
+
expect(m["release_date"]).to eq "2013-09-01"
|
76
93
|
|
77
94
|
v = Verifier.new settings
|
78
95
|
result = v.verify m
|
79
96
|
if !result.valid?
|
80
97
|
result.print_result
|
81
98
|
end
|
82
|
-
expect(result.valid?).to
|
99
|
+
expect(result.valid?).to be true
|
100
|
+
end
|
101
|
+
|
102
|
+
it "creates new generic manifest" do
|
103
|
+
settings.manifest_path = given_directory do
|
104
|
+
given_directory "newawesomelib"
|
105
|
+
end
|
106
|
+
manifest_filename = File.join( settings.manifest_path, "newawesomelib",
|
107
|
+
"newawesomelib.manifest" )
|
108
|
+
|
109
|
+
c = Creator.new settings, "newawesomelib"
|
110
|
+
expect(File.exists?(manifest_filename)).to be false
|
111
|
+
|
112
|
+
c.create_generic
|
113
|
+
|
114
|
+
expect(File.exists?(manifest_filename)).to be true
|
115
|
+
|
116
|
+
v = Verifier.new settings
|
117
|
+
result = v.verify_file manifest_filename
|
118
|
+
if !result.valid?
|
119
|
+
result.print_result
|
120
|
+
end
|
121
|
+
expect(result.valid?).to be true
|
83
122
|
end
|
84
123
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
124
|
+
describe "#create_dir" do
|
125
|
+
|
126
|
+
before(:each) do
|
127
|
+
@settings = Settings.new
|
128
|
+
@settings.manifest_path = given_directory
|
129
|
+
end
|
130
|
+
|
131
|
+
it "creates dir" do
|
132
|
+
c = Creator.new( @settings, "one" )
|
133
|
+
c.create_dir()
|
134
|
+
expect( File.exists? File.join( @settings.manifest_path, "one" ) )
|
135
|
+
.to be true
|
136
|
+
expect( File.directory? File.join( @settings.manifest_path, "one" ) )
|
137
|
+
.to be true
|
138
|
+
end
|
139
|
+
|
140
|
+
it "uses existing dir" do
|
141
|
+
c = Creator.new( @settings, "one" )
|
142
|
+
c.create_dir()
|
143
|
+
c.create_dir()
|
144
|
+
expect( File.exists? File.join( @settings.manifest_path, "one" ) )
|
145
|
+
.to be true
|
146
|
+
expect( File.directory? File.join( @settings.manifest_path, "one" ) )
|
147
|
+
.to be true
|
148
|
+
end
|
89
149
|
end
|
90
150
|
|
91
151
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
{
|
2
|
-
"
|
2
|
+
"$schema": "http://inqlude.org/schema/release-manifest-v1#",
|
3
3
|
"name": "awesomelib",
|
4
4
|
"release_date": "2013-09-08",
|
5
5
|
"version": "0.2.0",
|
@@ -8,12 +8,20 @@
|
|
8
8
|
"homepage": "http://example.com",
|
9
9
|
"download": "http://example.com/download"
|
10
10
|
},
|
11
|
-
"licenses": [
|
11
|
+
"licenses": [
|
12
|
+
"LGPLv2.1+",
|
13
|
+
"Commercial"
|
14
|
+
],
|
12
15
|
"description": "This is an awesome library.",
|
13
|
-
"authors": [
|
16
|
+
"authors": [
|
17
|
+
"Cornelius Schumacher <schumacher@kde.org>"
|
18
|
+
],
|
14
19
|
"maturity": "stable",
|
15
|
-
"platforms": [
|
20
|
+
"platforms": [
|
21
|
+
"Linux"
|
22
|
+
],
|
16
23
|
"packages": {
|
17
24
|
"source": "ftp://example.com/download/awesomelib-0.2.0.tar.gz"
|
18
|
-
}
|
19
|
-
|
25
|
+
},
|
26
|
+
"group": "kde-frameworks"
|
27
|
+
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
{
|
2
|
-
"
|
2
|
+
"$schema": "http://inqlude.org/schema/release-manifest-v1#",
|
3
3
|
"name": "bleedingedge",
|
4
4
|
"release_date": "2012-01-01",
|
5
5
|
"version": "edge",
|
@@ -15,5 +15,6 @@
|
|
15
15
|
"platforms": [ "Linux" ],
|
16
16
|
"packages": {
|
17
17
|
"source": "ftp://example.org/download/bleedingedge-latest.tar.gz"
|
18
|
-
}
|
18
|
+
},
|
19
|
+
"group": "kde-frameworks"
|
19
20
|
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "http://inqlude.org/schema/generic-manifest-v1#",
|
3
|
+
"name": "commercial",
|
4
|
+
"summary": "Commercial library",
|
5
|
+
"urls": {
|
6
|
+
"homepage": "http://commercial.example.org"
|
7
|
+
},
|
8
|
+
"licenses": ["Commercial"],
|
9
|
+
"description": "Library only available under commercial license.",
|
10
|
+
"authors": ["John Doe <doe@example.org>"],
|
11
|
+
"maturity": "stable",
|
12
|
+
"platforms": [ "Linux", "Windows" ]
|
13
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "http://inqlude.org/schema/generic-manifest-v1#",
|
3
|
+
"name": "karchive",
|
4
|
+
"display_name": "KArchive",
|
5
|
+
"summary": "Reading, creating, and manipulating file archives",
|
6
|
+
"urls": {
|
7
|
+
"homepage": "https://projects.kde.org/projects/frameworks/karchive",
|
8
|
+
"vcs": "https://projects.kde.org/projects/frameworks/karchive/repository",
|
9
|
+
"mailing_list": "https://mail.kde.org/mailman/listinfo/kde-frameworks-devel"
|
10
|
+
},
|
11
|
+
"licenses": [
|
12
|
+
"LGPLv2.1+"
|
13
|
+
],
|
14
|
+
"description": "KArchive provides classes for easy reading, creation and manipulation of\n\"archive\" formats like ZIP and TAR.\n\nIf also provides transparent compression and decompression of data, like the\nGZip format, via a subclass of QIODevice.",
|
15
|
+
"authors": [
|
16
|
+
"The KDE Community"
|
17
|
+
],
|
18
|
+
"platforms": [
|
19
|
+
"Linux"
|
20
|
+
],
|
21
|
+
"group": "kde-frameworks"
|
22
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "http://inqlude.org/schema/release-manifest-v1#",
|
3
|
+
"name": "karchive",
|
4
|
+
"display_name": "KArchive",
|
5
|
+
"summary": "Reading, creating, and manipulating file archives",
|
6
|
+
"urls": {
|
7
|
+
"homepage": "https://projects.kde.org/projects/frameworks/karchive",
|
8
|
+
"vcs": "https://projects.kde.org/projects/frameworks/karchive/repository",
|
9
|
+
"mailing_list": "https://mail.kde.org/mailman/listinfo/kde-frameworks-devel",
|
10
|
+
"download": "http://download.kde.org/unstable/frameworks/4.9.90/"
|
11
|
+
},
|
12
|
+
"licenses": [
|
13
|
+
"LGPLv2.1+"
|
14
|
+
],
|
15
|
+
"description": "KArchive provides classes for easy reading, creation and manipulation of\n\"archive\" formats like ZIP and TAR.\n\nIf also provides transparent compression and decompression of data, like the\nGZip format, via a subclass of QIODevice.",
|
16
|
+
"authors": [
|
17
|
+
"The KDE Community"
|
18
|
+
],
|
19
|
+
"platforms": [
|
20
|
+
"Linux"
|
21
|
+
],
|
22
|
+
"group": "kde-frameworks",
|
23
|
+
"maturity": "beta",
|
24
|
+
"release_date": "2014-02-01",
|
25
|
+
"version": "4.9.90",
|
26
|
+
"packages": {
|
27
|
+
"source": "http://download.kde.org/unstable/frameworks/4.9.90/karchive-4.9.90.tar.xz"
|
28
|
+
}
|
29
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "http://inqlude.org/schema/release-manifest-v1#",
|
3
|
+
"name": "karchive",
|
4
|
+
"display_name": "KArchive",
|
5
|
+
"summary": "Reading, creating, and manipulating file archives",
|
6
|
+
"urls": {
|
7
|
+
"homepage": "https://projects.kde.org/projects/frameworks/karchive",
|
8
|
+
"vcs": "https://projects.kde.org/projects/frameworks/karchive/repository",
|
9
|
+
"mailing_list": "https://mail.kde.org/mailman/listinfo/kde-frameworks-devel",
|
10
|
+
"download": "http://download.kde.org/stable/frameworks/5.0.0/"
|
11
|
+
},
|
12
|
+
"licenses": [
|
13
|
+
"LGPLv2.1+"
|
14
|
+
],
|
15
|
+
"description": "KArchive provides classes for easy reading, creation and manipulation of\n\"archive\" formats like ZIP and TAR.\n\nIf also provides transparent compression and decompression of data, like the\nGZip format, via a subclass of QIODevice.",
|
16
|
+
"authors": [
|
17
|
+
"The KDE Community"
|
18
|
+
],
|
19
|
+
"platforms": [
|
20
|
+
"Linux"
|
21
|
+
],
|
22
|
+
"group": "kde-frameworks",
|
23
|
+
"maturity": "stable",
|
24
|
+
"release_date": "2014-07-07",
|
25
|
+
"version": "5.0.0",
|
26
|
+
"packages": {
|
27
|
+
"source": "http://download.kde.org/stable/frameworks/5.0.0/karchive-5.0.0.tar.xz"
|
28
|
+
}
|
29
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "http://inqlude.org/schema/release-manifest-v1#",
|
3
|
+
"name": "karchive",
|
4
|
+
"display_name": "KArchive",
|
5
|
+
"summary": "Reading, creating, and manipulating file archives",
|
6
|
+
"urls": {
|
7
|
+
"homepage": "https://projects.kde.org/projects/frameworks/karchive",
|
8
|
+
"vcs": "https://projects.kde.org/projects/frameworks/karchive/repository",
|
9
|
+
"mailing_list": "https://mail.kde.org/mailman/listinfo/kde-frameworks-devel",
|
10
|
+
"download": "ftp://ftp.kde.org/pub/kde/stable/karchive/"
|
11
|
+
},
|
12
|
+
"licenses": [
|
13
|
+
"LGPLv2.1+"
|
14
|
+
],
|
15
|
+
"description": "KArchive provides classes for easy reading, creation and manipulation of\n\"archive\" formats like ZIP and TAR.\n\nIf also provides transparent compression and decompression of data, like the\nGZip format, via a subclass of QIODevice.",
|
16
|
+
"authors": [
|
17
|
+
"The KDE Community"
|
18
|
+
],
|
19
|
+
"platforms": [
|
20
|
+
"Linux"
|
21
|
+
],
|
22
|
+
"group": "kde-frameworks",
|
23
|
+
"maturity": "alpha",
|
24
|
+
"release_date": "2014-03-04",
|
25
|
+
"version": "4.97.0",
|
26
|
+
"packages": {
|
27
|
+
"source": "ftp://ftp.kde.org/pub/kde/stable/karchive/karchive-4.97.0.tar.bz2"
|
28
|
+
}
|
29
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# KArchive
|
2
|
+
|
3
|
+
Reading, creation, and manipulation of file archives
|
4
|
+
|
5
|
+
## Introduction
|
6
|
+
|
7
|
+
KArchive provides classes for easy reading, creation and manipulation of
|
8
|
+
"archive" formats like ZIP and TAR.
|
9
|
+
|
10
|
+
If also provides transparent compression and decompression of data, like the
|
11
|
+
GZip format, via a subclass of QIODevice.
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
If you are using CMake, you need to have
|
16
|
+
|
17
|
+
find_package(KF5Archive NO_MODULE)
|
18
|
+
|
19
|
+
(or similar) in your CMakeLists.txt file, and you need to link any target that
|
20
|
+
uses KArchive against KF5::Archive.
|
21
|
+
|
22
|
+
If you want to read and write compressed data, just create an instance of
|
23
|
+
KCompressionDevice and write to or read from that.
|
24
|
+
|
25
|
+
If you want to read and write archive formats, create an instance of the
|
26
|
+
appropriate subclass of KArchive (eg: K7Zip for 7-Zip files). You may need to
|
27
|
+
combine this with usage of KCompressionDevice (see the API documentation for the
|
28
|
+
relevant KArchive subclass for details).
|
29
|
+
|
30
|
+
## Links
|
31
|
+
|
32
|
+
- Home page: <https://projects.kde.org/projects/frameworks/karchive>
|
33
|
+
- Mailing list: <https://mail.kde.org/mailman/listinfo/kde-frameworks-devel>
|
34
|
+
- IRC channel: #kde-devel on Freenode
|
35
|
+
- Git repository: <https://projects.kde.org/projects/frameworks/karchive/repository>
|