add create subcommands

parent b92ae51f
......@@ -5,6 +5,10 @@ import (
"path/filepath"
)
type CreateEnv struct {
Config string
}
type HyprEnv struct {
Config string
SystemModulesDir string
......@@ -17,6 +21,7 @@ type RepoEnv struct {
type Environment struct {
Version string
Create *CreateEnv
Hyprland *HyprEnv
Repo *RepoEnv
}
......@@ -34,6 +39,10 @@ func InitConfig() error {
home, _ := os.UserHomeDir()
Env.Create = &CreateEnv{
Config: "/etc/ximperdistro/ximperconf/profiles.json",
}
if Env.Hyprland != nil {
userModulesPath := filepath.Join(home, ".config", "hypr")
systemModulesPath := "/etc/ximperdistro/hyprland/hypr"
......
package create
import (
"ximperconf/config"
"context"
"encoding/json"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/fatih/color"
"github.com/urfave/cli/v3"
)
func processProfile(entries []LinkEntry, dryRun bool) {
for _, entry := range entries {
if len(entry.Apps) > 0 {
for _, app := range entry.Apps {
if commandExists(app) {
sys := expandPath(entry.Sys, app)
user := expandPath(entry.User, app)
_ = createLinkIfMissing(sys, user, dryRun)
}
}
continue
}
if entry.App != "" && !commandExists(entry.App) {
continue
}
sys := expandPath(entry.Sys, "")
user := expandPath(entry.User, "")
_ = createLinkIfMissing(sys, user, dryRun)
}
}
func loadConfig(path string) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
var cfg Config
err = json.Unmarshal(data, &cfg)
return &cfg, err
}
func expandPath(path, name string) string {
home := os.Getenv("HOME")
if strings.HasPrefix(path, "~") {
path = filepath.Join(os.Getenv("HOME"), path[1:])
}
path = strings.ReplaceAll(path, "{home}", home)
return strings.ReplaceAll(path, "{name}", name)
}
func commandExists(name string) bool {
_, err := exec.LookPath(name)
return err == nil
}
func createLinkIfMissing(src, dest string, dryRun bool) error {
if _, err := os.Stat(src); os.IsNotExist(err) {
return nil
}
if _, err := os.Lstat(dest); err == nil {
if dryRun {
color.Yellow("[Dry-run] Уже существует: %s — пропущено", dest)
} else {
color.Yellow("Уже существует: %s — пропущено", dest)
}
return nil
}
if dryRun {
color.Blue("[Dry-run] Создана ссылка: %s → %s", dest, src)
return nil
}
if err := os.MkdirAll(filepath.Dir(dest), 0755); err != nil {
return err
}
if err := os.Symlink(src, dest); err != nil {
return err
}
color.Blue("Создана ссылка: %s → %s", dest, src)
return nil
}
func createProfile(profile string, dryRun bool) error {
cfg, err := loadConfig(config.Env.Create.Config)
if err != nil {
color.Red("Не удалось загрузить конфигурацию: %v", err)
return err
}
prof, ok := cfg.Profiles[profile]
if !ok {
color.Red("Профиль %s не найден", profile)
return nil
}
color.Green("Создаётся профиль: %s", profile)
processProfile(prof.Links, dryRun)
return nil
}
func CreateConfCommand(ctx context.Context, cmd *cli.Command) error {
profile := cmd.Args().Get(0)
dryRun := cmd.Bool("dry-run")
createProfile(profile, dryRun)
return nil
}
package create
import (
"context"
"fmt"
"os/exec"
"ximperconf/config"
"github.com/urfave/cli/v3"
)
func CommandList() *cli.Command {
return &cli.Command{
Name: "create",
Usage: "Creating a configuration",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "dry-run",
Usage: "Show what would be created without making changes.",
Aliases: []string{"d"},
Value: false,
},
},
Action: CreateConfCommand,
ShellComplete: ShellCompleteProfiles,
}
}
func ShellCompleteProfiles(ctx context.Context, cmd *cli.Command) {
if cmd.NArg() > 0 {
return
}
cfg, err := loadConfig(config.Env.Create.Config)
if err != nil {
return
}
for profileName, profile := range cfg.Profiles {
show := true
if profile.Binary != "" {
if _, err := exec.LookPath(profile.Binary); err != nil {
show = false
}
}
if show {
fmt.Println(profileName)
}
}
}
package create
type LinkEntry struct {
Apps []string `json:"apps,omitempty"`
App string `json:"app,omitempty"`
Sys string `json:"sys"`
User string `json:"user"`
}
type Profile struct {
Binary string `json:"binary,omitempty"`
Links []LinkEntry `json:"links"`
}
type Config struct {
Profiles map[string]Profile `json:"profiles"`
}
......@@ -2,7 +2,7 @@
function __fish_ximperconf_no_subcommand --description 'Test if there has been any subcommand yet'
for i in (commandline -opc)
if contains -- $i repo hyprland help h completion
if contains -- $i repo create hyprland help h completion
return 1
end
end
......@@ -18,6 +18,8 @@ function __fish_ximperconf_complete
end
end
complete -c ximperconf -n '__fish_seen_subcommand_from create' -f -a '(__fish_ximperconf_complete)'
complete -c ximperconf -n '__fish_seen_subcommand_from hyprland; and __fish_seen_subcommand_from var; and __fish_seen_subcommand_from set' -f -a '(__fish_ximperconf_complete)'
complete -c ximperconf -n '__fish_seen_subcommand_from hyprland; and __fish_seen_subcommand_from var; and __fish_seen_subcommand_from get' -f -a '(__fish_ximperconf_complete)'
complete -c ximperconf -n '__fish_seen_subcommand_from hyprland; and __fish_seen_subcommand_from var; and __fish_seen_subcommand_from unset' -f -a '(__fish_ximperconf_complete)'
......@@ -38,6 +40,9 @@ complete -x -c ximperconf -n '__fish_seen_subcommand_from repo; and __fish_seen_
complete -c ximperconf -n '__fish_seen_subcommand_from repo; and __fish_seen_subcommand_from deferred; and __fish_seen_subcommand_from date' -f -l help -s h -d 'show help'
complete -x -c ximperconf -n '__fish_seen_subcommand_from repo; and __fish_seen_subcommand_from deferred; and not __fish_seen_subcommand_from info date last-update' -a 'last-update' -d 'Date of last update'
complete -c ximperconf -n '__fish_seen_subcommand_from repo; and __fish_seen_subcommand_from deferred; and __fish_seen_subcommand_from last-update' -f -l help -s h -d 'show help'
complete -x -c ximperconf -n '__fish_ximperconf_no_subcommand' -a 'create' -d 'Creating a configuration'
complete -c ximperconf -n '__fish_seen_subcommand_from create' -f -l dry-run -s d -d 'Show what would be created without making changes.'
complete -c ximperconf -n '__fish_seen_subcommand_from create' -f -l help -s h -d 'show help'
complete -x -c ximperconf -n '__fish_ximperconf_no_subcommand' -a 'hyprland' -d 'Hyprland Management'
complete -c ximperconf -n '__fish_seen_subcommand_from hyprland' -f -l help -s h -d 'show help'
complete -x -c ximperconf -n '__fish_seen_subcommand_from hyprland; and not __fish_seen_subcommand_from check sync-xkb-layouts module var' -a 'check' -d 'Check the Hyprland config'
......
......@@ -4,6 +4,7 @@ import (
"context"
"os"
"ximperconf/config"
"ximperconf/create"
"ximperconf/hyprland"
"ximperconf/repo"
......@@ -23,6 +24,7 @@ func main() {
Version: config.Env.Version,
Commands: []*cli.Command{
repo.CommandList(),
create.CommandList(),
hyprland.CommandList(),
{
Name: "help",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment