Compare commits

...

10 Commits

Author SHA1 Message Date
299f6dea06 bump version to 1.0.13 2025-02-10 15:53:30 +03:00
ed025f9acb ... 2025-02-10 15:53:06 +03:00
c4ea066927 bump version to 1.0.12 2025-02-10 12:43:27 +03:00
5f9c6ff2bb ... 2025-02-10 12:41:14 +03:00
8965f7ae89 bump version to 1.0.10 2025-02-10 12:08:03 +03:00
9a931b65e2 bump version to 1.0.9 2025-02-10 09:42:52 +03:00
2c149507f6 fixes 2025-02-10 09:42:09 +03:00
timurgordon
34dea39c52 ... 2025-02-09 20:13:18 +00:00
timurgordon
f1a4547961 Merge branch 'development' of https://github.com/freeflowuniverse/herolib into development 2025-02-09 17:55:25 +00:00
timurgordon
8ae56a8df6 new 2025-02-09 17:53:16 +00:00
17 changed files with 579 additions and 51 deletions

2
cli/.gitignore vendored
View File

@@ -1 +1,3 @@
hero
compile
compile_upload

View File

@@ -51,7 +51,7 @@ fn do() ! {
mut cmd := Command{
name: 'hero'
description: 'Your HERO toolset.'
version: '1.0.8'
version: '1.0.13'
}
// herocmds.cmd_run_add_flags(mut cmd)

View File

@@ -4,7 +4,7 @@ set -e
os_name="$(uname -s)"
arch_name="$(uname -m)"
version='1.0.8'
version='1.0.13'
# Base URL for GitHub releases

View File

@@ -0,0 +1,153 @@
module livekit
// import time
// import rand
// import crypto.hmac
// import crypto.sha256
// import encoding.base64
// import json
// // Define AccessTokenOptions struct
// pub struct AccessTokenOptions {
// pub mut:
// ttl int | string // TTL in seconds or a time span (e.g., '2d', '5h')
// name string // Display name for the participant
// identity string // Identity of the user
// metadata string // Custom metadata to be passed to participants
// }
// // Struct representing grants
// pub struct ClaimGrants {
// pub mut:
// video VideoGrant
// iss string
// exp i64
// nbf int
// sub string
// name string
// }
// // VideoGrant struct placeholder
// pub struct VideoGrant {
// pub mut:
// room string
// room_join bool @[json: 'roomJoin']
// can_publish bool @[json: 'canPublish']
// can_publish_data bool @[json: 'canPublishData']
// can_subscribe bool @[json: 'canSubscribe']
// }
// // SIPGrant struct placeholder
// struct SIPGrant {}
// // AccessToken class
// pub struct AccessToken {
// mut:
// api_key string
// api_secret string
// grants ClaimGrants
// identity string
// ttl int | string
// }
// // Constructor for AccessToken
// pub fn new_access_token(api_key string, api_secret string, options AccessTokenOptions) !AccessToken {
// if api_key == '' || api_secret == '' {
// return error('API key and API secret must be set')
// }
// ttl := if options.ttl is int { options.ttl } else { 21600 } // Default TTL of 6 hours (21600 seconds)
// return AccessToken{
// api_key: api_key
// api_secret: api_secret
// identity: options.identity
// ttl: ttl
// grants: ClaimGrants{
// exp: time.now().unix()+ttl
// iss: api_key
// sub: options.name
// name: options.name
// }
// }
// }
// // Method to add a video grant to the token
// pub fn (mut token AccessToken) add_video_grant(grant VideoGrant) {
// token.grants.video = grant
// }
// // Method to generate a JWT token
// pub fn (token AccessToken) to_jwt() !string {
// // Create JWT payload
// payload := json.encode(token.grants)
// println('payload: ${payload}')
// // Create JWT header
// header := '{"alg":"HS256","typ":"JWT"}'
// // Encode header and payload in base64
// header_encoded := base64.url_encode_str(header)
// payload_encoded := base64.url_encode_str(payload)
// // Create the unsigned token
// unsigned_token := '${header_encoded}.${payload_encoded}'
// // Create the HMAC-SHA256 signature
// signature := hmac.new(token.api_secret.bytes(), unsigned_token.bytes(), sha256.sum, sha256.block_size)
// // Encode the signature in base64
// signature_encoded := base64.url_encode(signature)
// // Create the final JWT
// jwt := '${unsigned_token}.${signature_encoded}'
// return jwt
// }
// // TokenVerifier class
// pub struct TokenVerifier {
// api_key string
// api_secret string
// }
// // Constructor for TokenVerifier
// pub fn new_token_verifier(api_key string, api_secret string) !TokenVerifier {
// if api_key == '' || api_secret == '' {
// return error('API key and API secret must be set')
// }
// return TokenVerifier{
// api_key: api_key
// api_secret: api_secret
// }
// }
// // Method to verify the JWT token
// pub fn (verifier TokenVerifier) verify(token string) !ClaimGrants {
// // Split the token into parts
// parts := token.split('.')
// if parts.len != 3 {
// return error('Invalid token')
// }
// // Decode header, payload, and signature
// payload_encoded := parts[1]
// signature_encoded := parts[2]
// // Recompute the HMAC-SHA256 signature
// unsigned_token := '${parts[0]}.${parts[1]}'
// expected_signature := hmac.new(verifier.api_secret.bytes(), unsigned_token.bytes(), sha256.sum, sha256.block_size)
// expected_signature_encoded := base64.url_encode(expected_signature)
// // Verify the signature
// if signature_encoded != expected_signature_encoded {
// return error('Invalid token signature')
// }
// // Decode the payload
// payload_json := base64.url_decode_str(payload_encoded)
// // Parse and return the claims as ClaimGrants
// return json.decode(ClaimGrants, payload_json)
// }

View File

@@ -0,0 +1,199 @@
module livekit
import net.http
import json
// // pub struct Client {
// // pub:
// // host string
// // token string
// // }
// // pub struct Room {
// // pub mut:
// // sid string
// // name string
// // empty_timeout string
// // max_participants string
// // creation_time string
// // turn_password string
// // metadata string
// // num_participants u32
// // active_recording bool
// // }
// pub struct ParticipantInfo {
// pub mut:
// sid string
// identity string
// name string
// state string
// tracks []TrackInfo
// metadata string
// joined_at i64
// permission ParticipantPermission
// is_publisher bool
// }
// pub struct TrackInfo {
// pub mut:
// sid string
// typ string @[json: 'type']
// source string
// name string
// mime_type string
// muted bool
// width u32
// height u32
// simulcast bool
// disable_dtx bool
// layers []VideoLayer
// }
// pub struct ParticipantPermission {
// pub mut:
// can_subscribe bool
// can_publish bool
// can_publish_data bool
// }
// pub struct VideoLayer {
// pub mut:
// quality string
// width u32
// height u32
// }
// // Helper method to make POST requests to LiveKit API
// fn (client Client) make_post_request(url string, body string) !http.Response {
// mut headers := http.new_header()
// headers.add_custom('Authorization', 'Bearer ${client.token}')!
// headers.add_custom('Content-Type', 'application/json')!
// req := http.Request{
// method: http.Method.post
// url: url
// data: body
// header: headers
// }
// return req.do()!
// }
// pub struct CreateRoomArgs {
// pub:
// name string
// empty_timeout u32
// max_participants u32
// metadata string
// }
// // RoomService API methods
// pub fn (client Client) create_room(args CreateRoomArgs) !Room {
// body := json.encode(args)
// url := '${client.host}/twirp/livekit.RoomService/CreateRoom'
// response := client.make_post_request(url, body)!
// return json.decode(Room, response.body)!
// }
// // pub fn (client Client) list_rooms(names []string) ![]Room {
// // body := json.encode({
// // 'names': names
// // })
// // url := '${client.host}/twirp/livekit.RoomService/ListRooms'
// // response := client.make_post_request(url, body)!
// // return json.decode([]Room, response.body)!
// // }
// pub fn (client Client) delete_room(room_name string) ! {
// body := json.encode({
// 'room': room_name
// })
// url := '${client.host}/twirp/livekit.RoomService/DeleteRoom'
// _ := client.make_post_request(url, body)!
// }
// pub fn (client Client) list_participants(room_name string) ![]ParticipantInfo {
// body := json.encode({
// 'room': room_name
// })
// url := '${client.host}/twirp/livekit.RoomService/ListParticipants'
// response := client.make_post_request(url, body)!
// return json.decode([]ParticipantInfo, response.body)!
// }
// pub fn (client Client) get_participant(room_name string, identity string) !ParticipantInfo {
// body := json.encode({
// 'room': room_name
// 'identity': identity
// })
// url := '${client.host}/twirp/livekit.RoomService/GetParticipant'
// response := client.make_post_request(url, body)!
// return json.decode(ParticipantInfo, response.body)!
// }
// pub fn (client Client) remove_participant(room_name string, identity string) ! {
// body := json.encode({
// 'room': room_name
// 'identity': identity
// })
// url := '${client.host}/twirp/livekit.RoomService/RemoveParticipant'
// _ := client.make_post_request(url, body)!
// }
// pub struct MutePublishedTrackArgs {
// pub:
// room_name string
// identity string
// track_sid string
// muted bool
// }
// pub fn (client Client) mute_published_track(args MutePublishedTrackArgs) ! {
// body := json.encode(args)
// url := '${client.host}/twirp/livekit.RoomService/MutePublishedTrack'
// _ := client.make_post_request(url, body)!
// }
// pub struct UpdateParticipantArgs {
// pub:
// room_name string @[json: 'room']
// identity string
// metadata string
// permission ParticipantPermission
// }
// pub fn (client Client) update_participant(args UpdateParticipantArgs) ! {
// body := json.encode(args)
// url := '${client.host}/twirp/livekit.RoomService/UpdateParticipant'
// _ := client.make_post_request(url, body)!
// }
// pub struct UpdateRoomMetadataArgs {
// pub:
// room_name string @[json: 'room']
// metadata string
// }
// pub fn (client Client) update_room_metadata(args UpdateRoomMetadataArgs) ! {
// body := json.encode(args)
// url := '${client.host}/twirp/livekit.RoomService/UpdateRoomMetadata'
// _ := client.make_post_request(url, body)!
// }
// pub struct SendDataArgs {
// pub:
// room_name string @[json: 'room']
// data []u8
// kind string
// destination_identities []string
// }
// pub fn (client Client) send_data(args SendDataArgs) ! {
// body := json.encode(args)
// url := '${client.host}/twirp/livekit.RoomService/SendData'
// _ := client.make_post_request(url, body)!
// }

View File

@@ -29,19 +29,37 @@ pub fn cmd_docusaurus(mut cmdroot Command) {
description: 'Url where docusaurus source is.'
})
cmd_run.add_flag(Flag{
flag: .string
required: false
name: 'deploykey'
abbrev: 'dk'
// default: ''
description: 'Path of SSH Key used to deploy.'
})
cmd_run.add_flag(Flag{
flag: .string
required: false
name: 'publish'
// default: ''
description: 'Path where to publish.'
})
cmd_run.add_flag(Flag{
flag: .bool
required: false
name: 'build'
abbrev: 'b'
name: 'buildpublish'
abbrev: 'bp'
description: 'build and publish.'
})
cmd_run.add_flag(Flag{
flag: .bool
required: false
name: 'builddev'
abbrev: 'bd'
name: 'builddevpublish'
abbrev: 'bpd'
description: 'build dev version and publish.'
})
@@ -49,7 +67,6 @@ pub fn cmd_docusaurus(mut cmdroot Command) {
flag: .bool
required: false
name: 'update'
abbrev: 'p'
description: 'update your environment the template and the repo you are working on (git pull).'
})
@@ -67,6 +84,8 @@ pub fn cmd_docusaurus(mut cmdroot Command) {
fn cmd_docusaurus_execute(cmd Command) ! {
mut update := cmd.flags.get_bool('update') or { false }
mut url := cmd.flags.get_string('url') or { '' }
mut publish_path := cmd.flags.get_string('publish') or { '' }
mut deploykey := cmd.flags.get_string('deploykey') or { '' }
// mut path := cmd.flags.get_string('path') or { '' }
// if path == '' {
@@ -74,30 +93,42 @@ fn cmd_docusaurus_execute(cmd Command) ! {
// }
// path = path.replace('~', os.home_dir())
mut build := cmd.flags.get_bool('build') or { false }
mut builddev := cmd.flags.get_bool('builddev') or { false }
mut buildpublish := cmd.flags.get_bool('buildpublish') or { false }
mut builddevpublish := cmd.flags.get_bool('builddevpublish') or { false }
mut dev := cmd.flags.get_bool('dev') or { false }
// if build== false && build== false && build== false {
// eprintln("specify build, builddev or dev")
// exit(1)
// }
mut docs := docusaurus.new(update: update)!
if build {
// Create a new docusaurus site
if publish_path.len>0 {
_ := docs.build(
url: url
update: update
publish_path: publish_path
deploykey:deploykey
)!
}
if builddev {
if buildpublish {
// Create a new docusaurus site
_ := docs.build_dev(
_ := docs.build_publish(
url: url
update: update
deploykey:deploykey
)!
}
if builddevpublish {
// Create a new docusaurus site
_ := docs.build_dev_publish(
url: url
update: update
deploykey:deploykey
)!
}
@@ -106,6 +137,7 @@ fn cmd_docusaurus_execute(cmd Command) ! {
_ := docs.dev(
url: url
update: update
deploykey:deploykey
)!
}
}

View File

@@ -20,6 +20,7 @@ pub mut:
log bool = true // If true, logs git commands/statements
debug bool = true
ssh_key_name string // name of ssh key to be used when loading the gitstructure
ssh_key_path string
reload bool
}
@@ -35,6 +36,8 @@ pub fn new(args_ GitStructureArgsNew) !&GitStructure {
log: args.log
debug: args.debug
ssh_key_name: args.ssh_key_name
ssh_key_path: args.ssh_key_path
}
return get(coderoot: args.coderoot, reload: args.reload, cfg: cfg)
@@ -77,7 +80,19 @@ pub fn get(args_ GitStructureArgGet) !&GitStructure {
coderoot: pathlib.get_dir(path: args.coderoot, create: true)!
}
mut cfg := args.cfg or {
mut cfg_:=GitStructureConfig{coderoot:"SKIP"}
cfg_
}
if cfg.coderoot != "SKIP"{
gs.config_ = cfg
gs.config_save()!
//println(gs.config()!)
}
gs.config()! // will load the config, don't remove
gs.load(false)!
if gs.repos.keys().len == 0 || args.reload {

View File

@@ -14,8 +14,10 @@ pub mut:
log bool = true // If true, logs git commands/statements
debug bool = true
ssh_key_name string
ssh_key_path string
}
// GitStructure holds information about repositories within a specific code root.
// This structure keeps track of loaded repositories, their configurations, and their status.
@[heap]
@@ -233,6 +235,6 @@ pub fn (mut self GitStructure) config_reset() ! {
pub fn (mut self GitStructure) config_save() ! {
// Retrieve the configuration from Redis.
mut redis := redis_get()
datajson := json.encode(self.config)
datajson := json.encode(self.config()!)
redis.set('${self.cache_key()}:config', datajson)!
}

View File

@@ -34,7 +34,17 @@ pub fn (mut gitstructure GitStructure) clone(args GitCloneArgs) !&GitRepo {
extra = '--depth 1 --no-single-branch '
}
cmd := 'cd ${parent_dir} && git clone ${extra} ${repo.get_http_url()!} ${repo.name}'
cfg:=gitstructure.config()!
mut cmd := 'cd ${parent_dir} && git clone ${extra} ${repo.get_http_url()!} ${repo.name}'
mut sshkey_include := ""
if cfg.ssh_key_path.len>0{
sshkey_include="GIT_SSH_COMMAND=\"ssh -i ${cfg.ssh_key_path}\" "
cmd = 'cd ${parent_dir} && ${sshkey_include}git clone ${extra} ${repo.get_ssh_url()!} ${repo.name}'
}
console.print_debug(cmd)
result := os.execute(cmd)
if result.exit_code != 0 {
return error('Cannot clone the repository due to: \n${result.output}')

View File

@@ -22,7 +22,7 @@ fn installed() !bool {
if r.len != 1 {
return error("couldn't parse bun version.\n${res.output}")
}
println(' ${texttools.version(version)} <= ${texttools.version(r[0])}')
// println(' ${texttools.version(version)} <= ${texttools.version(r[0])}')
if texttools.version(version) <= texttools.version(r[0]) {
return true
}

View File

@@ -0,0 +1,38 @@
module authentication
import log
// // Creates and updates, authenticates email authentication sessions
// @[noinit]
// struct MemoryBackend {
// mut:
// sessions map[string]AuthSession
// logger &log.Logger = &log.Logger(&log.Log{
// level: .info
// })
// }
// // factory for
// pub fn new_memory_backend() !MemoryBackend {
// return MemoryBackend{}
// }
// fn (mut backend MemoryBackend) create_auth_session(session AuthSession) ! {
// backend.sessions[session.email] = session
// }
// fn (backend MemoryBackend) read_auth_session(email string) ?AuthSession {
// return backend.sessions[email] or { return none }
// }
// fn (mut backend MemoryBackend) update_auth_session(session AuthSession) ! {
// backend.sessions[session.email] = session
// }
// fn (mut backend MemoryBackend) set_session_authenticated(email string) ! {
// backend.sessions[email].authenticated = true
// }
// fn (mut backend MemoryBackend) delete_auth_session(email string) ! {
// backend.sessions.delete(email)
// }

View File

@@ -42,8 +42,8 @@ pub mut:
base_url string @[json: 'baseUrl']
image string
metadata MainMetadata
build_dest string @[json: 'buildDest']
build_dest_dev string @[json: 'buildDestDev']
build_dest []string @[json: 'buildDest']
build_dest_dev []string @[json: 'buildDestDev']
}
// Navbar config structures
@@ -80,8 +80,37 @@ pub fn load_config(cfg_dir string) !Config {
footer := json.decode(Footer, footer_content)!
// Load and parse main config
main_content := os.read_file(os.join_path(cfg_dir, 'main.json'))!
main := json.decode(Main, main_content)!
main_config_path := os.join_path(cfg_dir, 'main.json')
main_content := os.read_file(main_config_path)!
main := json.decode(Main, main_content) or {
eprintln("${main_config_path} is not in the right format please fix.")
println('
## EXAMPLE OF A GOOD ONE:
- note the list for buildDest and buildDestDev
- note its the full path where the html is pushed too
{
"title": "ThreeFold Web4",
"tagline": "ThreeFold Web4",
"favicon": "img/favicon.png",
"url": "https://docs.threefold.io",
"url_home": "docs/introduction",
"baseUrl": "/",
"image": "img/tf_graph.png",
"metadata": {
"description": "ThreeFold is laying the foundation for a geo aware Web 4, the next generation of the Internet.",
"image": "https://threefold.info/kristof/img/tf_graph.png",
"title": "ThreeFold Docs"
},
"buildDest":["root@info.ourworld.tf:/root/hero/www/info/tfgrid4"],
"buildDestDev":["root@info.ourworld.tf:/root/hero/www/infodev/tfgrid4"]
}
')
exit(99)
}
// Load and parse navbar config
navbar_content := os.read_file(os.join_path(cfg_dir, 'navbar.json'))!

View File

@@ -30,24 +30,12 @@ pub mut:
nameshort string
path string
url string
// publish_path string
publish_path string
build_path string
production bool
watch_changes bool = true
update bool
}
pub fn (mut f DocusaurusFactory) build_dev(args_ DSiteNewArgs) !&DocSite {
mut s := f.add(args_)!
s.generate()!
osal.exec(
cmd: '
cd ${s.path_build.path}
bash build_dev.sh
'
retry: 0
)!
return s
deploykey string
}
pub fn (mut f DocusaurusFactory) build(args_ DSiteNewArgs) !&DocSite {
@@ -63,6 +51,35 @@ pub fn (mut f DocusaurusFactory) build(args_ DSiteNewArgs) !&DocSite {
return s
}
pub fn (mut f DocusaurusFactory) build_dev_publish(args_ DSiteNewArgs) !&DocSite {
mut s := f.add(args_)!
s.generate()!
osal.exec(
cmd: '
cd ${s.path_build.path}
bash build_dev_publish.sh
'
retry: 0
)!
return s
}
pub fn (mut f DocusaurusFactory) build_publish(args_ DSiteNewArgs) !&DocSite {
mut s := f.add(args_)!
s.generate()!
osal.exec(
cmd: '
cd ${s.path_build.path}
bash build_publish.sh
'
retry: 0
)!
return s
}
pub fn (mut f DocusaurusFactory) dev(args_ DSiteNewArgs) !&DocSite {
mut s := f.add(args_)!
@@ -126,8 +143,10 @@ pub fn (mut f DocusaurusFactory) add(args_ DSiteNewArgs) !&DocSite {
// if args.publish_path.len == 0 {
// args.publish_path = '${f.path_publish.path}/${args.name}'
// coderoot:"${os.home_dir()}/hero/var/publishcode"
mut gs := gittools.new(ssh_key_path:args.deploykey)!
if args.url.len > 0 {
mut gs := gittools.new()!
args.path = gs.get_path(url: args.url)!
}
@@ -135,7 +154,6 @@ pub fn (mut f DocusaurusFactory) add(args_ DSiteNewArgs) !&DocSite {
return error("Can't get path from docusaurus site, its not specified.")
}
mut gs := gittools.new()!
mut r := gs.get_repo(
url: 'https://github.com/freeflowuniverse/docusaurus_template.git'
pull: args.update
@@ -204,6 +222,7 @@ pub fn (mut site DocSite) error(args ErrorArgs) {
pub fn (mut site DocSite) generate() ! {
console.print_header(' site generate: ${site.name} on ${site.path_build.path}')
console.print_header(' site source on ${site.path_src.path}')
site.template_install()!
// osal.exec(
// cmd: '
@@ -262,7 +281,8 @@ fn (mut site DocSite) template_install() ! {
develop := $tmpl('templates/develop.sh')
build := $tmpl('templates/build.sh')
build_dev := $tmpl('templates/build_dev.sh')
build_dev_publish := $tmpl('templates/build_dev_publish.sh')
build_publish := $tmpl('templates/build_publish.sh')
mut develop_ := site.path_build.file_get_new('develop.sh')!
develop_.template_write(develop, true)!
@@ -272,9 +292,13 @@ fn (mut site DocSite) template_install() ! {
build_.template_write(build, true)!
build_.chmod(0o700)!
mut build_dev_ := site.path_build.file_get_new('build_dev.sh')!
build_dev_.template_write(build_dev, true)!
build_dev_.chmod(0o700)!
mut build_publish_ := site.path_build.file_get_new('build_publish.sh')!
build_publish_.template_write(build_publish, true)!
build_publish_.chmod(0o700)!
mut build_dev_publish_ := site.path_build.file_get_new('build_dev_publish.sh')!
build_dev_publish_.template_write(build_dev_publish, true)!
build_dev_publish_.chmod(0o700)!
mut develop2_ := site.path_src.file_get_new('develop.sh')!
develop2_.template_write(develop, true)!
@@ -284,7 +308,5 @@ fn (mut site DocSite) template_install() ! {
build2_.template_write(build, true)!
build2_.chmod(0o700)!
mut build_dev2_ := site.path_src.file_get_new('build_dev.sh')!
build_dev2_.template_write(build_dev, true)!
build_dev2_.chmod(0o700)!
}

View File

@@ -1,9 +1,9 @@
#!/bin/bash
set -e
set -ex
script_dir="??(cd "??(dirname "??{BASH_SOURCE[0]}")" && pwd)"
cd "??{script_dir}"
script_dir="???cd "???dirname "??{BASH_SOURCE[0]}")" && pwd)"
cd "???script_dir}"
echo "Docs directory: ??script_dir"
@@ -17,4 +17,6 @@ ${profile_include}
bun docusaurus build
rsync -rv --delete ${site.path_build.path}/build/ ${cfg.main.build_dest.trim_right("/")}/${cfg.main.name.trim_right("/")}/
mkdir -p ${site.args.publish_path.trim_right("/")}
echo SYNC TO ${site.args.publish_path.trim_right("/")}
rsync -rv --delete ${site.path_build.path}/build/ ${site.args.publish_path.trim_right("/")}/

View File

@@ -2,7 +2,7 @@
set -e
script_dir="??(cd "??(dirname "??{BASH_SOURCE[0]}")" && pwd)"
script_dir="???cd "???dirname "??{BASH_SOURCE[0]}")" && pwd)"
cd "??{script_dir}"
@@ -18,4 +18,6 @@ ${profile_include}
bun docusaurus build
rsync -rv --delete ${site.path_build.path}/build/ ${cfg.main.build_dest_dev.trim_right("/")}/${cfg.main.name.trim_right("/")}/
@for dest in cfg.main.build_dest_dev
rsync -rv --delete ${site.path_build.path}/build/ ${dest.trim_right("/")}/
@end

View File

@@ -0,0 +1,22 @@
#!/bin/bash
set -ex
script_dir="???cd "???dirname "??{BASH_SOURCE[0]}")" && pwd)"
cd "??{script_dir}"
echo "Docs directory: ??script_dir"
cd ${site.path_build.path}
export PATH=/tmp/docusaurus_build/node_modules/.bin:??{HOME}/.bun/bin/:??PATH
rm -rf ${site.path_build.path}/build/
${profile_include}
bun docusaurus build
@for dest in cfg.main.build_dest
rsync -rv --delete ${site.path_build.path}/build/ ${dest.trim_right("/")}/
@end

View File

@@ -2,7 +2,7 @@
set -e
script_dir="??(cd "??(dirname "??{BASH_SOURCE[0]}")" && pwd)"
script_dir="???cd "???dirname "??{BASH_SOURCE[0]}")" && pwd)"
cd "??{script_dir}"
echo "Docs directory: ??script_dir"