Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Analyze/test cmdline tutorial code excerpts #1902

Merged
merged 4 commits into from
Sep 19, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/misc/analyzer-2-results.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Analyzing analysis_options.yaml, lib, test...
Analyzing analysis_options.yaml, bin, lib, test...
# https://github.com/dart-lang/sdk/issues/32236 - flow analysis can't yet figure out that the variable is of type Person.
error • 'Object' doesn't extend 'SomeBaseClass' at lib/language_tour/generics/misc.dart:29:19 • type_argument_not_matching_bounds
error • The argument type 'int' can't be assigned to the parameter type 'String' at lib/library_tour/core/collections.dart:5:14 • argument_type_not_assignable
Expand Down
96 changes: 96 additions & 0 deletions examples/misc/bin/dcat.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// IMPORTANT NOTE:
// 1. If you change this file, ensure that the associated tooltip data remains
// valid (*_tooltips.html).
// 2. Regenerate the HTML version of this sample, by running
// tool/create_code_with_tooltips.dart
// 3. To generate the DartPad version: (1) delete lines containly only tip
// instructions. (2) Trim //!foo markers from the end of the remaining lines,
// e.g., using this Perl regexp: / ?\/\/!.*//g

import 'dart:convert';
import 'dart:io';

import 'package:args/args.dart';

const lineNumber = 'line-number';

// #docregion arg-processing
ArgResults argResults;
// #enddocregion arg-processing

/// Simple implementation of the *nix cat utility. //!web-only
/// //!web-only
/// Usage: dart dcat.dart [-n] patterns files //!web-only
/// //!web-only
/// `dcat` reads `files` sequentially, writing them to standard output. The //!web-only
/// file operands are processed in command-line order. //!web-only
/// If `files` is absent, `dcat` reads from the standard input until `EOF`. //!web-only
/// //!web-only
/// Unlike the *nix `cat`, `dcat` does not support single dash ('-') arguments. //!web-only
// #docregion arg-processing
//!tip("List<String> arguments")
void main(List<String> arguments) {
exitCode = 0; // presume success
final parser = ArgParser()
..addFlag(lineNumber, negatable: false, abbr: 'n');

//!tip("argResults = parser.parse(arguments)")
argResults = parser.parse(arguments);
final paths = argResults.rest;

dcat(paths, argResults[lineNumber] as bool);
}
// #enddocregion arg-processing

//!tip("async")
Future dcat(List<String> paths, bool showLineNumbers) async {
if (paths.isEmpty) {
// No files provided as arguments. Read from stdin and print each line.
// #docregion pipe
//!tip("stdin.pipe(stdout)") //!tip("await")
await stdin.pipe(stdout);
// #enddocregion pipe
} else {
// #docregion for-path
for (var path in paths) {
var lineNumber = 1;
final lines = utf8.decoder
//!tip("openRead()") //!tip("File(path)")
.bind(File(path).openRead())
//!tip("transform(const LineSplitter())")
.transform(const LineSplitter());
//!tip("try")
try {
//!tip("await for (var line in lines)")
await for (var line in lines) {
// #docregion showLineNumbers
if (showLineNumbers) {
stdout.write('${lineNumber++} ');
}
stdout.writeln(line);
// #enddocregion showLineNumbers
}
//!tip("catch")
} catch (_) {
await _handleError(path);
}
}
// #enddocregion for-path
}
}

// #docregion _handleError
Future _handleError(String path) async {
//!tip("await FileSystemEntity.isDirectory(path)")
// #docregion await-FileSystemEntity
if (await FileSystemEntity.isDirectory(path)) {
stderr.writeln('error: $path is a directory');
} else {
exitCode = 2; //!tip("exitCode = 2")
}
// #enddocregion await-FileSystemEntity
}
12 changes: 12 additions & 0 deletions examples/misc/bin/dcat1.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// #docregion
import 'dart:io';

void main() {
stdout.writeln('Type something');
String input = stdin.readLineSync();
stdout.writeln('You typed: $input');
}
53 changes: 53 additions & 0 deletions examples/misc/bin/dcat_tooltips.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<!--
Tooltip data.

Source file: dcat.dart

Ensure that:
- Each //!tip() entry in the source file has a corresponding entry below (an
entry with a `name` attribute that matches the //!tip() text), in the same
order as in the source file.
- Each entry below has a corresponding //!tip() entry in the source file.
-->
<ul class="fp-tooltips" style="display: none">
<li name="List<String> arguments" title="Command-line arguments">
Command-line arguments are passed in by the system when the program starts.
</li>
<li name="argResults = parser.parse(arguments)" title="Arguments parser">
The <code>ArgParser</code> class provides help with parsing command-line arguments.
</li>
<li name="async" title="Async function">
A function marked as <code>async</code>. These functions are asynchronous and return futures.
</li>
<li name="await" title="Using await">
The <code>await</code> keyword, which works only in <code>async</code> functions,
makes the program pause until the following expression completes.
</li>
<li name="stdin.pipe(stdout)" title="Standard I/O streams">
This line reads from the standard input stream and pipes the data to the standard output stream.
</li>
<li name="File(path)" title="Create a File object">
Use the <code>File</code> class to represent the file on the native file system.
</li>
<li name="openRead()" title="Open a file for reading">
Read the content from the file asynchronously.
</li>
<li name="transform(const LineSplitter())" title="Data converters">
Convert data as it becomes available on the stream.
</li>
<li name="try" title="Exception handling">
Function calls that might generate an exception are placed in a <code>try</code> block.
</li>
<li name="await for (var line in lines)" title="Get data from the stream">
Use <code>await for</code> to loop over the values as they become available on the stream. The program pauses while waiting for the next line.
</li>
<li name="catch" title="Exception handling">
Any errors encountered in the stream are handled in the <code>catch</code> block.
</li>
<li name="await FileSystemEntity.isDirectory(path)" title="Test the path">
You can get information about the file system on which your program is running. The <code>await</code> keyword causes error handling to pause until the path is available.
</li>
<li name="exitCode = 2" title="Exit code">
A well-behaved command-line app sets an exit code to indicate whether the program was successful.
</li>
</ul>
45 changes: 45 additions & 0 deletions examples/misc/lib/tutorial/cmdline.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import 'dart:io';

void printEnvVar() {
// #docregion env
final envVarMap = Platform.environment;

print('PWD = ${envVarMap["PWD"]}');
print('LOGNAME = ${envVarMap["LOGNAME"]}');
print('PATH = ${envVarMap["PATH"]}');
// #enddocregion env
}

Future writeQuote() async {
// #docregion write-quote
final quotes = File('quotes.txt');
const stronger = 'That which does not kill us makes us stronger. -Nietzsche';

await quotes.writeAsString(stronger, mode: FileMode.append);
// #enddocregion write-quote
print('Data written.');
}

Future writeQuotes() async {
// #docregion write-quotes
final quotes = File('quotes.txt').openWrite(mode: FileMode.append);

quotes.write("Don't cry because it's over, ");
quotes.writeln("smile because it happened. -Dr. Seuss");
await quotes.close();
// #enddocregion write-quotes
print('Done!');
}

// Not currently used
Future writeQuoteTryCatch() async {
final quotesFile = File('quotes.txt');
const stronger = 'That which does not kill us makes us stronger. -Nietzsche';

try {
await quotesFile.writeAsString(stronger, mode: FileMode.append);
print('Data written.');
} catch (e) {
print('Oops!');
}
}
1 change: 1 addition & 0 deletions examples/misc/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ environment:
sdk: '>=2.5.0 <3.0.0'

dev_dependencies:
args: any
chalin marked this conversation as resolved.
Show resolved Hide resolved
test: ^1.0.0
pedantic: ^1.0.0
dartlang_examples_util:
Expand Down
57 changes: 57 additions & 0 deletions src/_tutorials/server/_dcat-example.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{%- comment %}
WARNING: Do NOT EDIT this file directly. It is autogenerated by
tool/create_code_with_tooltips.dart
from sources in the example folder.
{% endcomment -%}
<pre class="prettyprint lang-dart">
import 'dart:convert';
import 'dart:io';

import 'package:args/args.dart';

const lineNumber = 'line-number';

ArgResults argResults;

void main(<a tabindex="0" role="button" data-toggle="popover" title="Command-line arguments" data-content="Command-line arguments are passed in by the system when the program starts.">List&lt;String&gt; arguments</a>) {
exitCode = 0; // presume success
final parser = ArgParser()
..addFlag(lineNumber, negatable: false, abbr: 'n');

<a tabindex="0" role="button" data-toggle="popover" title="Arguments parser" data-content="The <code>ArgParser</code> class provides help with parsing command-line arguments.">argResults = parser.parse(arguments)</a>;
final paths = argResults.rest;

dcat(paths, argResults[lineNumber] as bool);
}

Future dcat(List&lt;String&gt; paths, bool showLineNumbers) <a tabindex="0" role="button" data-toggle="popover" title="Async function" data-content="A function marked as <code>async</code>. These functions are asynchronous and return futures.">async</a> {
if (paths.isEmpty) {
// No files provided as arguments. Read from stdin and print each line.
<a tabindex="0" role="button" data-toggle="popover" title="Using await" data-content="The <code>await</code> keyword, which works only in <code>async</code> functions, makes the program pause until the following expression completes.">await</a> <a tabindex="0" role="button" data-toggle="popover" title="Standard I/O streams" data-content="This line reads from the standard input stream and pipes the data to the standard output stream.">stdin.pipe(stdout)</a>;
} else {
for (var path in paths) {
var lineNumber = 1;
final lines = utf8.decoder
.bind(<a tabindex="0" role="button" data-toggle="popover" title="Create a File object" data-content="Use the <code>File</code> class to represent the file on the native file system.">File(path)</a>.<a tabindex="0" role="button" data-toggle="popover" title="Open a file for reading" data-content="Read the content from the file asynchronously.">openRead()</a>)
.<a tabindex="0" role="button" data-toggle="popover" title="Data converters" data-content="Convert data as it becomes available on the stream.">transform(const LineSplitter())</a>;
<a tabindex="0" role="button" data-toggle="popover" title="Exception handling" data-content="Function calls that might generate an exception are placed in a <code>try</code> block.">try</a> {
<a tabindex="0" role="button" data-toggle="popover" title="Get data from the stream" data-content="Use <code>await for</code> to loop over the values as they become available on the stream. The program pauses while waiting for the next line.">await for (var line in lines)</a> {
if (showLineNumbers) {
stdout.write('${lineNumber++} ');
}
stdout.writeln(line);
}
} <a tabindex="0" role="button" data-toggle="popover" title="Exception handling" data-content="Any errors encountered in the stream are handled in the <code>catch</code> block.">catch</a> (_) {
await _handleError(path);
}
}
}
}

Future _handleError(String path) async {
if (<a tabindex="0" role="button" data-toggle="popover" title="Test the path" data-content="You can get information about the file system on which your program is running. The <code>await</code> keyword causes error handling to pause until the path is available.">await FileSystemEntity.isDirectory(path)</a>) {
stderr.writeln('error: $path is a directory');
} else {
<a tabindex="0" role="button" data-toggle="popover" title="Exit code" data-content="A well-behaved command-line app sets an exit code to indicate whether the program was successful.">exitCode = 2</a>;
}
}</pre>
Loading