Skip to content

Commit 72630b4

Browse files
committed
Pull request #6: Command line wrapper
Merge in ADGUARD-IOS/safari-converter from feature/commandline to master * commit '540e7e378f273e58aa619a739ba15cba58744aad': updated readme updated readme github action github action command line wrapper stdin command line wrapper wrapped logger command line wrapper command line wrapper command line wrapper command line wrapper
2 parents a57eb93 + 540e7e3 commit 72630b4

File tree

9 files changed

+181
-7
lines changed

9 files changed

+181
-7
lines changed

.github/workflows/deploy.yml

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
name: Deploy
2+
3+
on:
4+
push:
5+
# Sequence of patterns matched against refs/tags
6+
tags:
7+
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
8+
jobs:
9+
build:
10+
runs-on: macOS-latest
11+
steps:
12+
- name: Checkout
13+
uses: actions/checkout@v2
14+
15+
- name: Build
16+
run: swift build -v
17+
18+
- name: Test
19+
run: swift test -v
20+
21+
- name: Build Release Binary
22+
run: swift build -v -c release
23+
24+
- name: Create Release
25+
id: create_release
26+
uses: actions/create-release@v1
27+
env:
28+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29+
with:
30+
tag_name: ${{ github.ref }}
31+
release_name: ${{ github.ref }}
32+
body: |
33+
- Updated converter binary
34+
draft: false
35+
prerelease: false
36+
37+
- name: Upload Release Asset
38+
id: upload-release-asset
39+
uses: actions/upload-release-asset@v1
40+
env:
41+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42+
with:
43+
upload_url: ${{ steps.create_release.outputs.upload_url }}
44+
asset_path: ./.build/release/ConverterTool
45+
asset_name: ConverterTool
46+
asset_content_type: application/macbinary
47+

Package.swift

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ let package = Package(
1111
name: "ContentBlockerConverter",
1212
type: .static,
1313
targets: ["ContentBlockerConverter"]),
14+
.executable(
15+
name: "ConverterTool",
16+
targets: ["CommandLineWrapper"])
1417
],
1518
dependencies: [
1619
// Dependencies declare other packages that this package depends on.
@@ -19,6 +22,9 @@ let package = Package(
1922
targets: [
2023
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
2124
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
25+
.target(
26+
name: "CommandLineWrapper",
27+
dependencies: ["ContentBlockerConverter"]),
2228
.target(
2329
name: "ContentBlockerConverter",
2430
dependencies: []),

README.md

+27
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@ Content Blocker converter swift code
88
Converts filter rules in AdGuard format to the format supported by Safari.
99
* https://webkit.org/blog/3476/content-blockers-first-look/
1010

11+
### How to build:
12+
13+
```
14+
swift build
15+
```
16+
17+
### Tests:
18+
19+
```
20+
swift test
21+
```
22+
1123
### How to use converter:
1224

1325
```
@@ -24,6 +36,21 @@ The result contains following properties:
2436
- converted: json string of content blocker rules
2537
- advancedBlocking: json string of advanced blocking rules
2638

39+
### How to use converter from command line:
40+
41+
```
42+
./ConverterTool -limit=0 -optimize=true -advancedBlocking=false <<STDIN -o other --options
43+
test_rule_one
44+
test_rule_two
45+
STDIN
46+
```
47+
48+
The tool then reads stdin line by line for rule until an empty line.
49+
50+
### How to release on Github
51+
52+
Push a new tag in `v*.*.*` format, then provided github action is intended to build and publish new release with an asset binary.
53+
2754
### Supported AdGuard rules types:
2855

2956
#### Basic content blocker format:

Sources/CommandLineWrapper/main.swift

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import Foundation
2+
import ContentBlockerConverter
3+
4+
/**
5+
* Command line wrapper
6+
* Usage:
7+
* ./CommandLineWrapper -limit=0 -optimize=true -advancedBlocking=false
8+
*/
9+
10+
func writeToStdError(str: String) {
11+
let handle = FileHandle.standardError;
12+
13+
if let data = str.data(using: String.Encoding.utf8, allowLossyConversion: false) {
14+
handle.write(data)
15+
}
16+
}
17+
18+
func writeToStdOut(str: String) {
19+
let handle = FileHandle.standardOutput;
20+
21+
if let data = str.data(using: String.Encoding.utf8, allowLossyConversion: false) {
22+
handle.write(data)
23+
}
24+
}
25+
26+
func encodeJson(_ result: ConversionResult) throws -> String {
27+
let encoder = JSONEncoder();
28+
encoder.outputFormatting = .prettyPrinted
29+
30+
let json = try encoder.encode(result);
31+
return String(data: json, encoding: .utf8)!.replacingOccurrences(of: "\\/", with: "/");
32+
}
33+
34+
do {
35+
Logger.log("AG: Conversion started");
36+
37+
let arguments: [String] = CommandLine.arguments;
38+
if (arguments.count < 4) {
39+
writeToStdError(str: "AG: Invalid arguments: Usage: ./CommandLineWrapper -limit=0 -optimize=false -advancedBlocking)");
40+
exit(EXIT_FAILURE);
41+
}
42+
43+
let limit = Int(arguments[1][String.Index(encodedOffset: 7)...]) ?? 0;
44+
Logger.log("AG: Limit: \(limit)");
45+
46+
let optimize = arguments[2] == "-optimize=true";
47+
Logger.log("AG: Optimize: \(optimize)");
48+
49+
let advancedBlocking = arguments[3] == "-advancedBlocking=true";
50+
Logger.log("AG: AdvancedBlocking: \(advancedBlocking)");
51+
52+
var rules = [String]();
53+
var line: String? = nil;
54+
while (true) {
55+
line = readLine(strippingNewline: true);
56+
if (line == nil || line == "") {
57+
break;
58+
}
59+
60+
rules.append(line!);
61+
}
62+
63+
Logger.log("AG: Rules to convert: \(rules.count)");
64+
65+
let result: ConversionResult? = ContentBlockerConverter().convertArray(
66+
rules: rules, limit: limit, optimize: optimize, advancedBlocking: advancedBlocking
67+
);
68+
69+
Logger.log("AG: Conversion done");
70+
71+
if (result == nil) {
72+
writeToStdError(str: "AG: ContentBlockerConverter: Empty result.");
73+
exit(EXIT_FAILURE);
74+
}
75+
76+
let encoded = try encodeJson(result!);
77+
78+
writeToStdOut(str: "\(encoded)");
79+
exit(EXIT_SUCCESS);
80+
} catch {
81+
writeToStdError(str: "AG: ContentBlockerConverter: Unexpected error: \(error)");
82+
exit(EXIT_FAILURE);
83+
}
84+

Sources/ContentBlockerConverter/Compiler/BlockerEntryFactory.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class BlockerEntryFactory {
7272
}
7373
} catch {
7474
self.errorsCounter.add();
75-
NSLog("AG: ContentBlockerConverter: Unexpected error: \(error) while converting \(rule.ruleText)");
75+
Logger.log("AG: ContentBlockerConverter: Unexpected error: \(error) while converting \(rule.ruleText)");
7676
}
7777

7878
return nil;

Sources/ContentBlockerConverter/ContentBlockerConverter.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public class ContentBlockerConverter {
1414
*/
1515
public func convertArray(rules: [String], limit: Int = 0, optimize: Bool = false, advancedBlocking: Bool = false) -> ConversionResult? {
1616
if rules.count == 0 {
17-
NSLog("AG: ContentBlockerConverter: No rules presented");
17+
Logger.log("AG: ContentBlockerConverter: No rules presented");
1818
return nil;
1919
}
2020

@@ -34,7 +34,7 @@ public class ContentBlockerConverter {
3434

3535
return try Distributor(limit: limit, advancedBlocking: advancedBlocking).createConversionResult(data: compilationResult);
3636
} catch {
37-
NSLog("AG: ContentBlockerConverter: Unexpected error: \(error)");
37+
Logger.log("AG: ContentBlockerConverter: Unexpected error: \(error)");
3838
}
3939

4040
return nil;
@@ -59,6 +59,6 @@ public class ContentBlockerConverter {
5959
message += "\nExceptions (jsinject): \(String(describing: compilationResult.scriptJsInjectExceptions.count))";
6060
message += "\nExceptions (other): \(String(describing: compilationResult.other.count))";
6161

62-
NSLog("AG: ContentBlockerConverter: " + message);
62+
Logger.log("AG: ContentBlockerConverter: " + message);
6363
}
6464
}

Sources/ContentBlockerConverter/ConversionResult.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Foundation
33
/**
44
* Conversion result wrapper class
55
*/
6-
public struct ConversionResult {
6+
public struct ConversionResult: Encodable {
77
/**
88
* Total entries count in result
99
*/
@@ -49,7 +49,7 @@ public struct ConversionResult {
4949
if self.overLimit {
5050
limitedEntries = Array(entries.prefix(limit));
5151

52-
NSLog("AG: ContentBlockerConverter: The limit is reached. Overlimit rules will be ignored.");
52+
Logger.log("AG: ContentBlockerConverter: The limit is reached. Overlimit rules will be ignored.");
5353
}
5454

5555
self.convertedCount = limitedEntries.count;

Sources/ContentBlockerConverter/Rules/RuleFactory.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class RuleFactory {
8383

8484
return try NetworkRule(ruleText: ruleText!);
8585
} catch {
86-
NSLog("AG: ContentBlockerConverter: Unexpected error: \(error) while creating rule from: \(String(describing: ruleText))");
86+
Logger.log("AG: ContentBlockerConverter: Unexpected error: \(error) while creating rule from: \(String(describing: ruleText))");
8787
throw error;
8888
}
8989
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* Logger
3+
*/
4+
public class Logger {
5+
public static func log(_ message: String) {
6+
#if DEBUG
7+
print("AG: \(message)")
8+
#endif
9+
}
10+
}

0 commit comments

Comments
 (0)