diff --git a/README.md b/README.md
index 7b3b4af..7912cff 100644
--- a/README.md
+++ b/README.md
@@ -10,10 +10,6 @@

[](https://goreportcard.com/report/github.com/brsyuksel/shellican)
-
-

-
-
## Why shellican?
**shellican** bridges the gap between simple shell aliases and complex Makefile setups.
@@ -61,13 +57,17 @@ Default storage location: `~/.shellican` (or `$SHELLICAN_HOME/.shellican`).
### Commands
-- **New Collection**: `shellican new collection `
-- **New Runnable**: `shellican new runnable `
+- **New Collection**: `shellican new `
+- **New Runnable**: `shellican new `
- **Run**: `shellican run [args...]`
-- **List**: `shellican list collections` or `shellican list runnables `
-- **Show**: `shellican show collection ` or `shellican show runnable `
-- **Create Shell Shortcut**: `shellican create-shell ` (creates `~/.local/bin/-shell`)
-- **Import/Export**: `shellican import ` / `shellican export `
+- **List Collections**: `shellican list`
+- **List Runnables**: `shellican list `
+- **Show Collection**: `shellican show [--readme]`
+- **Show Runnable**: `shellican show [--readme]`
+- **Create Shell Helper**: `shellican create-shell [name]` (creates `~/.local/bin/-shell`)
+- **Import Collection**: `shellican import [name]`
+- **Export Collection**: `shellican export [output]`
+- **Version**: `shellican version`
## Configuration
diff --git a/assets/shellican.gif b/assets/shellican.gif
deleted file mode 100644
index 0527c11..0000000
Binary files a/assets/shellican.gif and /dev/null differ
diff --git a/pkg/config/loader.go b/pkg/config/loader.go
index 38147dd..7f2e8cf 100644
--- a/pkg/config/loader.go
+++ b/pkg/config/loader.go
@@ -60,3 +60,15 @@ func LoadRunnableConfig(path string) (*RunnableConfig, error) {
}
return &cfg, nil
}
+
+// SaveCollectionConfig saves the collection configuration to the given path.
+func SaveCollectionConfig(path string, cfg *CollectionConfig) error {
+ data, err := yaml.Marshal(cfg)
+ if err != nil {
+ return fmt.Errorf("failed to marshal collection config: %w", err)
+ }
+ if err := os.WriteFile(filepath.Join(path, "collection.yml"), data, 0644); err != nil {
+ return fmt.Errorf("failed to write collection.yml: %w", err)
+ }
+ return nil
+}
diff --git a/pkg/core/scaffold.go b/pkg/core/scaffold.go
index d89806b..29d694b 100644
--- a/pkg/core/scaffold.go
+++ b/pkg/core/scaffold.go
@@ -4,6 +4,8 @@ import (
"fmt"
"os"
"path/filepath"
+
+ "github.com/brsyuksel/shellican/pkg/config"
)
// CreateCollection creates a new collection.
@@ -26,7 +28,6 @@ func CreateCollection(name string) error {
help: "Usage for %s"
readme: "README.md"
runnables: []
- # - example_runnable
environments:
COLLECTION_ENV: "value"
`, name, name)
@@ -88,7 +89,32 @@ environments:
fmt.Printf("Warning: failed to create README.md: %v\n", err)
}
- fmt.Printf("Runnable '%s' created at %s\n", runnableName, runnablePath)
- fmt.Println("Hint: Don't forget to add it to 'runnables' in collection.yml!")
+ // Load collection config and add the runnable
+ collectionCfg, err := config.LoadCollectionConfig(collectionPath)
+ if err != nil {
+ return fmt.Errorf("failed to load collection config: %w", err)
+ }
+ if collectionCfg == nil {
+ return fmt.Errorf("collection config not found")
+ }
+
+ // Add runnable to the list if not already present
+ found := false
+ for _, r := range collectionCfg.Runnables {
+ if r == runnableName {
+ found = true
+ break
+ }
+ }
+ if !found {
+ collectionCfg.Runnables = append(collectionCfg.Runnables, runnableName)
+ }
+
+ // Save updated collection config
+ if err := config.SaveCollectionConfig(collectionPath, collectionCfg); err != nil {
+ return fmt.Errorf("failed to save collection config: %w", err)
+ }
+
+ fmt.Printf("Runnable '%s' created and added to collection at %s\n", runnableName, runnablePath)
return nil
}
diff --git a/pkg/core/scaffold_test.go b/pkg/core/scaffold_test.go
index 4683ad9..0c64485 100644
--- a/pkg/core/scaffold_test.go
+++ b/pkg/core/scaffold_test.go
@@ -4,6 +4,8 @@ import (
"os"
"path/filepath"
"testing"
+
+ "github.com/brsyuksel/shellican/pkg/config"
)
func TestCreateCollection(t *testing.T) {
@@ -56,6 +58,27 @@ func TestCreateRunnable(t *testing.T) {
t.Errorf("runnable.yml not created")
}
+ // Verify runnable was added to collection.yml
+ colPath := filepath.Join(tempDir, ".shellican", colName)
+ cfg, err := config.LoadCollectionConfig(colPath)
+ if err != nil {
+ t.Fatalf("Failed to load collection config: %v", err)
+ }
+ if cfg == nil {
+ t.Fatal("Collection config is nil")
+ }
+
+ found := false
+ for _, r := range cfg.Runnables {
+ if r == runName {
+ found = true
+ break
+ }
+ }
+ if !found {
+ t.Errorf("Runnable '%s' not found in collection.yml runnables list", runName)
+ }
+
// Missing collection test
err = CreateRunnable("missing", "run")
if err == nil {