Skip to content

Commit

Permalink
Analyze/test cmdline tutorial code excerpts
Browse files Browse the repository at this point in the history
  • Loading branch information
chalin committed Sep 16, 2019
1 parent 1a963d5 commit eae6375
Show file tree
Hide file tree
Showing 11 changed files with 430 additions and 228 deletions.
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">
An async function is marked with <code>async</code> and returns a Future.
</li>
<li name="await" title="Using await">
The <code>await</code> keyword, which works only in async 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
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="An async function is marked with <code>async</code> and returns a Future.">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 async 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

0 comments on commit eae6375

Please sign in to comment.