Compare commits

..

32 Commits

Author SHA1 Message Date
83699de4ad fix: wip 2023-02-17 19:11:58 +01:00
459014b233 with personal github token 2023-02-17 19:11:23 +01:00
d365a9f8e2 Revert "merge releases"
This reverts commit e4f614fdbf.
2023-02-17 19:07:55 +01:00
f61afa73df fix: add merge 2023-02-17 19:03:58 +01:00
e4f614fdbf merge releases 2023-02-17 19:03:07 +01:00
fb6768a6fc bump version 2023-02-17 18:59:49 +01:00
49d3fc6b22 with github token 2023-02-17 18:54:36 +01:00
7f3399f1d8 only allow main 2023-02-17 18:51:47 +01:00
0eaf0dd3be fix: test creator of tags 2023-02-17 18:50:39 +01:00
91e39f4e65 add creator of tags 2023-02-17 18:50:18 +01:00
a71f60784f add create release 2023-02-17 18:44:59 +01:00
5a5b0e40f7 with changelog 2023-02-17 18:44:15 +01:00
f03452840c remove toolchain 2023-02-17 18:26:38 +01:00
7153c24f01 with actual versions 2023-02-17 18:24:45 +01:00
989d5bc260 with publish 2023-02-17 18:19:31 +01:00
c625ae49ba codegen also with repository 2023-02-17 18:14:51 +01:00
31eb44517d with repo 2023-02-17 18:13:31 +01:00
e5383b51f3 with repo 2023-02-17 18:13:17 +01:00
1e26b383d4 with readme and license 2023-02-17 18:12:02 +01:00
533b9dfef0 with wildcard version 2023-02-17 18:09:44 +01:00
bec62de62f cargo version 0.2.0 2023-02-17 18:05:33 +01:00
571963163f add version to main 2023-02-17 18:02:55 +01:00
36b0ecdabf bump version 2023-02-17 18:01:46 +01:00
578c2a6883 document usage 2023-02-17 18:00:20 +01:00
6be8482b46 fix all clippy 2023-02-17 17:51:39 +01:00
0cbd1790b0 add with dockerfile 2023-02-17 17:50:45 +01:00
728840ca8e with caching 2023-02-17 17:40:46 +01:00
59e2572173 add more quickstart 2023-02-17 17:29:23 +01:00
d894def70c build the application 2023-02-17 15:47:12 +01:00
cb9a4dd84f add test-the-application 2023-02-17 15:34:18 +01:00
d1726a052a with println 2023-02-17 15:17:28 +01:00
4a4c03f3c2 feature/add impl (#6)
* format code

* with object gen and args

* add implementation

* add rust generator

* reset generated code

* add basic output

* reset output

* add object

* add format function

* with opts

* fix vec

* add context to unwrap

* fix arguments

* with function body

* first complete generation: Still missing Vec<Obj>

* run full alpine

* add roadmap item
2023-02-17 12:33:16 +01:00
157 changed files with 182160 additions and 275 deletions

21
.github/workflows/create-release.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
name: Release
permissions:
contents: write
on:
push:
tags:
- v[0-9]+.*
jobs:
create-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: taiki-e/create-gh-release-action@v1
with:
# (Optional) Path to changelog.
changelog: CHANGELOG.md
# (Optional) Create a draft release.
# [default value: false]
draft: true
# (Required) GitHub token for creating GitHub Releases.
token: ${{ secrets.GITHUB_TOKEN }}

23
.github/workflows/create-tag.yml vendored Normal file
View File

@@ -0,0 +1,23 @@
name: Deploy
on:
workflow_dispatch:
push:
branches:
- "main"
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Get Next Version
id: semver
uses: ietf-tools/semver-action@v1
with:
token: ${{ github.token }}
branch: main
- uses: rickstaa/action-create-tag@v1
with:
tag: ${{ steps.semver.outputs.next }}
message: ${{ steps.semver.outputs.next }}
github_token: ${{ secrets.PERSONAL_GITHUB_TOKEN }}

4
CHANGELOG.md Normal file
View File

@@ -0,0 +1,4 @@
## 0.2.0 - 2023-02-17
First actual useful version of dagger-sdk. contains code for codegen, cli, and
core.

45
Cargo.lock generated
View File

@@ -184,7 +184,7 @@ dependencies = [
[[package]]
name = "dagger-codegen"
version = "0.1.0"
version = "0.2.0"
dependencies = [
"convert_case",
"dagger-core",
@@ -198,7 +198,7 @@ dependencies = [
[[package]]
name = "dagger-core"
version = "0.1.0"
version = "0.2.0"
dependencies = [
"clap",
"dirs",
@@ -220,7 +220,7 @@ dependencies = [
[[package]]
name = "dagger-rs"
version = "0.1.2"
version = "0.2.0"
dependencies = [
"clap",
"dagger-codegen",
@@ -244,7 +244,7 @@ dependencies = [
[[package]]
name = "dagger-sdk"
version = "0.1.0"
version = "0.2.0"
dependencies = [
"base64",
"dagger-core",
@@ -253,6 +253,7 @@ dependencies = [
"genco",
"gql_client",
"pretty_assertions",
"rand",
"serde",
"serde_json",
"tokio",
@@ -1047,6 +1048,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "pretty_assertions"
version = "1.3.0"
@@ -1077,6 +1084,36 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "redox_syscall"
version = "0.2.16"

View File

@@ -1,10 +1,12 @@
[package]
name = "dagger-rs"
version = "0.1.2"
version = "0.2.0"
edition = "2021"
readme = "README.md"
license-file = "LICENSE.MIT"
description = "A dagger sdk for rust, written in rust"
repository = "https://github.com/kjuulh/dagger-rs"
publish = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -12,8 +14,8 @@ description = "A dagger sdk for rust, written in rust"
members = ["crates/dagger-codegen", "crates/dagger-sdk", "crates/dagger-core"]
[dependencies]
dagger-codegen = { path = "crates/dagger-codegen" }
dagger-core = { path = "crates/dagger-core" }
dagger-codegen = { path = "crates/dagger-codegen", version = "0.2.0" }
dagger-core = { path = "crates/dagger-core", version = "0.2.0" }
clap = "4.1.4"
dirs = "4.0.0"

View File

@@ -2,9 +2,9 @@
A dagger sdk written in rust for rust.
## Disclaimer
# Usage
Work in progress. This is not ready for usage yet
See [dagger-sdk](./crates/dagger-sdk/README.md)
### Status
@@ -20,10 +20,10 @@ Work in progress. This is not ready for usage yet
- [x] Querier
- [x] Context
- [x] Deserializer for nested response (bind)
- [ ] Add codegen to hook into querier
- [x] Add codegen to hook into querier
- [ ] fix build / release cycle
- [ ] general api stabilisation
- [ ] document usage
- [x] document usage
- [ ] make async variant
## Architecture

View File

@@ -1,13 +1,17 @@
[package]
name = "dagger-codegen"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
readme = "README.md"
license-file = "LICENSE.MIT"
description = "dagger sdk codegen library"
repository = "https://github.com/kjuulh/dagger-rs"
publish = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
convert_case = "0.6.0"
dagger-core = { path = "../dagger-core" }
dagger-core = { path = "../dagger-core", version = "0.2.0" }
eyre = "0.6.8"
genco = "0.17.3"

View File

@@ -0,0 +1,7 @@
Copyright 2023 Kasper J. Hermansen
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

View File

@@ -1 +0,0 @@
nightly

View File

@@ -1,6 +1,6 @@
use std::sync::Arc;
use dagger_core::introspection::{FullType, InputValue, TypeRef, __TypeKind};
use dagger_core::introspection::{FullType, FullTypeFields, InputValue, TypeRef, __TypeKind};
use eyre::ContextCompat;
use crate::utility::OptionExt;
@@ -154,7 +154,29 @@ pub fn type_ref_is_optional(type_ref: &TypeRef) -> bool {
.unwrap_or(false)
}
pub fn type_field_has_optional(field: &FullTypeFields) -> bool {
field
.args
.pipe(|a| {
a.iter()
.map(|a| a.pipe(|a| &a.input_value))
.flatten()
.collect::<Vec<_>>()
})
.pipe(|s| input_values_has_optionals(s.as_slice()))
.unwrap_or(false)
}
pub fn type_ref_is_scalar(type_ref: &TypeRef) -> bool {
let mut type_ref = type_ref.clone();
if type_ref
.kind
.pipe(|k| *k == __TypeKind::NON_NULL)
.unwrap_or(false)
{
type_ref = *type_ref.of_type.unwrap().clone();
}
type_ref
.kind
.pipe(|k| *k == __TypeKind::SCALAR)
@@ -162,6 +184,15 @@ pub fn type_ref_is_scalar(type_ref: &TypeRef) -> bool {
}
pub fn type_ref_is_object(type_ref: &TypeRef) -> bool {
let mut type_ref = type_ref.clone();
if type_ref
.kind
.pipe(|k| *k == __TypeKind::NON_NULL)
.unwrap_or(false)
{
type_ref = *type_ref.of_type.unwrap().clone();
}
type_ref
.kind
.pipe(|k| *k == __TypeKind::OBJECT)
@@ -169,13 +200,43 @@ pub fn type_ref_is_object(type_ref: &TypeRef) -> bool {
}
pub fn type_ref_is_list(type_ref: &TypeRef) -> bool {
let mut type_ref = type_ref.clone();
if type_ref
.kind
.pipe(|k| *k == __TypeKind::NON_NULL)
.unwrap_or(false)
{
type_ref = *type_ref.of_type.unwrap().clone();
}
type_ref
.kind
.pipe(|k| *k == __TypeKind::LIST)
.unwrap_or(false)
}
pub fn input_values_has_optionals(input_values: &[InputValue]) -> bool {
pub fn type_ref_is_list_of_objects(type_ref: &TypeRef) -> bool {
let mut type_ref = type_ref.clone();
if type_ref
.kind
.pipe(|k| *k == __TypeKind::NON_NULL)
.unwrap_or(false)
{
type_ref = *type_ref.of_type.unwrap().clone();
}
if type_ref
.kind
.pipe(|k| *k == __TypeKind::LIST)
.unwrap_or(false)
{
type_ref = *type_ref.of_type.unwrap().clone();
}
type_ref_is_object(&type_ref)
}
pub fn input_values_has_optionals(input_values: &[&InputValue]) -> bool {
input_values
.into_iter()
.map(|k| type_ref_is_optional(&k.type_))
@@ -324,7 +385,7 @@ mod test {
},
];
let output = input_values_has_optionals(&input);
let output = input_values_has_optionals(input.iter().collect::<Vec<_>>().as_slice());
assert_eq!(output, true);
}
@@ -354,7 +415,7 @@ mod test {
},
];
let output = input_values_has_optionals(&input);
let output = input_values_has_optionals(input.iter().collect::<Vec<_>>().as_slice());
assert_eq!(output, false);
}

View File

@@ -37,10 +37,10 @@ impl FormatTypeFuncs for FormatTypeFunc {
&self,
representation: &str,
ref_name: &str,
input: bool,
_input: bool,
) -> String {
let mut rep = representation.to_string();
rep.push_str(ref_name);
rep.push_str(&format_name(ref_name));
rep
}
@@ -58,7 +58,7 @@ impl FormatTypeFuncs for FormatTypeFunc {
fn format_kind_enum(&self, representation: &str, ref_name: &str) -> String {
let mut rep = representation.to_string();
rep.push_str(ref_name);
rep.push_str(&format_name(ref_name));
rep
}
}

View File

@@ -1,5 +1,14 @@
use convert_case::{Case, Casing};
use dagger_core::introspection::FullTypeFields;
use genco::prelude::rust;
use genco::quote;
use genco::tokens::quoted;
use crate::functions::{
type_field_has_optional, type_ref_is_list_of_objects, type_ref_is_object,
type_ref_is_optional, CommonFunctions,
};
use crate::utility::OptionExt;
pub fn format_name(s: &str) -> String {
s.to_case(Case::Pascal)
@@ -18,3 +27,180 @@ pub fn field_options_struct_name(field: &FullTypeFields) -> Option<String> {
.zip(field.name.as_ref().map(|n| format_name(n)))
.map(|(parent_name, field_name)| format!("{parent_name}{field_name}Opts"))
}
pub fn format_function(funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> {
let signature = quote! {
pub fn $(field.name.pipe(|n | format_struct_name(n)))
};
let args = format_function_args(funcs, field);
let output_type = field
.type_
.pipe(|t| &t.type_ref)
.pipe(|t| funcs.format_output_type(t));
Some(quote! {
$(signature)(
$(args)
) -> $(output_type) {
let mut query = self.selection.select($(quoted(field.name.as_ref())));
$(render_required_args(funcs, field))
$(render_optional_args(funcs, field))
$(render_execution(funcs, field))
}
})
}
fn render_required_args(_funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> {
if let Some(args) = field.args.as_ref() {
let args = args
.into_iter()
.map(|a| {
a.as_ref().and_then(|s| {
if type_ref_is_optional(&s.input_value.type_) {
return None;
}
let n = format_struct_name(&s.input_value.name);
let name = &s.input_value.name;
Some(quote! {
query = query.arg($(quoted(name)), $(n)).unwrap();
})
})
})
.flatten()
.collect::<Vec<_>>();
let required_args = quote! {
$(for arg in args join ($['\r']) => $arg)
};
Some(required_args)
} else {
None
}
}
fn render_optional_args(_funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> {
if let Some(args) = field.args.as_ref() {
let args = args
.into_iter()
.map(|a| {
a.as_ref().and_then(|s| {
if !type_ref_is_optional(&s.input_value.type_) {
return None;
}
let n = format_struct_name(&s.input_value.name);
let name = &s.input_value.name;
Some(quote! {
if let Some($(&n)) = opts.$(&n) {
query = query.arg($(quoted(name)), $(&n)).unwrap();
}
})
})
})
.flatten()
.collect::<Vec<_>>();
if args.len() == 0 {
return None;
}
let required_args = quote! {
if let Some(opts) = opts {
$(for arg in args join ($['\r']) => $arg)
}
};
Some(required_args)
} else {
None
}
}
fn render_execution(funcs: &CommonFunctions, field: &FullTypeFields) -> rust::Tokens {
if let Some(true) = field.type_.pipe(|t| type_ref_is_object(&t.type_ref)) {
let output_type = funcs.format_output_type(&field.type_.as_ref().unwrap().type_ref);
return quote! {
return $(output_type) {
proc: self.proc.clone(),
selection: query,
conn: self.conn.clone(),
}
};
}
if let Some(true) = field
.type_
.pipe(|t| type_ref_is_list_of_objects(&t.type_ref))
{
let output_type = funcs.format_output_type(
&field
.type_
.as_ref()
.unwrap()
.type_ref
.of_type
.as_ref()
.unwrap()
.of_type
.as_ref()
.unwrap(),
);
return quote! {
return vec![$(output_type) {
proc: self.proc.clone(),
selection: query,
conn: self.conn.clone(),
}]
};
}
let graphql_client = rust::import("crate::client", "graphql_client");
quote! {
query.execute(&$graphql_client(&self.conn)).unwrap().unwrap()
}
}
fn format_function_args(funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> {
if let Some(args) = field.args.as_ref() {
let args = args
.into_iter()
.map(|a| {
a.as_ref().and_then(|s| {
if type_ref_is_optional(&s.input_value.type_) {
return None;
}
let t = funcs.format_input_type(&s.input_value.type_);
let n = format_struct_name(&s.input_value.name);
Some(quote! {
$(n): $(t),
})
})
})
.flatten()
.collect::<Vec<_>>();
let required_args = quote! {
&self,
$(for arg in args join ($['\r']) => $arg)
};
if type_field_has_optional(field) {
Some(quote! {
$(required_args)
opts: Option<$(field_options_struct_name(field))>
})
} else {
Some(required_args)
}
} else {
None
}
}

View File

@@ -31,7 +31,7 @@ impl Generator for RustGenerator {
handlers: VisitHandlers {
visit_scalar: Arc::new({
let render = render.clone();
let common_funcs = common_funcs.clone();
let _common_funcs = common_funcs.clone();
move |t| {
println!("generating scalar");
@@ -83,7 +83,7 @@ impl Generator for RustGenerator {
}),
visit_enum: Arc::new({
let render = render.clone();
let common_funcs = common_funcs.clone();
let _common_funcs = common_funcs.clone();
move |t| {
println!("generating enum");

View File

@@ -6,7 +6,10 @@ use crate::functions::CommonFunctions;
use crate::rust::functions::{format_name, format_struct_name};
pub fn render_input(funcs: &CommonFunctions, t: &FullType) -> eyre::Result<rust::Tokens> {
let deserialize = rust::import("serde", "Deserialize");
let serialize = rust::import("serde", "Serialize");
Ok(quote! {
#[derive($serialize, $deserialize)]
pub struct $(format_name(t.name.as_ref().unwrap())) {
$(render_input_fields(funcs, t.input_fields.as_ref().unwrap_or(&Vec::new()) ))
}

View File

@@ -2,20 +2,29 @@ use dagger_core::introspection::{FullType, FullTypeFields, FullTypeFieldsArgs};
use genco::prelude::rust;
use genco::quote;
use crate::functions::CommonFunctions;
use crate::rust::functions::{field_options_struct_name, format_name, format_struct_name};
use crate::functions::{type_ref_is_optional, CommonFunctions};
use crate::rust::functions::{
field_options_struct_name, format_function, format_name, format_struct_name,
};
use crate::utility::OptionExt;
pub fn render_object(funcs: &CommonFunctions, t: &FullType) -> eyre::Result<rust::Tokens> {
let selection = rust::import("crate::querybuilder", "Selection");
let child = rust::import("std::process", "Child");
let conn = rust::import("dagger_core::connect_params", "ConnectParams");
let arc = rust::import("std::sync", "Arc");
Ok(quote! {
pub struct $(t.name.pipe(|s| format_name(s))) {
pub proc: $arc<$child>,
pub selection: $selection,
pub conn: $conn,
}
$(t.fields.pipe(|f| render_optional_args(funcs, f)))
impl $(t.name.pipe(|s| format_name(s))) {
$(t.fields.pipe(|f| render_functions(funcs, f)))
}
})
}
@@ -44,6 +53,11 @@ fn render_optional_arg(funcs: &CommonFunctions, field: &FullTypeFields) -> Optio
let fields = field
.args
.pipe(|t| t.into_iter().flatten().collect::<Vec<_>>())
.map(|t| {
t.into_iter()
.filter(|t| type_ref_is_optional(&t.input_value.type_))
.collect::<Vec<_>>()
})
.pipe(|t| render_optional_field_args(funcs, t))
.flatten();
@@ -67,7 +81,7 @@ fn render_optional_field_args(
}
let rendered_args = args.into_iter().map(|a| &a.input_value).map(|a| {
quote! {
pub $(format_struct_name(&a.name)): $(funcs.format_output_type(&a.type_)),
pub $(format_struct_name(&a.name)): Option<$(funcs.format_output_type(&a.type_))>,
}
});
@@ -75,3 +89,24 @@ fn render_optional_field_args(
$(for arg in rendered_args join ($['\r']) => $arg)
})
}
fn render_functions(funcs: &CommonFunctions, fields: &Vec<FullTypeFields>) -> Option<rust::Tokens> {
let rendered_functions = fields
.iter()
.map(|f| render_function(funcs, f))
.collect::<Vec<_>>();
if rendered_functions.len() > 0 {
Some(quote! {
$(for func in rendered_functions join ($['\r']) => $func)
})
} else {
None
}
}
fn render_function(funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> {
Some(quote! {
$(format_function(funcs, field))
})
}

View File

@@ -3,9 +3,14 @@ use genco::prelude::rust;
use genco::quote;
use crate::rust::functions::format_name;
use crate::utility::OptionExt;
pub fn render_scalar(t: &FullType) -> eyre::Result<rust::Tokens> {
let deserialize = rust::import("serde", "Deserialize");
let serialize = rust::import("serde", "Serialize");
Ok(quote! {
pub struct $(format_name(&t.name.as_ref().unwrap()))(String);
#[derive($serialize, $deserialize)]
pub struct $(t.name.pipe(|n|format_name(n)))(String);
})
}

View File

@@ -1,8 +1,12 @@
[package]
name = "dagger-core"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
readme = "README.md"
license-file = "LICENSE.MIT"
description = "dagger sdk core library"
repository = "https://github.com/kjuulh/dagger-rs"
publish = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@@ -0,0 +1,7 @@
Copyright 2023 Kasper J. Hermansen
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

View File

@@ -89,17 +89,22 @@ impl InnerCliSession {
std::thread::spawn(move || {
let stdout_bufr = BufReader::new(stdout);
for line in stdout_bufr.lines() {
let out = line.unwrap();
let out = line.as_ref().unwrap();
if let Ok(conn) = serde_json::from_str::<ConnectParams>(&out) {
sender.send(conn).unwrap();
}
if let Ok(line) = line {
println!("dagger: {}", line);
}
}
});
std::thread::spawn(|| {
let stderr_bufr = BufReader::new(stderr);
for line in stderr_bufr.lines() {
let out = line.unwrap();
if let Ok(line) = line {
println!("dagger: {}", line);
}
//panic!("could not start dagger session: {}", out)
}
});

View File

@@ -1,16 +1,18 @@
[package]
name = "dagger-sdk"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
readme = "README.md"
license-file = "LICENSE.MIT"
description = "A dagger sdk for rust, written in rust"
repository = "https://github.com/kjuulh/dagger-rs"
publish = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
base64 = "0.21.0"
dagger-core = { path = "../dagger-core" }
dagger-core = { path = "../dagger-core", version = "0.2.0" }
eyre = "0.6.8"
futures = "0.3.26"
@@ -20,3 +22,6 @@ pretty_assertions = "1.3.0"
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.92"
tokio = { version = "1.25.0", features = ["full"] }
[dev-dependencies]
rand = "0.8.5"

View File

@@ -2,14 +2,46 @@
A dagger sdk written in rust for rust.
## Disclaimer
## Examples
Work in progress. This is not ready for usage yet
See [examples](./examples/)
### Status
Run them like so
- [x] dagger cli downloader
- [x] dagger network session
- [ ] graphql rust codegen (User API)
- [ ] fix build / release cycle
- [ ] general api stabilisation
```bash
cargo run --example first-pipeline
```
The examples match the folder name in each directory in examples
## Install
Simply install like:
```bash
cargo install dagger-sdk
```
### Usage
```rust
fn main() -> eyre::Result<()> {
let client = dagger_sdk::client::connect()?;
let version = client
.container(None)
.from("golang:1.19".into())
.with_exec(vec!["go".into(), "version".into()], None)
.stdout();
println!("Hello from Dagger and {}", version.trim());
Ok(())
}
```
And run it like a normal application:
```bash
cargo run
```

View File

@@ -0,0 +1,25 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
build-*

View File

@@ -0,0 +1,17 @@
# React Build
This is based on the [Getting Started guide for Nodejs](https://docs.dagger.io/sdk/nodejs/783645/get-started#step-5-test-against-multiple-nodejs-versions)
A simple react app is created with `create-react-app` which is built and tested by `build.js` or `build.ts`.
Run:
`npm install`
and then:
`node --loader ts-node/esm ./build.ts`
or
`node ./build.js`

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
{
"name": "react-build",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.6",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"ts-node": "^10.9.1",
"typescript": "^4.9.3",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"type": "module",
"devDependencies": {
"@dagger.io/dagger": "^0.3.2"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View File

@@ -0,0 +1,38 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

View File

@@ -0,0 +1,9 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

View File

@@ -0,0 +1,26 @@
import React from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;

View File

@@ -0,0 +1,13 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

View File

@@ -0,0 +1,19 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1 @@
/// <reference types="react-scripts" />

View File

@@ -0,0 +1,15 @@
import { ReportHandler } from 'web-vitals';
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

View File

@@ -0,0 +1,5 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

View File

@@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}

View File

@@ -0,0 +1,44 @@
use dagger_sdk::gen::HostDirectoryOpts;
fn main() -> eyre::Result<()> {
let client = dagger_sdk::client::connect()?;
let host_source_dir = client.host().directory(
"examples/build-the-application/app".into(),
Some(HostDirectoryOpts {
exclude: Some(vec!["node_modules".into(), "ci/".into()]),
include: None,
}),
);
let source = client
.container(None)
.from("node:16".into())
.with_mounted_directory("/src".into(), host_source_dir.id());
let runner = source
.with_workdir("/src".into())
.with_exec(vec!["npm".into(), "install".into()], None);
let test = runner.with_exec(
vec![
"npm".into(),
"test".into(),
"--".into(),
"--watchAll=false".into(),
],
None,
);
let build_dir = test
.with_exec(vec!["npm".into(), "run".into(), "build".into()], None)
.directory("./build".into());
let _ = build_dir.export("./build".into());
let entries = build_dir.entries(None);
println!("build dir contents: \n {:?}", entries);
Ok(())
}

View File

@@ -0,0 +1,25 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
build-*

View File

@@ -0,0 +1,17 @@
# React Build
This is based on the [Getting Started guide for Nodejs](https://docs.dagger.io/sdk/nodejs/783645/get-started#step-5-test-against-multiple-nodejs-versions)
A simple react app is created with `create-react-app` which is built and tested by `build.js` or `build.ts`.
Run:
`npm install`
and then:
`node --loader ts-node/esm ./build.ts`
or
`node ./build.js`

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
{
"name": "react-build",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.6",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"ts-node": "^10.9.1",
"typescript": "^4.9.3",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"type": "module",
"devDependencies": {
"@dagger.io/dagger": "^0.3.2"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View File

@@ -0,0 +1,38 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

View File

@@ -0,0 +1,9 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

View File

@@ -0,0 +1,26 @@
import React from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;

View File

@@ -0,0 +1,13 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

View File

@@ -0,0 +1,19 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1 @@
/// <reference types="react-scripts" />

View File

@@ -0,0 +1,15 @@
import { ReportHandler } from 'web-vitals';
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

View File

@@ -0,0 +1,5 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

View File

@@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}

View File

@@ -0,0 +1,55 @@
use dagger_sdk::gen::HostDirectoryOpts;
use rand::Rng;
fn main() -> eyre::Result<()> {
let client = dagger_sdk::client::connect()?;
let host_source_dir = client.host().directory(
"./examples/caching/app".into(),
Some(HostDirectoryOpts {
exclude: Some(vec!["node_modules".into(), "ci/".into()]),
include: None,
}),
);
let node_cache = client.cache_volume("node".into()).id();
let source = client
.container(None)
.from("node:16".into())
.with_mounted_directory("/src".into(), host_source_dir.id())
.with_mounted_cache("/src/node_modules".into(), node_cache, None);
let runner = source
.with_workdir("/src".into())
.with_exec(vec!["npm".into(), "install".into()], None);
let test = runner.with_exec(
vec![
"npm".into(),
"test".into(),
"--".into(),
"--watchAll=false".into(),
],
None,
);
let build_dir = test
.with_exec(vec!["npm".into(), "run".into(), "build".into()], None)
.directory("./build".into());
let mut rng = rand::thread_rng();
let ref_ = client
.container(None)
.from("nginx".into())
.with_directory("/usr/share/nginx/html".into(), build_dir.id(), None)
.publish(
format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::<u64>()),
None,
);
println!("published image to: {}", ref_);
Ok(())
}

View File

@@ -0,0 +1,25 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
build-*

View File

@@ -0,0 +1,15 @@
FROM node:16 as builder
COPY . /src
WORKDIR /src
RUN npm install
RUN npm test -- --watchAll=false
RUN npm run build
FROM nginx
COPY --from=builder /src/build /usr/share/nginx/html

View File

@@ -0,0 +1,17 @@
# React Build
This is based on the [Getting Started guide for Nodejs](https://docs.dagger.io/sdk/nodejs/783645/get-started#step-5-test-against-multiple-nodejs-versions)
A simple react app is created with `create-react-app` which is built and tested by `build.js` or `build.ts`.
Run:
`npm install`
and then:
`node --loader ts-node/esm ./build.ts`
or
`node ./build.js`

View File

@@ -0,0 +1,2 @@
node_modules/
build/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
{
"name": "react-build",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.6",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"ts-node": "^10.9.1",
"typescript": "^4.9.3",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"type": "module",
"devDependencies": {
"@dagger.io/dagger": "^0.3.2"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View File

@@ -0,0 +1,38 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

View File

@@ -0,0 +1,9 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

View File

@@ -0,0 +1,26 @@
import React from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;

View File

@@ -0,0 +1,13 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

View File

@@ -0,0 +1,19 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1 @@
/// <reference types="react-scripts" />

View File

@@ -0,0 +1,15 @@
import { ReportHandler } from 'web-vitals';
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

View File

@@ -0,0 +1,5 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

View File

@@ -0,0 +1,26 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}

View File

@@ -0,0 +1,24 @@
use rand::Rng;
fn main() -> eyre::Result<()> {
let mut rng = rand::thread_rng();
let client = dagger_sdk::client::connect()?;
let context_dir = client
.host()
.directory("./examples/existing-dockerfile/app".into(), None);
let ref_ = client
.container(None)
.build(context_dir.id(), None)
.publish(
format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::<u64>()),
None,
);
println!("published image to: {}", ref_);
Ok(())
}

View File

@@ -0,0 +1,13 @@
fn main() -> eyre::Result<()> {
let client = dagger_sdk::client::connect()?;
let version = client
.container(None)
.from("golang:1.19".into())
.with_exec(vec!["go".into(), "version".into()], None)
.stdout();
println!("Hello from Dagger and {}", version.trim());
Ok(())
}

View File

@@ -0,0 +1,25 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
build-*

View File

@@ -0,0 +1,17 @@
# React Build
This is based on the [Getting Started guide for Nodejs](https://docs.dagger.io/sdk/nodejs/783645/get-started#step-5-test-against-multiple-nodejs-versions)
A simple react app is created with `create-react-app` which is built and tested by `build.js` or `build.ts`.
Run:
`npm install`
and then:
`node --loader ts-node/esm ./build.ts`
or
`node ./build.js`

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
{
"name": "react-build",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.6",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"ts-node": "^10.9.1",
"typescript": "^4.9.3",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"type": "module",
"devDependencies": {
"@dagger.io/dagger": "^0.3.2"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View File

@@ -0,0 +1,38 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

Some files were not shown because too many files have changed in this diff Show More