-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Loading status checks…
Merge branch 'main' into merge-path-package
Showing
41 changed files
with
2,538 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
name: "package:args" | ||
about: "Create a bug or file a feature request against package:args." | ||
labels: "package:args" | ||
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
name: "package:logging" | ||
about: "Create a bug or file a feature request against package:logging." | ||
labels: "package:logging" | ||
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
name: "package:os_detect" | ||
about: "Create a bug or file a feature request against package:os_detect." | ||
labels: "package:os_detect" | ||
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
name: package:logging | ||
|
||
on: | ||
# Run CI on pushes to the main branch, and on PRs against main. | ||
push: | ||
branches: [ main ] | ||
paths: | ||
- '.github/workflows/logging.yaml' | ||
- 'pkgs/logging/**' | ||
pull_request: | ||
branches: [ main ] | ||
paths: | ||
- '.github/workflows/logging.yaml' | ||
- 'pkgs/logging/**' | ||
schedule: | ||
- cron: "0 0 * * 0" | ||
env: | ||
PUB_ENVIRONMENT: bot.github | ||
|
||
defaults: | ||
run: | ||
working-directory: pkgs/logging/ | ||
|
||
jobs: | ||
# Check code formatting and static analysis. | ||
analyze: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
sdk: [dev] | ||
steps: | ||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 | ||
- uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 | ||
with: | ||
sdk: ${{ matrix.sdk }} | ||
- id: install | ||
name: Install dependencies | ||
run: dart pub get | ||
- name: Check formatting | ||
run: dart format --output=none --set-exit-if-changed . | ||
if: always() && steps.install.outcome == 'success' | ||
- name: Analyze code | ||
run: dart analyze --fatal-infos | ||
if: always() && steps.install.outcome == 'success' | ||
|
||
# Run tests on a matrix of platforms and sdk versions. | ||
test: | ||
needs: analyze | ||
runs-on: ${{ matrix.os }} | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
# Add macos-latest and/or windows-latest if relevant for this package. | ||
os: [ubuntu-latest] | ||
sdk: [3.4, dev] | ||
steps: | ||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 | ||
- uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 | ||
with: | ||
sdk: ${{ matrix.sdk }} | ||
- id: install | ||
name: Install dependencies | ||
run: dart pub get | ||
- name: Run VM tests | ||
run: dart test --platform vm | ||
if: always() && steps.install.outcome == 'success' | ||
- name: Run Chrome tests | ||
run: dart test --platform chrome | ||
if: always() && steps.install.outcome == 'success' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
name: package:os_detect | ||
|
||
on: | ||
# Run CI on pushes to the main branch, and on PRs against main. | ||
push: | ||
branches: [ main ] | ||
paths: | ||
- '.github/workflows/os_detect.yaml' | ||
- 'pkgs/os_detect/**' | ||
pull_request: | ||
branches: [ main ] | ||
paths: | ||
- '.github/workflows/os_detect.yaml' | ||
- 'pkgs/os_detect/**' | ||
schedule: | ||
- cron: "0 0 * * 0" | ||
env: | ||
PUB_ENVIRONMENT: bot.github | ||
|
||
defaults: | ||
run: | ||
working-directory: pkgs/os_detect/ | ||
|
||
jobs: | ||
# Check code formatting and static analysis on a single OS (linux) | ||
# against Dart dev. | ||
analyze: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
sdk: [dev] | ||
steps: | ||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 | ||
- uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 | ||
with: | ||
sdk: ${{ matrix.sdk }} | ||
- id: install | ||
name: Install dependencies | ||
run: dart pub get | ||
- name: Check formatting | ||
run: dart format --output=none --set-exit-if-changed . | ||
if: always() && steps.install.outcome == 'success' | ||
- name: Analyze code | ||
run: dart analyze --fatal-infos | ||
if: always() && steps.install.outcome == 'success' | ||
|
||
# Run tests on a matrix consisting of two dimensions: | ||
# 1. OS: ubuntu-latest, (macos-latest, windows-latest) | ||
# 2. release channel: dev | ||
test: | ||
needs: analyze | ||
runs-on: ${{ matrix.os }} | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
# Add macos-latest and/or windows-latest if relevant for this package. | ||
os: [ubuntu-latest, windows-latest, macos-latest] | ||
sdk: [3.0.0, dev] | ||
steps: | ||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 | ||
- uses: dart-lang/setup-dart@0a8a0fc875eb934c15d08629302413c671d3f672 | ||
with: | ||
sdk: ${{ matrix.sdk }} | ||
- id: install | ||
name: Install dependencies | ||
run: dart pub get | ||
- name: Run VM tests | ||
run: dart test --platform vm | ||
if: always() && steps.install.outcome == 'success' | ||
- name: Run Chrome tests | ||
run: dart test --platform chrome | ||
if: always() && steps.install.outcome == 'success' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.dart_tool | ||
.packages | ||
pubspec.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Names should be added to this file with this pattern: | ||
# | ||
# For individuals: | ||
# Name <email address> | ||
# | ||
# For organizations: | ||
# Organization <fnmatch pattern> | ||
# | ||
Google Inc. <*@google.com> | ||
Anton Astashov <[email protected]> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
## 1.3.0 | ||
|
||
* Override empty stack traces for trace level events. | ||
* Require Dart 3.4 | ||
* Move to `dart-lang/core` monorepo. | ||
|
||
## 1.2.0 | ||
|
||
* Add notification when the log level is changed. Logger `onLevelChanged` broadcasts a stream of level values. | ||
* Require Dart 2.19. | ||
|
||
## 1.1.1 | ||
|
||
* Add a check that throws if a logger name ends with '.'. | ||
* Require Dart 2.18 | ||
|
||
## 1.1.0 | ||
|
||
* Add `Logger.attachedLoggers` which exposes all loggers created with the | ||
default constructor. | ||
* Enable the `avoid_dynamic_calls` lint. | ||
|
||
## 1.0.2 | ||
|
||
* Update description. | ||
* Add example. | ||
|
||
## 1.0.1 | ||
|
||
* List log levels in README. | ||
|
||
## 1.0.0 | ||
|
||
* Stable null safety release. | ||
|
||
## 1.0.0-nullsafety.0 | ||
|
||
* Migrate to null safety. | ||
* Removed the deprecated `LoggerHandler` typedef. | ||
|
||
## 0.11.4 | ||
|
||
* Add top level `defaultLevel`. | ||
* Require Dart `>=2.0.0`. | ||
* Make detached loggers work regardless of `hierarchicalLoggingEnabled`. | ||
|
||
## 0.11.3+2 | ||
|
||
* Set max SDK version to `<3.0.0`, and adjust other dependencies. | ||
|
||
## 0.11.3+1 | ||
|
||
* Fixed several documentation comments. | ||
|
||
## 0.11.3 | ||
|
||
* Added optional `LogRecord.object` field. | ||
|
||
* `Logger.log` sets `LogRecord.object` if the message is not a string or a | ||
function that returns a string. So that a handler can access the original | ||
object instead of just its `toString()`. | ||
|
||
## 0.11.2 | ||
|
||
* Added `Logger.detached` - a convenience factory to obtain a logger that is not | ||
attached to this library's logger hierarchy. | ||
|
||
## 0.11.1+1 | ||
|
||
* Include default error with the auto-generated stack traces. | ||
|
||
## 0.11.1 | ||
|
||
* Add support for automatically logging the stack trace on error messages. Note | ||
this can be expensive, so it is off by default. | ||
|
||
## 0.11.0 | ||
|
||
* Revert change in `0.10.0`. `stackTrace` must be an instance of `StackTrace`. | ||
Use the `Trace` class from the [stack_trace package][] to convert strings. | ||
|
||
[stack_trace package]: https://pub.dev/packages/stack_trace | ||
|
||
## 0.10.0 | ||
|
||
* Change type of `stackTrace` from `StackTrace` to `Object`. | ||
|
||
## 0.9.3 | ||
|
||
* Added optional `LogRecord.zone` field. | ||
|
||
* Record current zone (or user specified zone) when creating new `LogRecord`s. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
Copyright 2013, the Dart project authors. | ||
|
||
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 Google LLC 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 | ||
OWNER 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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
[![Dart CI](https://github.com/dart-lang/core/actions/workflows/logging.yaml/badge.svg)](https://github.com/dart-lang/core/actions/workflows/logging.yaml) | ||
[![Pub](https://img.shields.io/pub/v/logging.svg)](https://pub.dev/packages/logging) | ||
[![package publisher](https://img.shields.io/pub/publisher/logging.svg)](https://pub.dev/packages/logging/publisher) | ||
|
||
## Initializing | ||
|
||
By default, the logging package does not do anything useful with the log | ||
messages. You must configure the logging level and add a handler for the log | ||
messages. | ||
|
||
Here is a simple logging configuration that logs all messages via `print`. | ||
|
||
```dart | ||
Logger.root.level = Level.ALL; // defaults to Level.INFO | ||
Logger.root.onRecord.listen((record) { | ||
print('${record.level.name}: ${record.time}: ${record.message}'); | ||
}); | ||
``` | ||
|
||
First, set the root `Level`. All messages at or above the current level are sent to the | ||
`onRecord` stream. Available levels are: | ||
|
||
+ `Level.OFF` | ||
+ `Level.SHOUT` | ||
+ `Level.SEVERE` | ||
+ `Level.WARNING` | ||
+ `Level.INFO` | ||
+ `Level.CONFIG` | ||
+ `Level.FINE` | ||
+ `Level.FINER` | ||
+ `Level.FINEST` | ||
|
||
Then, listen on the `onRecord` stream for `LogRecord` events. The `LogRecord` | ||
class has various properties for the message, error, logger name, and more. | ||
|
||
To listen for changed level notifications use: | ||
|
||
```dart | ||
Logger.root.onLevelChanged.listen((level) { | ||
print('The new log level is $level'); | ||
}); | ||
``` | ||
|
||
## Logging messages | ||
|
||
Create a `Logger` with a unique name to easily identify the source of the log | ||
messages. | ||
|
||
```dart | ||
final log = Logger('MyClassName'); | ||
``` | ||
|
||
Here is an example of logging a debug message and an error: | ||
|
||
```dart | ||
var future = doSomethingAsync().then((result) { | ||
log.fine('Got the result: $result'); | ||
processResult(result); | ||
}).catchError((e, stackTrace) => log.severe('Oh noes!', e, stackTrace)); | ||
``` | ||
|
||
When logging more complex messages, you can pass a closure instead that will be | ||
evaluated only if the message is actually logged: | ||
|
||
```dart | ||
log.fine(() => [1, 2, 3, 4, 5].map((e) => e * 4).join("-")); | ||
``` | ||
|
||
Available logging methods are: | ||
|
||
+ `log.shout(logged_content);` | ||
+ `log.severe(logged_content);` | ||
+ `log.warning(logged_content);` | ||
+ `log.info(logged_content);` | ||
+ `log.config(logged_content);` | ||
+ `log.fine(logged_content);` | ||
+ `log.finer(logged_content);` | ||
+ `log.finest(logged_content);` | ||
|
||
## Configuration | ||
|
||
Loggers can be individually configured and listened to. When an individual logger has no | ||
specific configuration, it uses the configuration and any listeners found at `Logger.root`. | ||
|
||
To begin, set the global boolean `hierarchicalLoggingEnabled` to `true`. | ||
|
||
Then, create unique loggers and configure their `level` attributes and assign any listeners to | ||
their `onRecord` streams. | ||
|
||
|
||
```dart | ||
hierarchicalLoggingEnabled = true; | ||
Logger.root.level = Level.WARNING; | ||
Logger.root.onRecord.listen((record) { | ||
print('[ROOT][WARNING+] ${record.message}'); | ||
}); | ||
final log1 = Logger('FINE+'); | ||
log1.level = Level.FINE; | ||
log1.onRecord.listen((record) { | ||
print('[LOG1][FINE+] ${record.message}'); | ||
}); | ||
// log2 inherits LEVEL value of WARNING from `Logger.root` | ||
final log2 = Logger('WARNING+'); | ||
log2.onRecord.listen((record) { | ||
print('[LOG2][WARNING+] ${record.message}'); | ||
}); | ||
// Will NOT print because FINER is too low level for `Logger.root`. | ||
log1.finer('LOG_01 FINER (X)'); | ||
// Will print twice ([LOG1] & [ROOT]) | ||
log1.fine('LOG_01 FINE (√√)'); | ||
// Will print ONCE because `log1` only uses root listener. | ||
log1.warning('LOG_01 WARNING (√)'); | ||
// Will never print because FINE is too low level. | ||
log2.fine('LOG_02 FINE (X)'); | ||
// Will print twice ([LOG2] & [ROOT]) because warning is sufficient for all | ||
// loggers' levels. | ||
log2.warning('LOG_02 WARNING (√√)'); | ||
// Will never print because `info` is filtered by `Logger.root.level` of | ||
// `Level.WARNING`. | ||
log2.info('INFO (X)'); | ||
``` | ||
|
||
Results in: | ||
|
||
``` | ||
[LOG1][FINE+] LOG_01 FINE (√√) | ||
[ROOT][WARNING+] LOG_01 FINE (√√) | ||
[LOG1][FINE+] LOG_01 WARNING (√) | ||
[ROOT][WARNING+] LOG_01 WARNING (√) | ||
[LOG2][WARNING+] LOG_02 WARNING (√√) | ||
[ROOT][WARNING+] LOG_02 WARNING (√√) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# https://dart.dev/guides/language/analysis-options | ||
include: package:dart_flutter_team_lints/analysis_options.yaml | ||
|
||
analyzer: | ||
language: | ||
strict-raw-types: true | ||
|
||
linter: | ||
rules: | ||
- avoid_bool_literals_in_conditional_expressions | ||
- avoid_classes_with_only_static_members | ||
- avoid_private_typedef_functions | ||
- avoid_redundant_argument_values | ||
- avoid_returning_this | ||
- avoid_unused_constructor_parameters | ||
- avoid_void_async | ||
- cancel_subscriptions | ||
- join_return_with_assignment | ||
- literal_only_boolean_expressions | ||
- missing_whitespace_between_adjacent_strings | ||
- no_adjacent_strings_in_list | ||
- no_runtimeType_toString | ||
- package_api_docs | ||
- prefer_const_declarations | ||
- prefer_expression_function_bodies | ||
- prefer_final_locals | ||
- unnecessary_await_in_return | ||
- unnecessary_raw_strings | ||
- use_if_null_to_convert_nulls_to_bools | ||
- use_raw_strings | ||
- use_string_buffers |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright (c) 2024, 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. | ||
|
||
import 'package:logging/logging.dart'; | ||
|
||
final log = Logger('ExampleLogger'); | ||
|
||
/// Example of configuring a logger to print to stdout. | ||
/// | ||
/// This example will print: | ||
/// | ||
/// INFO: 2021-09-13 15:35:10.703401: recursion: n = 4 | ||
/// INFO: 2021-09-13 15:35:10.707974: recursion: n = 3 | ||
/// Fibonacci(4) is: 3 | ||
/// Fibonacci(5) is: 5 | ||
/// SHOUT: 2021-09-13 15:35:10.708087: Unexpected negative n: -42 | ||
/// Fibonacci(-42) is: 1 | ||
void main() { | ||
Logger.root.level = Level.ALL; // defaults to Level.INFO | ||
Logger.root.onRecord.listen((record) { | ||
print('${record.level.name}: ${record.time}: ${record.message}'); | ||
}); | ||
|
||
print('Fibonacci(4) is: ${fibonacci(4)}'); | ||
|
||
Logger.root.level = Level.SEVERE; // skip logs less then severe. | ||
print('Fibonacci(5) is: ${fibonacci(5)}'); | ||
|
||
print('Fibonacci(-42) is: ${fibonacci(-42)}'); | ||
} | ||
|
||
int fibonacci(int n) { | ||
if (n <= 2) { | ||
if (n < 0) log.shout('Unexpected negative n: $n'); | ||
return 1; | ||
} else { | ||
log.info('recursion: n = $n'); | ||
return fibonacci(n - 2) + fibonacci(n - 1); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// Copyright (c) 2012, 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. | ||
|
||
export 'src/level.dart'; | ||
export 'src/log_record.dart'; | ||
export 'src/logger.dart'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// 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. | ||
|
||
// ignore_for_file: constant_identifier_names | ||
|
||
/// [Level]s to control logging output. Logging can be enabled to include all | ||
/// levels above certain [Level]. [Level]s are ordered using an integer | ||
/// value [Level.value]. The predefined [Level] constants below are sorted as | ||
/// follows (in descending order): [Level.SHOUT], [Level.SEVERE], | ||
/// [Level.WARNING], [Level.INFO], [Level.CONFIG], [Level.FINE], [Level.FINER], | ||
/// [Level.FINEST], and [Level.ALL]. | ||
/// | ||
/// We recommend using one of the predefined logging levels. If you define your | ||
/// own level, make sure you use a value between those used in [Level.ALL] and | ||
/// [Level.OFF]. | ||
class Level implements Comparable<Level> { | ||
final String name; | ||
|
||
/// Unique value for this level. Used to order levels, so filtering can | ||
/// exclude messages whose level is under certain value. | ||
final int value; | ||
|
||
const Level(this.name, this.value); | ||
|
||
/// Special key to turn on logging for all levels ([value] = 0). | ||
static const Level ALL = Level('ALL', 0); | ||
|
||
/// Special key to turn off all logging ([value] = 2000). | ||
static const Level OFF = Level('OFF', 2000); | ||
|
||
/// Key for highly detailed tracing ([value] = 300). | ||
static const Level FINEST = Level('FINEST', 300); | ||
|
||
/// Key for fairly detailed tracing ([value] = 400). | ||
static const Level FINER = Level('FINER', 400); | ||
|
||
/// Key for tracing information ([value] = 500). | ||
static const Level FINE = Level('FINE', 500); | ||
|
||
/// Key for static configuration messages ([value] = 700). | ||
static const Level CONFIG = Level('CONFIG', 700); | ||
|
||
/// Key for informational messages ([value] = 800). | ||
static const Level INFO = Level('INFO', 800); | ||
|
||
/// Key for potential problems ([value] = 900). | ||
static const Level WARNING = Level('WARNING', 900); | ||
|
||
/// Key for serious failures ([value] = 1000). | ||
static const Level SEVERE = Level('SEVERE', 1000); | ||
|
||
/// Key for extra debugging loudness ([value] = 1200). | ||
static const Level SHOUT = Level('SHOUT', 1200); | ||
|
||
static const List<Level> LEVELS = [ | ||
ALL, | ||
FINEST, | ||
FINER, | ||
FINE, | ||
CONFIG, | ||
INFO, | ||
WARNING, | ||
SEVERE, | ||
SHOUT, | ||
OFF | ||
]; | ||
|
||
@override | ||
bool operator ==(Object other) => other is Level && value == other.value; | ||
|
||
bool operator <(Level other) => value < other.value; | ||
|
||
bool operator <=(Level other) => value <= other.value; | ||
|
||
bool operator >(Level other) => value > other.value; | ||
|
||
bool operator >=(Level other) => value >= other.value; | ||
|
||
@override | ||
int compareTo(Level other) => value - other.value; | ||
|
||
@override | ||
int get hashCode => value; | ||
|
||
@override | ||
String toString() => name; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// 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. | ||
|
||
import 'dart:async'; | ||
|
||
import 'level.dart'; | ||
import 'logger.dart'; | ||
|
||
/// A log entry representation used to propagate information from [Logger] to | ||
/// individual handlers. | ||
class LogRecord { | ||
final Level level; | ||
final String message; | ||
|
||
/// Non-string message passed to Logger. | ||
final Object? object; | ||
|
||
/// Logger where this record is stored. | ||
final String loggerName; | ||
|
||
/// Time when this record was created. | ||
final DateTime time; | ||
|
||
/// Unique sequence number greater than all log records created before it. | ||
final int sequenceNumber; | ||
|
||
static int _nextNumber = 0; | ||
|
||
/// Associated error (if any) when recording errors messages. | ||
final Object? error; | ||
|
||
/// Associated stackTrace (if any) when recording errors messages. | ||
final StackTrace? stackTrace; | ||
|
||
/// Zone of the calling code which resulted in this LogRecord. | ||
final Zone? zone; | ||
|
||
LogRecord(this.level, this.message, this.loggerName, | ||
[this.error, this.stackTrace, this.zone, this.object]) | ||
: time = DateTime.now(), | ||
sequenceNumber = LogRecord._nextNumber++; | ||
|
||
@override | ||
String toString() => '[${level.name}] $loggerName: $message'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,326 @@ | ||
// 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. | ||
|
||
import 'dart:async'; | ||
import 'dart:collection'; | ||
|
||
import 'level.dart'; | ||
import 'log_record.dart'; | ||
|
||
/// Whether to allow fine-grain logging and configuration of loggers in a | ||
/// hierarchy. | ||
/// | ||
/// When false, all hierarchical logging instead is merged in the root logger. | ||
bool hierarchicalLoggingEnabled = false; | ||
|
||
/// Automatically record stack traces for any message of this level or above. | ||
/// | ||
/// Because this is expensive, this is off by default. | ||
Level recordStackTraceAtLevel = Level.OFF; | ||
|
||
/// The default [Level]. | ||
const defaultLevel = Level.INFO; | ||
|
||
/// Use a [Logger] to log debug messages. | ||
/// | ||
/// [Logger]s are named using a hierarchical dot-separated name convention. | ||
class Logger { | ||
/// Simple name of this logger. | ||
final String name; | ||
|
||
/// The full name of this logger, which includes the parent's full name. | ||
String get fullName => | ||
parent?.name.isNotEmpty ?? false ? '${parent!.fullName}.$name' : name; | ||
|
||
/// Parent of this logger in the hierarchy of loggers. | ||
final Logger? parent; | ||
|
||
/// Logging [Level] used for entries generated on this logger. | ||
/// | ||
/// Only the root logger is guaranteed to have a non-null [Level]. | ||
Level? _level; | ||
|
||
/// Private modifiable map of child loggers, indexed by their simple names. | ||
final Map<String, Logger> _children; | ||
|
||
/// Children in the hierarchy of loggers, indexed by their simple names. | ||
/// | ||
/// This is an unmodifiable map. | ||
final Map<String, Logger> children; | ||
|
||
/// Controller used to notify when log entries are added to this logger. | ||
/// | ||
/// If hierarchical logging is disabled then this is `null` for all but the | ||
/// root [Logger]. | ||
StreamController<LogRecord>? _controller; | ||
|
||
/// Controller used to notify when the log level of this logger is changed. | ||
StreamController<Level?>? _levelChangedController; | ||
|
||
/// Create or find a Logger by name. | ||
/// | ||
/// Calling `Logger(name)` will return the same instance whenever it is called | ||
/// with the same string name. Loggers created with this constructor are | ||
/// retained indefinitely and available through [attachedLoggers]. | ||
factory Logger(String name) => | ||
_loggers.putIfAbsent(name, () => Logger._named(name)); | ||
|
||
/// Creates a new detached [Logger]. | ||
/// | ||
/// Returns a new [Logger] instance (unlike `new Logger`, which returns a | ||
/// [Logger] singleton), which doesn't have any parent or children, | ||
/// and is not a part of the global hierarchical loggers structure. | ||
/// | ||
/// It can be useful when you just need a local short-living logger, | ||
/// which you'd like to be garbage-collected later. | ||
factory Logger.detached(String name) => | ||
Logger._internal(name, null, <String, Logger>{}); | ||
|
||
factory Logger._named(String name) { | ||
if (name.startsWith('.')) { | ||
throw ArgumentError("name shouldn't start with a '.'"); | ||
} | ||
if (name.endsWith('.')) { | ||
throw ArgumentError("name shouldn't end with a '.'"); | ||
} | ||
|
||
// Split hierarchical names (separated with '.'). | ||
final dot = name.lastIndexOf('.'); | ||
Logger? parent; | ||
String thisName; | ||
if (dot == -1) { | ||
if (name != '') parent = Logger(''); | ||
thisName = name; | ||
} else { | ||
parent = Logger(name.substring(0, dot)); | ||
thisName = name.substring(dot + 1); | ||
} | ||
return Logger._internal(thisName, parent, <String, Logger>{}); | ||
} | ||
|
||
Logger._internal(this.name, this.parent, Map<String, Logger> children) | ||
: _children = children, | ||
children = UnmodifiableMapView(children) { | ||
if (parent == null) { | ||
_level = defaultLevel; | ||
} else { | ||
parent!._children[name] = this; | ||
} | ||
} | ||
|
||
/// Effective level considering the levels established in this logger's | ||
/// parents (when [hierarchicalLoggingEnabled] is true). | ||
Level get level { | ||
Level effectiveLevel; | ||
|
||
if (parent == null) { | ||
// We're either the root logger or a detached logger. Return our own | ||
// level. | ||
effectiveLevel = _level!; | ||
} else if (!hierarchicalLoggingEnabled) { | ||
effectiveLevel = root._level!; | ||
} else { | ||
effectiveLevel = _level ?? parent!.level; | ||
} | ||
|
||
// ignore: unnecessary_null_comparison | ||
assert(effectiveLevel != null); | ||
return effectiveLevel; | ||
} | ||
|
||
/// Override the level for this particular [Logger] and its children. | ||
/// | ||
/// Setting this to `null` makes it inherit the [parent]s level. | ||
set level(Level? value) { | ||
if (!hierarchicalLoggingEnabled && parent != null) { | ||
throw UnsupportedError( | ||
'Please set "hierarchicalLoggingEnabled" to true if you want to ' | ||
'change the level on a non-root logger.'); | ||
} | ||
if (parent == null && value == null) { | ||
throw UnsupportedError( | ||
'Cannot set the level to `null` on a logger with no parent.'); | ||
} | ||
final isLevelChanged = _level != value; | ||
_level = value; | ||
if (isLevelChanged) { | ||
_levelChangedController?.add(value); | ||
} | ||
} | ||
|
||
/// Returns a stream of level values set to this [Logger]. | ||
/// | ||
/// You can listen for set levels using the standard stream APIs, | ||
/// for instance: | ||
/// | ||
/// ```dart | ||
/// logger.onLevelChanged.listen((level) { ... }); | ||
/// ``` | ||
/// A state error will be thrown if the level is changed | ||
/// inside the callback. | ||
Stream<Level?> get onLevelChanged { | ||
_levelChangedController ??= StreamController<Level?>.broadcast(sync: true); | ||
return _levelChangedController!.stream; | ||
} | ||
|
||
/// Returns a stream of messages added to this [Logger]. | ||
/// | ||
/// You can listen for messages using the standard stream APIs, for instance: | ||
/// | ||
/// ```dart | ||
/// logger.onRecord.listen((record) { ... }); | ||
/// ``` | ||
Stream<LogRecord> get onRecord => _getStream(); | ||
|
||
void clearListeners() { | ||
if (hierarchicalLoggingEnabled || parent == null) { | ||
_controller?.close(); | ||
_controller = null; | ||
} else { | ||
root.clearListeners(); | ||
} | ||
} | ||
|
||
/// Whether a message for [value]'s level is loggable in this logger. | ||
bool isLoggable(Level value) => value >= level; | ||
|
||
/// Adds a log record for a [message] at a particular [logLevel] if | ||
/// `isLoggable(logLevel)` is true. | ||
/// | ||
/// Use this method to create log entries for user-defined levels. To record a | ||
/// message at a predefined level (e.g. [Level.INFO], [Level.WARNING], etc) | ||
/// you can use their specialized methods instead (e.g. [info], [warning], | ||
/// etc). | ||
/// | ||
/// If [message] is a [Function], it will be lazy evaluated. Additionally, if | ||
/// [message] or its evaluated value is not a [String], then 'toString()' will | ||
/// be called on the object and the result will be logged. The log record will | ||
/// contain a field holding the original object. | ||
/// | ||
/// The log record will also contain a field for the zone in which this call | ||
/// was made. This can be advantageous if a log listener wants to handler | ||
/// records of different zones differently (e.g. group log records by HTTP | ||
/// request if each HTTP request handler runs in it's own zone). | ||
/// | ||
/// If this record is logged at a level equal to or higher than | ||
/// [recordStackTraceAtLevel] and [stackTrace] is `null` or [StackTrace.empty] | ||
/// it will be defaulted to the current stack trace for this call. | ||
void log(Level logLevel, Object? message, | ||
[Object? error, StackTrace? stackTrace, Zone? zone]) { | ||
Object? object; | ||
if (isLoggable(logLevel)) { | ||
if (message is Function) { | ||
message = (message as Object? Function())(); | ||
} | ||
|
||
String msg; | ||
if (message is String) { | ||
msg = message; | ||
} else { | ||
msg = message.toString(); | ||
object = message; | ||
} | ||
|
||
if ((stackTrace == null || stackTrace == StackTrace.empty) && | ||
logLevel >= recordStackTraceAtLevel) { | ||
stackTrace = StackTrace.current; | ||
error ??= 'autogenerated stack trace for $logLevel $msg'; | ||
} | ||
zone ??= Zone.current; | ||
|
||
final record = | ||
LogRecord(logLevel, msg, fullName, error, stackTrace, zone, object); | ||
|
||
if (parent == null) { | ||
_publish(record); | ||
} else if (!hierarchicalLoggingEnabled) { | ||
root._publish(record); | ||
} else { | ||
Logger? target = this; | ||
while (target != null) { | ||
target._publish(record); | ||
target = target.parent; | ||
} | ||
} | ||
} | ||
} | ||
|
||
/// Log message at level [Level.FINEST]. | ||
/// | ||
/// See [log] for information on how non-String [message] arguments are | ||
/// handled. | ||
void finest(Object? message, [Object? error, StackTrace? stackTrace]) => | ||
log(Level.FINEST, message, error, stackTrace); | ||
|
||
/// Log message at level [Level.FINER]. | ||
/// | ||
/// See [log] for information on how non-String [message] arguments are | ||
/// handled. | ||
void finer(Object? message, [Object? error, StackTrace? stackTrace]) => | ||
log(Level.FINER, message, error, stackTrace); | ||
|
||
/// Log message at level [Level.FINE]. | ||
/// | ||
/// See [log] for information on how non-String [message] arguments are | ||
/// handled. | ||
void fine(Object? message, [Object? error, StackTrace? stackTrace]) => | ||
log(Level.FINE, message, error, stackTrace); | ||
|
||
/// Log message at level [Level.CONFIG]. | ||
/// | ||
/// See [log] for information on how non-String [message] arguments are | ||
/// handled. | ||
void config(Object? message, [Object? error, StackTrace? stackTrace]) => | ||
log(Level.CONFIG, message, error, stackTrace); | ||
|
||
/// Log message at level [Level.INFO]. | ||
/// | ||
/// See [log] for information on how non-String [message] arguments are | ||
/// handled. | ||
void info(Object? message, [Object? error, StackTrace? stackTrace]) => | ||
log(Level.INFO, message, error, stackTrace); | ||
|
||
/// Log message at level [Level.WARNING]. | ||
/// | ||
/// See [log] for information on how non-String [message] arguments are | ||
/// handled. | ||
void warning(Object? message, [Object? error, StackTrace? stackTrace]) => | ||
log(Level.WARNING, message, error, stackTrace); | ||
|
||
/// Log message at level [Level.SEVERE]. | ||
/// | ||
/// See [log] for information on how non-String [message] arguments are | ||
/// handled. | ||
void severe(Object? message, [Object? error, StackTrace? stackTrace]) => | ||
log(Level.SEVERE, message, error, stackTrace); | ||
|
||
/// Log message at level [Level.SHOUT]. | ||
/// | ||
/// See [log] for information on how non-String [message] arguments are | ||
/// handled. | ||
void shout(Object? message, [Object? error, StackTrace? stackTrace]) => | ||
log(Level.SHOUT, message, error, stackTrace); | ||
|
||
Stream<LogRecord> _getStream() { | ||
if (hierarchicalLoggingEnabled || parent == null) { | ||
return (_controller ??= StreamController<LogRecord>.broadcast(sync: true)) | ||
.stream; | ||
} else { | ||
return root._getStream(); | ||
} | ||
} | ||
|
||
void _publish(LogRecord record) => _controller?.add(record); | ||
|
||
/// Top-level root [Logger]. | ||
static final Logger root = Logger(''); | ||
|
||
/// All attached [Logger]s in the system. | ||
static final Map<String, Logger> _loggers = <String, Logger>{}; | ||
|
||
/// All attached [Logger]s in the system. | ||
/// | ||
/// Loggers created with [Logger.detached] are not included. | ||
static Iterable<Logger> get attachedLoggers => _loggers.values; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
name: logging | ||
version: 1.3.0 | ||
description: >- | ||
Provides APIs for debugging and error logging, similar to loggers in other | ||
languages, such as the Closure JS Logger and java.util.logging.Logger. | ||
repository: https://github.com/dart-lang/core/tree/main/pkgs/logging | ||
|
||
topics: | ||
- logging | ||
- debugging | ||
|
||
environment: | ||
sdk: ^3.4.0 | ||
|
||
dev_dependencies: | ||
dart_flutter_team_lints: ^3.0.0 | ||
test: ^1.16.0 |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.dart_tool/ | ||
.packages | ||
pubspec.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Below is a list of people and organizations that have contributed | ||
# to the Dart project. Names should be added to the list like so: | ||
# | ||
# Name/Organization <email address> | ||
|
||
Google LLC |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
## 2.0.2 | ||
|
||
- Require Dart 3.0 | ||
- Make work with VM's platform-constants. | ||
- Move to `dart-lang/core` monorepo. | ||
|
||
## 2.0.1 | ||
|
||
- Populate the pubspec `repository` field. | ||
|
||
## 2.0.0 | ||
|
||
- Stable null safety release. | ||
|
||
## 1.0.0 | ||
|
||
- Initial release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
Copyright 2020, the Dart project authors. | ||
|
||
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 Google LLC 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 | ||
OWNER 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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
[![Dart CI](https://github.com/dart-lang/core/actions/workflows/os_detect.yaml/badge.svg)](https://github.com/dart-lang/core/actions/workflows/os_detect.yaml) | ||
[![pub package](https://img.shields.io/pub/v/os_detect.svg)](https://pub.dev/packages/os_detect) | ||
[![package publisher](https://img.shields.io/pub/publisher/os_detect.svg)](https://pub.dev/packages/os_detect/publisher) | ||
|
||
Platform independent access to information about the current operating system. | ||
|
||
## Querying the current OS | ||
|
||
Exposes `operatingSystem` and `operatingSystemVersion` strings similar to those | ||
of the `Platform` class in `dart:io`, but also works on the web. The | ||
`operatingSystem` of a browser is the string "browser". Also exposes convenience | ||
getters like `isLinux`, `isAndroid` and `isBrowser` based on the | ||
`operatingSystem` string. | ||
|
||
To use this package instead of `dart:io`, replace the import of `dart:io` with: | ||
|
||
```dart | ||
import 'package:os_detect/os_detect.dart' as os_detect; | ||
``` | ||
|
||
That should keep the code working if the only functionality used from `dart:io` | ||
is operating system detection. You should then use your IDE to rename the import | ||
prefix from `Platform` to something lower-cased which follows the style guide | ||
for import prefixes. | ||
|
||
Any new platform which supports neither `dart:io` nor `dart:html` can make | ||
itself recognizable by configuring the `dart.os.name` and `dart.os.version` | ||
environment settings, so that `const String.fromEnvironment` can access them. | ||
|
||
## Overriding the current OS string | ||
|
||
It's possible to override the current operating system string, as exposed by | ||
`operatingSystem` and `operatingSystemVersion` in | ||
`package:os_detect/os_detect.dart`. To do so, import the | ||
`package:os_detect/override.dart` library and use the `overrideOperatingSystem` | ||
function to run code in a zone where the operating system and version values are | ||
set to whatever values are desired. | ||
|
||
The class `OperatingSystemID` can also be used directly to abstract over the | ||
operating system name and version. The `OperatingSystemID.current` defaults to | ||
the values provided by the platform when not overridden using | ||
`overrideOperatingSystem`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# https://dart.dev/tools/analysis#the-analysis-options-file | ||
include: package:dart_flutter_team_lints/analysis_options.yaml | ||
|
||
analyzer: | ||
language: | ||
strict-casts: true | ||
strict-inference: true | ||
strict-raw-types: true | ||
|
||
linter: | ||
rules: | ||
- avoid_bool_literals_in_conditional_expressions | ||
- avoid_classes_with_only_static_members | ||
- avoid_private_typedef_functions | ||
- avoid_redundant_argument_values | ||
- avoid_returning_this | ||
- avoid_unused_constructor_parameters | ||
- avoid_void_async | ||
- literal_only_boolean_expressions | ||
- missing_whitespace_between_adjacent_strings | ||
- no_adjacent_strings_in_list | ||
- no_runtimeType_toString | ||
- package_api_docs | ||
- prefer_const_declarations | ||
- use_raw_strings | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Copyright (c) 2023, 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. | ||
|
||
/// Prints the operating system detected by the current compilation environment. | ||
library pkg.os_detect.run; | ||
|
||
import 'package:os_detect/os_detect.dart' as os_detect; | ||
|
||
void main() { | ||
final knownName = knownOSName(); | ||
print('OS name : ${os_detect.operatingSystem} ' | ||
'${knownName != null ? '($knownName)' : ''}'); | ||
print('OS version : ${os_detect.operatingSystemVersion}'); | ||
} | ||
|
||
String? knownOSName() { | ||
if (os_detect.isAndroid) { | ||
return 'Android'; | ||
} | ||
if (os_detect.isBrowser) { | ||
return 'Browser'; | ||
} | ||
if (os_detect.isFuchsia) { | ||
return 'Fuchsia'; | ||
} | ||
if (os_detect.isIOS) { | ||
return 'iOS'; | ||
} | ||
if (os_detect.isLinux) { | ||
return 'Linux'; | ||
} | ||
if (os_detect.isMacOS) { | ||
return 'MacOS'; | ||
} | ||
if (os_detect.isWindows) { | ||
return 'Windows'; | ||
} | ||
return null; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright (c) 2023, 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. | ||
|
||
import 'package:os_detect/os_detect.dart' as os_detect; | ||
|
||
void main() { | ||
print(''' | ||
OS ID: ${os_detect.operatingSystem} | ||
OS Version: ${os_detect.operatingSystemVersion}'''); | ||
if (os_detect.isAndroid) { | ||
print(' OS Type: Android'); | ||
} else if (os_detect.isBrowser) { | ||
print(' OS Type: Browser'); | ||
} else if (os_detect.isFuchsia) { | ||
print(' OS Type: Fuchsia'); | ||
} else if (os_detect.isIOS) { | ||
print(' OS Type: iOS'); | ||
} else if (os_detect.isLinux) { | ||
print(' OS Type: Linux'); | ||
} else if (os_detect.isMacOS) { | ||
print(' OS Type: MacOS'); | ||
} else if (os_detect.isWindows) { | ||
print(' OS Type: Windows'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Copyright (c) 2023, 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. | ||
|
||
// Try compiling this example with (if on Linux): | ||
// | ||
// dart compile exe --target-os=linux tree_shaking.dart | ||
// | ||
// then check that "SOMETHING ELSE" does not occur in the | ||
// output `tree_shaking.exe` program, e.g.: | ||
// | ||
// strings tree_shaking.exe | grep SOMETHING | ||
// | ||
// which shows no matches. | ||
|
||
import 'package:os_detect/os_detect.dart' as platform; | ||
|
||
void main() { | ||
if (platform.isLinux) { | ||
print('Is Linux'); | ||
} else { | ||
print('SOMETHING ELSE'); | ||
} | ||
if (platform.operatingSystem == 'linux') { | ||
print('Is Linux'); | ||
} else { | ||
print('SOMETHING ELSE'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// Copyright (c) 2020, 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. | ||
|
||
/// Information about the current operating system. | ||
library pkg.os_detect; | ||
|
||
import 'src/os_override.dart'; | ||
|
||
/// Identification of the current operating system or platform. | ||
/// | ||
/// Specific known operating systems are reported by a unique known string, | ||
/// and all the `is<Name>` values are computed by comparing the | ||
/// [operatingSystem] string against those known strings. | ||
/// That means that *at most* one of those value can be `true`, | ||
/// and usually precisely one will be `true`. | ||
/// | ||
/// **Notice:** Programs running in a browser will report their | ||
/// operating system as `"browser"`, not the operating system | ||
/// that browser is running on. See [isBrowser]. | ||
String get operatingSystem => OperatingSystem.current.id; | ||
|
||
/// Representation of the version of the current operating system or platform. | ||
/// | ||
/// May be empty if no version is known or available. | ||
String get operatingSystemVersion => OperatingSystem.current.version; | ||
|
||
/// Whether the current operating system is a version of | ||
/// [Linux](https://en.wikipedia.org/wiki/Linux). | ||
/// | ||
/// Identified by [operatingSystem] being the string `linux`. | ||
/// | ||
/// This value is `false` if the operating system is a specialized | ||
/// version of Linux that identifies itself by a different name, | ||
/// for example Android (see [isAndroid]), | ||
/// or if the code is running inside a browser (see [isBrowser]). | ||
@pragma('vm:prefer-inline') | ||
bool get isLinux => OperatingSystem.current.isLinux; | ||
|
||
/// Whether the current operating system is a version of | ||
/// [macOS](https://en.wikipedia.org/wiki/MacOS). | ||
/// | ||
/// Identified by [operatingSystem] being the string `macos`. | ||
/// | ||
/// The value is `false` if the code is running inside a browser, | ||
/// even if that browser is running on MacOS (see [isBrowser]). | ||
@pragma('vm:prefer-inline') | ||
bool get isMacOS => OperatingSystem.current.isMacOS; | ||
|
||
/// Whether the current operating system is a version of | ||
/// [Microsoft Windows](https://en.wikipedia.org/wiki/Microsoft_Windows). | ||
/// | ||
/// Identified by [operatingSystem] being the string `windows`. | ||
/// | ||
/// The value is `false` if the code is running inside a browser, | ||
/// even if that browser is running on Windows (see [isBrowser]). | ||
@pragma('vm:prefer-inline') | ||
bool get isWindows => OperatingSystem.current.isWindows; | ||
|
||
/// Whether the current operating system is a version of | ||
/// [Android](https://en.wikipedia.org/wiki/Android_%28operating_system%29). | ||
/// | ||
/// Identified by [operatingSystem] being the string `android`. | ||
/// | ||
/// The value is `false` if the code is running inside a browser, | ||
/// even if that browser is running on Android (see [isBrowser]). | ||
@pragma('vm:prefer-inline') | ||
bool get isAndroid => OperatingSystem.current.isAndroid; | ||
|
||
/// Whether the current operating system is a version of | ||
/// [iOS](https://en.wikipedia.org/wiki/IOS). | ||
/// | ||
/// Identified by [operatingSystem] being the string `ios`. | ||
/// | ||
/// The value is `false` if the code is running inside a browser, | ||
/// even if that browser is running on iOS (see [isBrowser]). | ||
@pragma('vm:prefer-inline') | ||
bool get isIOS => OperatingSystem.current.isIOS; | ||
|
||
/// Whether the current operating system is a version of | ||
/// [Fuchsia](https://en.wikipedia.org/wiki/Google_Fuchsia). | ||
/// | ||
/// Identified by [operatingSystem] being the string `fuchsia`. | ||
/// | ||
/// The value is `false` if the code is running inside a browser, | ||
/// even if that browser is running on Fuchsia (see [isBrowser]). | ||
@pragma('vm:prefer-inline') | ||
bool get isFuchsia => OperatingSystem.current.isFuchsia; | ||
|
||
/// Whether running in a web browser. | ||
/// | ||
/// Identified by [operatingSystem] being the string `browser`. | ||
/// | ||
/// If so, the [operatingSystemVersion] is the string made available | ||
/// through `window.navigator.appVersion`. | ||
/// | ||
/// The value is `true` when the code is running inside a browser, | ||
/// no matter which operating system the browser is itself running on. | ||
/// No attempt is made to detect the underlying operating system. | ||
/// That information *may* be derived from [operatingSystemVersion], | ||
/// but browsers are able to lie in the app-version/user-agent | ||
/// string. | ||
@pragma('vm:prefer-inline') | ||
bool get isBrowser => OperatingSystem.current.isBrowser; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// Copyright (c) 2023, 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. | ||
|
||
/// Functionality to override information about the current platform. | ||
library; | ||
|
||
export 'src/os_override.dart' show OperatingSystem, overrideOperatingSystem; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
// Copyright (c) 2023, 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. | ||
|
||
/// Shared constants and classes used to represent a recongized OS type | ||
/// | ||
/// Not exported in the public API, but used to communicate between | ||
/// `override.dart` and the conditionally imported `osid_X.dart` files. | ||
/// | ||
/// When the platform is statically known, all but one of the subclasses | ||
/// should be tree-shaken, so an `os is AndroidOS` can be resolved to | ||
/// a constant true/false depending on whether the class is the retained one | ||
/// or not. | ||
library; | ||
|
||
/// Operating identity object. | ||
/// | ||
/// By only instantiating these subtypes guarded by target-OS guarded | ||
/// checks, unless using the "for testing" `OperatingSystem` constructor, | ||
/// all but one of the subclasses should be tree-shaken, | ||
/// and, e.g., the `_isId is IOS` test above should become tree-shakable | ||
/// on all other platforms. | ||
sealed class RecognizedOS { | ||
// The recognized OS identifier strings recognized. | ||
static const androidId = 'android'; | ||
static const browserId = 'browser'; | ||
static const fuchsiaId = 'fuchsia'; | ||
static const iOSId = 'ios'; | ||
static const linuxId = 'linux'; | ||
static const macOSId = 'macos'; | ||
static const windowsId = 'windows'; | ||
|
||
abstract final String id; | ||
const RecognizedOS(); | ||
} | ||
|
||
/// Operations system object for Android. | ||
class AndroidOS extends RecognizedOS { | ||
@override | ||
final String id = RecognizedOS.androidId; | ||
const AndroidOS(); | ||
} | ||
|
||
/// Operations system object for browsers. | ||
class BrowserOS extends RecognizedOS { | ||
@override | ||
final String id = RecognizedOS.browserId; | ||
const BrowserOS(); | ||
} | ||
|
||
/// Operations system object for Fuchsia. | ||
class FuchsiaOS extends RecognizedOS { | ||
@override | ||
final String id = RecognizedOS.fuchsiaId; | ||
const FuchsiaOS(); | ||
} | ||
|
||
/// Operations system object for iOS. | ||
class IOS extends RecognizedOS { | ||
@override | ||
final String id = RecognizedOS.iOSId; | ||
const IOS(); | ||
} | ||
|
||
/// Operations system object for Linux. | ||
class LinuxOS extends RecognizedOS { | ||
@override | ||
final String id = RecognizedOS.linuxId; | ||
const LinuxOS(); | ||
} | ||
|
||
/// Operations system object for MacOS. | ||
class MacOS extends RecognizedOS { | ||
@override | ||
final String id = RecognizedOS.macOSId; | ||
const MacOS(); | ||
} | ||
|
||
/// Operations system object for Windows. | ||
class WindowsOS extends RecognizedOS { | ||
@override | ||
final String id = RecognizedOS.windowsId; | ||
const WindowsOS(); | ||
} | ||
|
||
/// Fallback to represent unknown operating system. | ||
/// | ||
/// Do not use for one of the recognized operating | ||
/// systems | ||
class UnknownOS extends RecognizedOS { | ||
@override | ||
final String id; | ||
const UnknownOS(this.id) | ||
: assert(id != RecognizedOS.linuxId), | ||
assert(id != RecognizedOS.macOSId), | ||
assert(id != RecognizedOS.windowsId), | ||
assert(id != RecognizedOS.androidId), | ||
assert(id != RecognizedOS.iOSId), | ||
assert(id != RecognizedOS.fuchsiaId), | ||
assert(id != RecognizedOS.browserId); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
// Copyright (c) 2020, 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. | ||
|
||
import 'dart:async' show Zone, runZoned; | ||
|
||
import 'package:meta/meta.dart'; | ||
|
||
import 'os_kind.dart'; | ||
import 'osid_unknown.dart' | ||
if (dart.library.io) 'osid_io.dart' | ||
if (dart.library.html) 'osid_html.dart'; | ||
|
||
/// The name and version of an operating system. | ||
final class OperatingSystem { | ||
// The recognized OS identifier strings. | ||
|
||
/// The operating system ID string for Linux. | ||
/// | ||
/// Compare against [id] or the `operatingSystem` of `os_detect.dart`, | ||
/// or use as argument to [OperatingSystem.new]. | ||
static const androidId = RecognizedOS.androidId; | ||
|
||
/// The operating system ID string for browsers. | ||
/// | ||
/// Compare against [id] or the `operatingSystem` of `os_detect.dart`, | ||
/// or use as argument to [OperatingSystem.new]. | ||
static const browserId = RecognizedOS.browserId; | ||
|
||
/// The operating system ID string for Fuchsia. | ||
/// | ||
/// Compare against [id] or the `operatingSystem` of `os_detect.dart`, | ||
/// or use as argument to [OperatingSystem.new]. | ||
static const fuchsiaId = RecognizedOS.fuchsiaId; | ||
|
||
/// The operating system ID string for iOS. | ||
/// | ||
/// Compare against [id] or the `operatingSystem` of `os_detect.dart`, | ||
/// or use as argument to [OperatingSystem.new]. | ||
static const iOSId = RecognizedOS.iOSId; | ||
|
||
/// The operating system ID string for Linux. | ||
/// | ||
/// Compare against [id] or the `operatingSystem` of `os_detect.dart`, | ||
/// or use as argument to [OperatingSystem.new]. | ||
static const linuxId = RecognizedOS.linuxId; | ||
|
||
/// The operating system ID string for macOS. | ||
/// | ||
/// Compare against [id] or the `operatingSystem` of `os_detect.dart`, | ||
/// or use as argument to [OperatingSystem.new]. | ||
static const macOSId = RecognizedOS.macOSId; | ||
|
||
/// The operating system ID string for Windows. | ||
/// | ||
/// Compare against [id] or the `operatingSystem` of `os_detect.dart`, | ||
/// or use as argument to [OperatingSystem.new]. | ||
static const windowsId = RecognizedOS.windowsId; | ||
|
||
/// The current operating system ID. | ||
/// | ||
/// Defaults to what information is available | ||
/// from known platform specific libraries, | ||
/// but can be overridden using functionality from the | ||
/// `osid_override.dart` library. | ||
@pragma('vm:try-inline') | ||
static OperatingSystem get current => | ||
Zone.current[#_os] as OperatingSystem? ?? platformOS; | ||
|
||
/// A string representing the operating system or platform. | ||
String get id => _osId.id; | ||
|
||
// Operating system ID object. | ||
final RecognizedOS _osId; | ||
|
||
/// A string representing the version of the operating system or platform. | ||
/// | ||
/// May be empty if no version is known or available. | ||
final String version; | ||
|
||
/// Creates a new operating system object for testing. | ||
/// | ||
/// Can be used with [overrideOperatingSystem] to selectively | ||
/// change the value returned by [current]. | ||
/// | ||
/// **Notice:** Using this constructor may reduce the efficiency | ||
/// of compilers recognizing code that isn't needed when compiling | ||
/// for a particular platform (aka. "tree-shaking" of unreachable code). | ||
// Uses chained conditionals to allow back-ends to constant fold when they | ||
// know what `id` is, which they'd usually know for a specific operation. | ||
// That can avoid retaining *all* the subclasses of `OS`. | ||
@visibleForTesting | ||
@pragma('vm:prefer-inline') | ||
OperatingSystem(String id, String version) | ||
: this._( | ||
id == linuxId | ||
? const LinuxOS() | ||
: id == macOSId | ||
? const MacOS() | ||
: id == windowsId | ||
? const WindowsOS() | ||
: id == androidId | ||
? const AndroidOS() | ||
: id == iOSId | ||
? const IOS() | ||
: id == fuchsiaId | ||
? const FuchsiaOS() | ||
: id == browserId | ||
? const BrowserOS() | ||
: UnknownOS(id), | ||
version); | ||
|
||
/// Used by platforms which know the ID object. | ||
const OperatingSystem._(this._osId, this.version); | ||
|
||
/// Whether the operating system is a version of | ||
/// [Linux](https://en.wikipedia.org/wiki/Linux). | ||
/// | ||
/// Identified by [id] being the string `linux`. | ||
/// | ||
/// This value is `false` if the operating system is a specialized | ||
/// version of Linux that identifies itself by a different name, | ||
/// for example Android (see [isAndroid]). | ||
bool get isLinux => _osId is LinuxOS; | ||
|
||
/// Whether the operating system is a version of | ||
/// [macOS](https://en.wikipedia.org/wiki/MacOS). | ||
/// | ||
/// Identified by [id] being the string `macos`. | ||
bool get isMacOS => _osId is MacOS; | ||
|
||
/// Whether the operating system is a version of | ||
/// [Microsoft Windows](https://en.wikipedia.org/wiki/Microsoft_Windows). | ||
/// | ||
/// Identified by [id] being the string `windows`. | ||
bool get isWindows => _osId is WindowsOS; | ||
|
||
/// Whether the operating system is a version of | ||
/// [Android](https://en.wikipedia.org/wiki/Android_%28operating_system%29). | ||
/// | ||
/// Identified by [id] being the string `android`. | ||
bool get isAndroid => _osId is AndroidOS; | ||
|
||
/// Whether the operating system is a version of | ||
/// [iOS](https://en.wikipedia.org/wiki/IOS). | ||
/// | ||
/// Identified by [id] being the string `ios`. | ||
bool get isIOS => _osId is IOS; | ||
|
||
/// Whether the operating system is a version of | ||
/// [Fuchsia](https://en.wikipedia.org/wiki/Google_Fuchsia). | ||
/// | ||
/// Identified by [id] being the string `fuchsia`. | ||
bool get isFuchsia => _osId is FuchsiaOS; | ||
|
||
/// Whether running in a web browser. | ||
/// | ||
/// Identified by [id] being the string `browser`. | ||
/// | ||
/// If so, the [version] is the string made available | ||
/// through `window.navigator.appVersion`. | ||
bool get isBrowser => _osId is BrowserOS; | ||
} | ||
|
||
/// Run [body] in a zone with platform overrides. | ||
/// | ||
/// Overrides [OperatingSystem.current] with the supplied [operatingSystem] | ||
/// value while running in a new zone, and then runs [body] in that zone. | ||
/// | ||
/// This override affects the `operatingSystem` and `version` | ||
/// exported by `package:osid/osid.dart`. | ||
R overrideOperatingSystem<R>( | ||
OperatingSystem operatingSystem, R Function() body) => | ||
runZoned(body, zoneValues: {#_os: operatingSystem}); | ||
|
||
// Exposes the `OperatingSystem._` constructor to the conditionally imported | ||
// libraries. Not exported by `../override.dart'. | ||
final class OperatingSystemInternal extends OperatingSystem { | ||
const OperatingSystemInternal(super.id, super.version) : super._(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Copyright (c) 2020, 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. | ||
|
||
import 'dart:html'; | ||
|
||
import 'os_kind.dart' show BrowserOS; | ||
import 'os_override.dart'; | ||
|
||
String get _osVersion => window.navigator.appVersion; | ||
|
||
final OperatingSystem platformOS = | ||
OperatingSystemInternal(const BrowserOS(), _osVersion); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Copyright (c) 2020, 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. | ||
|
||
import 'dart:io'; | ||
|
||
import 'os_kind.dart'; | ||
import 'os_override.dart'; | ||
|
||
// Uses VM platform-constant functionality to constant fold this expression | ||
// when `Platform.operatingSystem` is known at compile-time. | ||
// Uses a valid "potentially constant" expression for this, instead of, e.g., | ||
// a `switch` expression. | ||
@pragma('vm:platform-const') | ||
final RecognizedOS? _osType = Platform.operatingSystem == RecognizedOS.linuxId | ||
? const LinuxOS() | ||
: Platform.operatingSystem == RecognizedOS.macOSId | ||
? const MacOS() | ||
: Platform.operatingSystem == RecognizedOS.windowsId | ||
? const WindowsOS() | ||
: Platform.operatingSystem == RecognizedOS.androidId | ||
? const AndroidOS() | ||
: Platform.operatingSystem == RecognizedOS.iOSId | ||
? const IOS() | ||
: Platform.operatingSystem == RecognizedOS.fuchsiaId | ||
? const FuchsiaOS() | ||
: Platform.operatingSystem == RecognizedOS.browserId | ||
? const BrowserOS() | ||
: null; | ||
|
||
final OperatingSystem platformOS = OperatingSystemInternal( | ||
_osType ?? UnknownOS(Platform.operatingSystem), | ||
Platform.operatingSystemVersion); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Copyright (c) 2020, 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. | ||
|
||
import 'os_kind.dart'; | ||
import 'os_override.dart'; | ||
|
||
@pragma('vm:platform-const') | ||
const String _os = | ||
String.fromEnvironment('dart.os.name', defaultValue: 'unknown'); | ||
const String _osVersion = String.fromEnvironment('dart.os.version'); | ||
|
||
const OperatingSystem platformOS = OperatingSystemInternal( | ||
_os == RecognizedOS.linuxId | ||
? LinuxOS() | ||
: _os == RecognizedOS.macOSId | ||
? MacOS() | ||
: _os == RecognizedOS.windowsId | ||
? WindowsOS() | ||
: _os == RecognizedOS.androidId | ||
? AndroidOS() | ||
: _os == RecognizedOS.iOSId | ||
? IOS() | ||
: _os == RecognizedOS.fuchsiaId | ||
? FuchsiaOS() | ||
: _os == RecognizedOS.browserId | ||
? BrowserOS() | ||
: UnknownOS(_os), | ||
_osVersion); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
name: os_detect | ||
version: 2.0.2 | ||
description: Platform independent OS detection. | ||
repository: https://github.com/dart-lang/core/tree/main/pkgs/os_detect | ||
|
||
environment: | ||
sdk: ^3.0.0 | ||
|
||
dependencies: | ||
meta: ^1.9.0 | ||
|
||
dev_dependencies: | ||
dart_flutter_team_lints: ^2.0.0 | ||
test: ^1.24.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// Copyright (c) 2020, 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. | ||
|
||
import 'dart:async'; | ||
|
||
import 'package:os_detect/os_detect.dart'; | ||
import 'package:os_detect/override.dart'; | ||
import 'package:test/test.dart'; | ||
|
||
void main() { | ||
test('Exists and is consistent', () { | ||
expect(operatingSystem, isNotNull); | ||
expect(operatingSystemVersion, isNotNull); | ||
|
||
expect(isLinux, operatingSystem == OperatingSystem.linuxId); | ||
expect(isAndroid, operatingSystem == OperatingSystem.androidId); | ||
expect(isMacOS, operatingSystem == OperatingSystem.macOSId); | ||
expect(isWindows, operatingSystem == OperatingSystem.windowsId); | ||
expect(isIOS, operatingSystem == OperatingSystem.iOSId); | ||
expect(isFuchsia, operatingSystem == OperatingSystem.fuchsiaId); | ||
expect(isBrowser, operatingSystem == OperatingSystem.browserId); | ||
}); | ||
|
||
test('Override', () { | ||
const overrideName = 'argle-bargle'; | ||
const overrideVersion = 'glop-glyf'; | ||
final overrideOS = OperatingSystem(overrideName, overrideVersion); | ||
Zone? overrideZone; | ||
|
||
final originalName = operatingSystem; | ||
final originalVersion = operatingSystemVersion; | ||
final originalID = OperatingSystem.current; | ||
final originalZone = Zone.current; | ||
expect(originalName, isNot(overrideName)); | ||
expect(originalVersion, isNot(overrideVersion)); | ||
|
||
// Override OS ID. | ||
overrideOperatingSystem(overrideOS, () { | ||
overrideZone = Zone.current; | ||
expect(operatingSystem, overrideName); | ||
expect(operatingSystemVersion, overrideVersion); | ||
expect(OperatingSystem.current, same(overrideOS)); | ||
// Nested override. | ||
overrideOperatingSystem(originalID, () { | ||
expect(operatingSystem, originalName); | ||
expect(operatingSystemVersion, originalVersion); | ||
expect(OperatingSystem.current, same(originalID)); | ||
}); | ||
expect(operatingSystem, overrideName); | ||
expect(operatingSystemVersion, overrideVersion); | ||
expect(OperatingSystem.current, same(overrideOS)); | ||
// Captured parent zone does not have override. | ||
originalZone.run(() { | ||
expect(operatingSystem, originalName); | ||
expect(operatingSystemVersion, originalVersion); | ||
}); | ||
expect(operatingSystem, overrideName); | ||
expect(operatingSystemVersion, overrideVersion); | ||
expect(OperatingSystem.current, same(overrideOS)); | ||
}); | ||
|
||
expect(operatingSystem, originalName); | ||
expect(operatingSystemVersion, originalVersion); | ||
|
||
// A captured override zone retains the override. | ||
overrideZone!.run(() { | ||
expect(operatingSystem, overrideName); | ||
expect(operatingSystemVersion, overrideVersion); | ||
expect(OperatingSystem.current, same(overrideOS)); | ||
}); | ||
}); | ||
} |