feat(office): add Workspace TUI with shared bootstrap and test suite
Introduce the office Bubble Tea browser (module tree, multi-select lists, markdown preview) alongside oo, with cmd/internal/bootstrap for shared auth, unit tests across preview/model/ui/fetch, CI build for both binaries, and GoReleaser archives for office. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+2
-32
@@ -9,7 +9,7 @@ import (
|
||||
"text/tabwriter"
|
||||
|
||||
onlyoffice "github.com/eslider/go-onlyoffice"
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/eslider/go-onlyoffice/cmd/internal/bootstrap"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -36,37 +36,7 @@ func execute() error { return rootCmd.Execute() }
|
||||
// newOO loads env (only .env in CWD) and returns an authenticated client.
|
||||
// godotenv is a CLI-only concern; the library itself never loads dotfiles.
|
||||
func newOO(cmd *cobra.Command) (*onlyoffice.Client, error) {
|
||||
loadOOEnv()
|
||||
creds := onlyoffice.GetEnvironmentCredentials()
|
||||
if creds.Url == "" || creds.User == "" || creds.Password == "" {
|
||||
return nil, fmt.Errorf("need ONLYOFFICE_URL (or ONLYOFFICE_HOST/OO_URL), user (ONLYOFFICE_USER or ONLYOFFICE_NAME/OO_USER), password (ONLYOFFICE_PASS or ONLYOFFICE_PASSWORD/OO_PASS)")
|
||||
}
|
||||
c := onlyoffice.NewClient(creds)
|
||||
c.SetDefaults(onlyoffice.GetEnvironmentDefaults())
|
||||
if err := c.AuthenticateContext(cmd.Context()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func loadOOEnv() {
|
||||
_ = godotenv.Load(".env")
|
||||
applyOOEnvAliases()
|
||||
}
|
||||
|
||||
func applyOOEnvAliases() {
|
||||
setEnvIfEmpty("ONLYOFFICE_URL", "OO_URL")
|
||||
setEnvIfEmpty("ONLYOFFICE_USER", "OO_USER")
|
||||
setEnvIfEmpty("ONLYOFFICE_PASS", "OO_PASS")
|
||||
}
|
||||
|
||||
func setEnvIfEmpty(dst, src string) {
|
||||
if strings.TrimSpace(os.Getenv(dst)) != "" {
|
||||
return
|
||||
}
|
||||
if v := strings.TrimSpace(os.Getenv(src)); v != "" {
|
||||
_ = os.Setenv(dst, v)
|
||||
}
|
||||
return bootstrap.NewClient(cmd.Context())
|
||||
}
|
||||
|
||||
// printJSON dumps any value as indented JSON.
|
||||
|
||||
@@ -8,46 +8,6 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLoadOOEnvFromCWDWithOOAliases(t *testing.T) {
|
||||
clearEnv(t, "ONLYOFFICE_URL", "ONLYOFFICE_USER", "ONLYOFFICE_PASS", "OO_URL", "OO_USER", "OO_PASS")
|
||||
dir := t.TempDir()
|
||||
oldwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.Chdir(dir); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { _ = os.Chdir(oldwd) })
|
||||
|
||||
if err := os.WriteFile(".env", []byte("OO_URL=https://office.example.com\nOO_USER=user@example.com\nOO_PASS=secret\n"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
loadOOEnv()
|
||||
if got := os.Getenv("ONLYOFFICE_URL"); got != "https://office.example.com" {
|
||||
t.Fatalf("ONLYOFFICE_URL=%q", got)
|
||||
}
|
||||
if got := os.Getenv("ONLYOFFICE_USER"); got != "user@example.com" {
|
||||
t.Fatalf("ONLYOFFICE_USER=%q", got)
|
||||
}
|
||||
if got := os.Getenv("ONLYOFFICE_PASS"); got != "secret" {
|
||||
t.Fatalf("ONLYOFFICE_PASS=%q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyOOEnvAliasesDoesNotOverrideCanonical(t *testing.T) {
|
||||
clearEnv(t, "ONLYOFFICE_URL", "OO_URL")
|
||||
t.Setenv("ONLYOFFICE_URL", "https://canonical.example")
|
||||
t.Setenv("OO_URL", "https://alias.example")
|
||||
|
||||
applyOOEnvAliases()
|
||||
|
||||
if got := os.Getenv("ONLYOFFICE_URL"); got != "https://canonical.example" {
|
||||
t.Fatalf("ONLYOFFICE_URL=%q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFmtCell(t *testing.T) {
|
||||
tests := []struct {
|
||||
in any
|
||||
|
||||
Reference in New Issue
Block a user