Initial commit.
This commit is contained in:
commit
8eb7a7ce99
17 changed files with 913 additions and 0 deletions
88
.gitignore
vendored
Normal file
88
.gitignore
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
!.vscode/extensions.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
*.class
|
||||
*.code-workspace
|
||||
*.ctxt
|
||||
*.iws
|
||||
*.log
|
||||
*.nar
|
||||
*.rar
|
||||
*.sublime-*
|
||||
*.tar.gz
|
||||
*.zip
|
||||
.DS_Store
|
||||
.classpath
|
||||
.dart_tool/
|
||||
.gradle
|
||||
.history
|
||||
.kobalt
|
||||
.mtj.tmp/
|
||||
.mvn/timing.properties
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
.nb-gradle
|
||||
.packages
|
||||
.project
|
||||
.scannerwork
|
||||
.settings
|
||||
.vscode/*
|
||||
/**/.idea/$CACHE_FILE$
|
||||
/**/.idea/$PRODUCT_WORKSPACE_FILE$
|
||||
/**/.idea/**/caches/build_file_checksums.ser
|
||||
/**/.idea/**/contentModel.xml
|
||||
/**/.idea/**/dataSources.ids
|
||||
/**/.idea/**/dataSources.local.xml
|
||||
/**/.idea/**/dataSources/
|
||||
/**/.idea/**/dbnavigator.xml
|
||||
/**/.idea/**/dictionaries
|
||||
/**/.idea/**/dynamic.xml
|
||||
/**/.idea/**/gradle.xml
|
||||
/**/.idea/**/httpRequests
|
||||
/**/.idea/**/libraries
|
||||
/**/.idea/**/mongoSettings.xml
|
||||
/**/.idea/**/replstate.xml
|
||||
/**/.idea/**/shelf
|
||||
/**/.idea/**/shelf/
|
||||
/**/.idea/**/sqlDataSources.xml
|
||||
/**/.idea/**/tasks.xml
|
||||
/**/.idea/**/uiDesigner.xml
|
||||
/**/.idea/**/usage.statistics.xml
|
||||
/**/.idea/**/workspace.xml
|
||||
/**/.idea/sonarlint*
|
||||
/**/.idea_modules/
|
||||
Thumbs.db
|
||||
__pycache__
|
||||
atlassian-ide-plugin.xml
|
||||
bin/dcat
|
||||
bin/dcat.exe
|
||||
build/
|
||||
cmake-build-*/
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics-build.properties
|
||||
crashlytics.properties
|
||||
dependency-reduced-pom.xml
|
||||
deploy/
|
||||
dist/
|
||||
ehthumbs.db
|
||||
fabric.properties
|
||||
gen/
|
||||
gradle.properties
|
||||
hs_err_pid*
|
||||
kobaltBuild
|
||||
kobaltw*-test
|
||||
lib/kotlin*
|
||||
libs/
|
||||
local.properties
|
||||
out/
|
||||
pom.xml.asc
|
||||
pom.xml.next
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.tag
|
||||
pom.xml.versionsBackup
|
||||
proguard-project.txt
|
||||
project.properties
|
||||
release.properties
|
||||
target/
|
||||
test-output
|
||||
venv
|
3
.idea/.gitignore
generated
vendored
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
43
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
43
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
|
@ -0,0 +1,43 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="TOP_LEVEL_CLASS_OPTIONS">
|
||||
<value>
|
||||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
<option name="REQUIRED_TAGS" value="" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="INNER_CLASS_OPTIONS">
|
||||
<value>
|
||||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
<option name="REQUIRED_TAGS" value="" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="METHOD_OPTIONS">
|
||||
<value>
|
||||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="FIELD_OPTIONS">
|
||||
<value>
|
||||
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||
<option name="REQUIRED_TAGS" value="" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="IGNORE_DEPRECATED" value="false" />
|
||||
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
|
||||
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
|
||||
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
|
||||
<option name="myAdditionalJavadocTags" value="created" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="LocalCanBeFinal" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="REPORT_VARIABLES" value="true" />
|
||||
<option name="REPORT_PARAMETERS" value="true" />
|
||||
<option name="REPORT_CATCH_PARAMETERS" value="false" />
|
||||
<option name="REPORT_IMPLICIT_FINALS" value="false" />
|
||||
</inspection_tool>
|
||||
<inspection_tool class="RedundantExplicitVariableType" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
6
.idea/misc.xml
generated
Normal file
6
.idea/misc.xml
generated
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/dcat.iml" filepath="$PROJECT_DIR$/dcat.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
10
.idea/runConfigurations.xml
generated
Normal file
10
.idea/runConfigurations.xml
generated
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
3
CHANGELOG.md
Normal file
3
CHANGELOG.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
## 1.0.0
|
||||
|
||||
- Initial version.
|
29
LICENSE
Normal file
29
LICENSE
Normal file
|
@ -0,0 +1,29 @@
|
|||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2021, Erik C. Thauvin (erik@thauvin.net)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of this project nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
2
README.md
Normal file
2
README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
Concatenate file(s) to standard output.
|
||||
|
30
analysis_options.yaml
Normal file
30
analysis_options.yaml
Normal file
|
@ -0,0 +1,30 @@
|
|||
# This file configures the static analysis results for your project (errors,
|
||||
# warnings, and lints).
|
||||
#
|
||||
# This enables the 'recommended' set of lints from `package:lints`.
|
||||
# This set helps identify many issues that may lead to problems when running
|
||||
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
|
||||
# style and format.
|
||||
#
|
||||
# If you want a smaller set of lints you can change this to specify
|
||||
# 'package:lints/core.yaml'. These are just the most critical lints
|
||||
# (the recommended set includes the core lints).
|
||||
# The core lints are also what is used by pub.dev for scoring packages.
|
||||
|
||||
include: package:lints/recommended.yaml
|
||||
|
||||
# Uncomment the following section to specify additional rules.
|
||||
|
||||
# linter:
|
||||
# rules:
|
||||
# - camel_case_types
|
||||
|
||||
# analyzer:
|
||||
# exclude:
|
||||
# - path/to/excluded/files/**
|
||||
|
||||
# For more information about the core and recommended set of lints, see
|
||||
# https://dart.dev/go/core-lints
|
||||
|
||||
# For additional information about configuring this file, see
|
||||
# https://dart.dev/guides/language/analysis-options
|
200
bin/dcat.dart
Normal file
200
bin/dcat.dart
Normal file
|
@ -0,0 +1,200 @@
|
|||
// Copyright (c) 2021, Erik C. Thauvin. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be found
|
||||
// in the LICENSE file.
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
import 'package:indent/indent.dart';
|
||||
|
||||
const appName = 'dcat';
|
||||
const appVersion = '1.0.0';
|
||||
const exitFailure = 1;
|
||||
const exitSuccess = 0;
|
||||
const helpFlag = 'help';
|
||||
const nonBlankFlag = 'number-nonblank';
|
||||
const numberFlag = 'number';
|
||||
const showEndsFlag = 'show-ends';
|
||||
const showTabsFlag = 'show-tabs';
|
||||
const squeezeBlank = 'squeeze-blank';
|
||||
const versionFlag = 'version';
|
||||
|
||||
/// Prints [message] and [path] to stderr.
|
||||
Future<int> handleError(String message, {String path = ''}) async {
|
||||
if (path.isNotEmpty) {
|
||||
stderr.writeln('$appName: $path: $message');
|
||||
} else {
|
||||
stderr.write('$appName: $message');
|
||||
}
|
||||
return exitFailure;
|
||||
}
|
||||
|
||||
/// Concatenates files in [paths].
|
||||
Future<int> cat(List<String> paths,
|
||||
{List<String>? log,
|
||||
bool showEnds = false,
|
||||
bool numberNonBlank = false,
|
||||
bool showLineNumbers = false,
|
||||
bool showTabs = false,
|
||||
bool squeezeBlank = false}) async {
|
||||
var lineNumber = 1;
|
||||
var returnCode = 0;
|
||||
log?.clear();
|
||||
if (paths.isEmpty) {
|
||||
final lines = await _readStdin();
|
||||
await _writeLines(lines, lineNumber, log, showEnds, showLineNumbers,
|
||||
numberNonBlank, showTabs, squeezeBlank);
|
||||
} else {
|
||||
for (final path in paths) {
|
||||
try {
|
||||
final Stream<String> lines;
|
||||
if (path == '-') {
|
||||
lines = await _readStdin();
|
||||
} else {
|
||||
lines = utf8.decoder
|
||||
.bind(File(path).openRead())
|
||||
.transform(const LineSplitter());
|
||||
}
|
||||
lineNumber = await _writeLines(lines, lineNumber, log, showEnds,
|
||||
showLineNumbers, numberNonBlank, showTabs, squeezeBlank);
|
||||
} on FileSystemException catch (e) {
|
||||
final String? osMessage = e.osError?.message;
|
||||
final String message;
|
||||
if (osMessage != null && osMessage.isNotEmpty) {
|
||||
message = osMessage;
|
||||
} else {
|
||||
message = e.message;
|
||||
}
|
||||
returnCode = await handleError(message, path: path);
|
||||
} on FormatException {
|
||||
returnCode =
|
||||
await handleError('Binary file not supported.', path: path);
|
||||
} catch (e) {
|
||||
returnCode = await handleError(e.toString(), path: path);
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
/// Concatenates files specified in [arguments].
|
||||
///
|
||||
/// ```
|
||||
/// dcat [OPTION]... [FILE]...
|
||||
/// ```
|
||||
Future<int> main(List<String> arguments) async {
|
||||
final parser = ArgParser();
|
||||
Future<int> returnCode;
|
||||
exitCode = exitSuccess;
|
||||
parser.addFlag(nonBlankFlag,
|
||||
negatable: false,
|
||||
abbr: 'b',
|
||||
help: 'number nonempty output lines, overrides -n');
|
||||
parser.addFlag(showEndsFlag,
|
||||
negatable: false, abbr: 'E', help: 'display \$ at end of each line');
|
||||
parser.addFlag(helpFlag,
|
||||
negatable: false, abbr: 'h', help: 'display this help and exit');
|
||||
parser.addFlag(numberFlag,
|
||||
negatable: false, abbr: 'n', help: 'number all output lines');
|
||||
parser.addFlag(showTabsFlag,
|
||||
negatable: false, abbr: 'T', help: 'display TAB characters as ^I');
|
||||
parser.addFlag(squeezeBlank,
|
||||
negatable: false,
|
||||
abbr: 's',
|
||||
help: 'suppress repeated empty output lines');
|
||||
parser.addFlag(versionFlag,
|
||||
negatable: false, help: 'output version information and exit');
|
||||
|
||||
final ArgResults argResults;
|
||||
try {
|
||||
argResults = parser.parse(arguments);
|
||||
} on FormatException catch (e) {
|
||||
return await handleError(
|
||||
"${e.message}\nTry '$appName --$helpFlag' for more information.");
|
||||
}
|
||||
|
||||
if (argResults[helpFlag]) {
|
||||
returnCode = usage(parser.usage);
|
||||
} else if (argResults[versionFlag]) {
|
||||
returnCode = printVersion();
|
||||
} else {
|
||||
final paths = argResults.rest;
|
||||
returnCode = cat(paths,
|
||||
showEnds: argResults[showEndsFlag],
|
||||
showLineNumbers: argResults[numberFlag],
|
||||
numberNonBlank: argResults[nonBlankFlag],
|
||||
showTabs: argResults[showTabsFlag],
|
||||
squeezeBlank: argResults[squeezeBlank]);
|
||||
}
|
||||
|
||||
exitCode = await returnCode;
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
/// Prints version info.
|
||||
Future<int> printVersion() async {
|
||||
print('''$appName (Dart cat) $appVersion
|
||||
Copyright (C) 2021 Erik C. Thauvin
|
||||
License: 3-Clause BSD <https://opensource.org/licenses/BSD-3-Clause>
|
||||
|
||||
Based on <https://dart.dev/tutorials/server/cmdline>
|
||||
Written by Erik C. Thauvin <https://erik.thauvin.net/>''');
|
||||
return exitSuccess;
|
||||
}
|
||||
|
||||
/// Reads from stdin.
|
||||
Future<Stream<String>> _readStdin() async =>
|
||||
stdin.transform(utf8.decoder).transform(const LineSplitter());
|
||||
|
||||
/// Prints usage with [options].
|
||||
Future<int> usage(String options) async {
|
||||
print('''Usage: $appName [OPTION]... [FILE]...
|
||||
Concatenate FILE(s) to standard output.
|
||||
|
||||
With no FILE, or when FILE is -, read standard input.
|
||||
|
||||
${options.indent(2)}
|
||||
Examples:
|
||||
$appName f - g Output f's contents, then standard input, then g's contents.
|
||||
$appName Copy standard input to standard output.
|
||||
|
||||
Source and documentation: <https://github.com/ethauvin/dcat>''');
|
||||
return exitSuccess;
|
||||
}
|
||||
|
||||
/// Writes lines to stdout.
|
||||
Future<int> _writeLines(Stream<String> lines, int lineNumber,
|
||||
[List<String>? log,
|
||||
bool showEnds = false,
|
||||
bool showLineNumbers = false,
|
||||
bool showNonBlank = false,
|
||||
bool showTabs = false,
|
||||
bool sqeezeBlank = false]) async {
|
||||
var emptyLine = 0;
|
||||
final sb = StringBuffer();
|
||||
await for (final line in lines) {
|
||||
sb.clear();
|
||||
if (sqeezeBlank && line.isEmpty) {
|
||||
if (++emptyLine >= 2) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
emptyLine = 0;
|
||||
}
|
||||
if (showNonBlank || showLineNumbers) {
|
||||
sb.write('${lineNumber++}: ');
|
||||
}
|
||||
if (showTabs) {
|
||||
sb.write(line.replaceAll('\t', '^I'));
|
||||
} else {
|
||||
sb.write(line);
|
||||
}
|
||||
if (showEnds) {
|
||||
sb.write('\$');
|
||||
}
|
||||
|
||||
log?.add(sb.toString());
|
||||
stdout.writeln(sb);
|
||||
}
|
||||
return lineNumber;
|
||||
}
|
14
dcat.iml
Normal file
14
dcat.iml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.pub" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
|
||||
</content>
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Dart SDK" level="project" />
|
||||
<orderEntry type="library" name="Dart Packages" level="project" />
|
||||
</component>
|
||||
</module>
|
348
pubspec.lock
Normal file
348
pubspec.lock
Normal file
|
@ -0,0 +1,348 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
_fe_analyzer_shared:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "28.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.5.0"
|
||||
args:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: args
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.8.2"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.4"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.2"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: frontend_server_client
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
indent:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: indent
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.3"
|
||||
lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.11"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_preamble
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pool
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.5.0"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
shelf_packages_handler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_packages_handler
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
shelf_static:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_static
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.10"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.1"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
test:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: test
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.18.2"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.5"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.5"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.3.0"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webkit_inspection_protocol
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.0"
|
||||
sdks:
|
||||
dart: ">=2.14.3 <3.0.0"
|
14
pubspec.yaml
Normal file
14
pubspec.yaml
Normal file
|
@ -0,0 +1,14 @@
|
|||
name: dcat
|
||||
description: Concatenate file(s) to standard output.
|
||||
version: 1.0.0
|
||||
homepage: https://github.com/ethauvin/dcat
|
||||
|
||||
environment:
|
||||
sdk: '>=2.14.3 <3.0.0'
|
||||
|
||||
dev_dependencies:
|
||||
lints: ^1.0.0
|
||||
test: ^1.18.2
|
||||
dependencies:
|
||||
args: ^2.3.0
|
||||
indent: ^2.0.0
|
102
test/dcat_test.dart
Normal file
102
test/dcat_test.dart
Normal file
|
@ -0,0 +1,102 @@
|
|||
import 'package:test/test.dart';
|
||||
|
||||
import '../bin/dcat.dart' as dcat;
|
||||
|
||||
void main() {
|
||||
final List<String> log = [];
|
||||
int exitCode;
|
||||
|
||||
test('Test Help', () async {
|
||||
expect(dcat.main(['-h']), completion(equals(0)));
|
||||
expect(dcat.main(['--help']), completion(equals(0)));
|
||||
exitCode = await dcat.main(['-h']);
|
||||
expect(exitCode, equals(dcat.exitSuccess));
|
||||
});
|
||||
|
||||
test('Test --version', () async {
|
||||
expect(dcat.main(['--version']), completion(equals(0)));
|
||||
exitCode = await dcat.main(['--version']);
|
||||
expect(exitCode, equals(dcat.exitSuccess));
|
||||
});
|
||||
|
||||
test('Test directory', () async {
|
||||
exitCode = await dcat.main(['bin']);
|
||||
expect(exitCode, equals(dcat.exitFailure));
|
||||
});
|
||||
|
||||
test('Test missing file', () async {
|
||||
exitCode = await dcat.main(['foo']);
|
||||
expect(exitCode, equals(dcat.exitFailure), reason: 'foo not found');
|
||||
exitCode = await dcat.main(['bin/dcat.dart', 'foo']);
|
||||
expect(exitCode, equals(dcat.exitFailure), reason: 'one missing file');
|
||||
});
|
||||
|
||||
test('Test cat source', () async {
|
||||
await dcat.cat(['bin/dcat.dart'], log: log);
|
||||
expect(log.isEmpty, false, reason: 'log is empty');
|
||||
expect(log.first, startsWith('// Copyright (c)'), reason: 'has copyright');
|
||||
expect(log.last, equals('}'));
|
||||
});
|
||||
|
||||
test('Test cat -n source', () async {
|
||||
exitCode =
|
||||
await dcat.cat(['bin/dcat.dart'], log: log, showLineNumbers: true);
|
||||
expect(exitCode, 0, reason: 'result code is 0');
|
||||
expect(log.first, startsWith('1: // Copyright (c)'),
|
||||
reason: 'has copyright');
|
||||
expect(log.last, endsWith(': }'), reason: 'last line');
|
||||
for (final String line in log) {
|
||||
expect(line, matches('^\\d+: .*'), reason: 'has line number');
|
||||
}
|
||||
});
|
||||
|
||||
test('Test cat -E', () async {
|
||||
await dcat.cat(['test/test.txt'], log: log, showEnds: true);
|
||||
var hasBlank = false;
|
||||
for (final String line in log) {
|
||||
expect(line, endsWith('\$'));
|
||||
if (line == '\$') {
|
||||
hasBlank = true;
|
||||
}
|
||||
}
|
||||
expect(hasBlank, true, reason: 'has blank line');
|
||||
});
|
||||
|
||||
test('Test cat -bE', () async {
|
||||
await dcat
|
||||
.cat(['test/test.txt'], log: log, numberNonBlank: true, showEnds: true);
|
||||
var hasBlank = false;
|
||||
for (final String line in log) {
|
||||
expect(line, endsWith('\$'));
|
||||
if (line.contains(RegExp(r'^\d+: .*\$$'))) {
|
||||
hasBlank = true;
|
||||
}
|
||||
}
|
||||
expect(hasBlank, true, reason: 'has blank line');
|
||||
});
|
||||
|
||||
test('Test cat -T', () async {
|
||||
await dcat.cat(['test/test.txt'], log: log, showTabs: true);
|
||||
var hasTab = false;
|
||||
for (final String line in log) {
|
||||
if (line.startsWith('^I')) {
|
||||
hasTab = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect(hasTab, true, reason: 'has tab');
|
||||
});
|
||||
|
||||
test('Test cat -s', () async {
|
||||
await dcat.cat(['test/test.txt'], log: log, squeezeBlank: true);
|
||||
var hasSqueeze = true;
|
||||
var prevLine = 'foo';
|
||||
for (final String line in log) {
|
||||
if (line == prevLine) {
|
||||
hasSqueeze = false;
|
||||
}
|
||||
prevLine = line;
|
||||
}
|
||||
expect(hasSqueeze, true, reason: 'has squeeze');
|
||||
});
|
||||
}
|
7
test/test.txt
Normal file
7
test/test.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||
|
||||
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
||||
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
|
||||
|
||||
|
||||
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
Loading…
Add table
Add a link
Reference in a new issue