Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PKG_NAME := github.com/fermayo/dpm
PKG_NAME := github.com/JPZ13/dpm
GO := docker run -it --rm -v ${PWD}:/go/src/$(PKG_NAME) -w /go/src/$(PKG_NAME) -e GOOS -e GOARCH golang:1.7 go
GLIDE := docker run -it --rm -v ${PWD}:/run/context -w /run/context dockerepo/glide

Expand Down
29 changes: 16 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
# dpm
# Docker Package Manager

Wouldn't it be great if the only tool you need to start developing on any project is just _Docker_?
Tired of spending too much time configuring your machine? Me too.

[![asciicast](https://asciinema.org/a/5h4iu5ypry79rw7hgxq4hteyc.png)](https://asciinema.org/a/5h4iu5ypry79rw7hgxq4hteyc)
DPM solves:
- Issues with different versions of node, python, golang etc
- System dependency conflicts
- Endlessly chaining things to your $PATH
- Random software updates that break everything

## Installation

Install Docker. Then:

curl -L "https://github.com/fermayo/dpm/releases/download/0.2.2/dpm-$(uname -s)-$(uname -m)" -o /usr/local/bin/dpm; chmod +x /usr/local/bin/dpm

And add `~/.dpm` to your `$PATH`. For example, for `bash`:

echo "export PATH=\$PATH:$HOME/.dpm" >> ~/.bashrc

If you want project commands installed with `dpm` to override system commands (be careful!), use the following instead:

echo "export PATH=$HOME/.dpm:\$PATH" >> ~/.bashrc
curl -L "https://github.com/JPZ13/dpm/releases/download/0.2.2/dpm-$(uname -s)-$(uname -m)" -o /usr/local/bin/dpm; chmod +x /usr/local/bin/dpm

Make sure /usr/local/bin is ahead of /usr/bin in your $PATH. Most likely, this
is already the case.

## Usage

Expand All @@ -29,7 +27,7 @@ Add a file called `dpm.yml` to your project root defining the commands you want
commands:
go:
image: golang:1.7.5
context: /go/src/github.com/fermayo/dpm
context: /go/src/github.com/JPZ13/dpm

glide:
image: dockerepo/glide
Expand Down Expand Up @@ -69,3 +67,8 @@ Then, just execute them as if they were installed in your OS:
You can also list which commands are currently available by running:

dpm list

### Deactivate
To go back to your normal system configuration,

dpm deactivate
21 changes: 21 additions & 0 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Golang CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-go/ for more details
version: 2
jobs:
build:
docker:
# specify the version
- image: circleci/golang:1.9

#### TEMPLATE_NOTE: go expects specific checkout path representing url
#### expecting it in the form of
#### /go/src/github.com/circleci/go-tool
#### /go/src/bitbucket.org/circleci/go-tool
working_directory: /go/src/github.com/JPZ13/dpm
steps:
- checkout

# specify any bash command here prefixed with `run: `
- run: go get -v -t -d ./...
- run: go test -v ./...
23 changes: 11 additions & 12 deletions cmd/activate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package cmd

import (
"fmt"
"github.com/fermayo/dpm/project"
"github.com/fermayo/dpm/switcher"
"github.com/spf13/cobra"
"log"

"github.com/JPZ13/dpm/internal/alias"
"github.com/JPZ13/dpm/internal/project"
"github.com/JPZ13/dpm/internal/shell"
"github.com/spf13/cobra"
)

var forceActivate bool
Expand All @@ -21,23 +23,20 @@ var activateCmd = &cobra.Command{
Short: "Activates the project in the current shell",
Run: func(cmd *cobra.Command, args []string) {
if !project.IsProjectInstalled() {
log.Fatal("error: commands are not installed - please run `dpm install` first\n")
installYAMLPackages()
}

switchProjectName, err := switcher.GetSwitchProjectName()
err := project.ActivateProject()
if err != nil {
log.Fatalf("error: %v", err)
}

if !forceActivate && switchProjectName != "" {
if switchProjectName == project.ProjectName {
log.Fatal("error: current project already active\n")
} else {
log.Fatalf("error: project '%s' already active", switchProjectName)
}
err = alias.SetAliases()
if err != nil {
log.Fatalf("error: %v", err)
}

err = switcher.SetSwitch(project.ProjectCmdPath)
err = shell.StartShell(shell.Activate)
if err != nil {
log.Fatalf("error: %v", err)
}
Expand Down
29 changes: 11 additions & 18 deletions cmd/deactivate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package cmd

import (
"fmt"
"github.com/fermayo/dpm/project"
"github.com/fermayo/dpm/switcher"
"github.com/spf13/cobra"
"log"

"github.com/JPZ13/dpm/internal/alias"
"github.com/JPZ13/dpm/internal/project"
"github.com/JPZ13/dpm/internal/shell"
"github.com/spf13/cobra"
)

var forceDeactivate bool
Expand All @@ -20,30 +22,21 @@ var deactivateCmd = &cobra.Command{
Use: "deactivate",
Short: "Deactivates the project in the current shell",
Run: func(cmd *cobra.Command, args []string) {
switchProjectName, err := switcher.GetSwitchProjectName()
err := project.DeactivateProject()
if err != nil {
log.Fatalf("error: %v", err)
}

if !forceDeactivate {
if switchProjectName == "" {
log.Fatal("error: no active project\n")
}

if switchProjectName != project.ProjectName {
log.Fatalf("error: project '%s' already active", switchProjectName)
}
err = alias.UnsetAliases()
if err != nil {
log.Fatalf("error: %v", err)
}

err = switcher.UnsetSwitch()
err = shell.StartShell(shell.Deactivate)
if err != nil {
log.Fatalf("error: %v", err)
}

if switchProjectName != "" {
fmt.Printf("Project '%s' deactivated\n", switchProjectName)
} else {
fmt.Print("No active project to deactivate\n")
}
fmt.Printf("Project '%s' deactivated\n", project.ProjectName)
},
}
106 changes: 76 additions & 30 deletions cmd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ package cmd

import (
"fmt"
"github.com/fermayo/dpm/parser"
"github.com/fermayo/dpm/project"
"github.com/fermayo/dpm/switcher"
"github.com/spf13/cobra"
"io/ioutil"
"log"
"os"
"path"
"strings"

"github.com/JPZ13/dpm/internal/parser"
"github.com/JPZ13/dpm/internal/project"
"github.com/spf13/cobra"
)

func init() {
Expand All @@ -25,52 +25,98 @@ var installCmd = &cobra.Command{
log.Fatal("error: no `dpm.yml` file found\n")
}

commands := parser.GetCommands(project.ProjectFilePath)
os.RemoveAll(project.ProjectCmdPath)
err := os.MkdirAll(project.ProjectCmdPath, 0755)
if err != nil {
log.Fatalf("error: %v", err)
}

data, err := ioutil.ReadFile(project.ProjectFilePath)
if err != nil {
log.Fatalf("error: %v", err)
if len(args) > 0 {
err = installListedPackages(args)
if err != nil {
log.Fatalf("error: %v", err)
}
}
err = ioutil.WriteFile(path.Join(project.ProjectCmdPath, "dpm.yml"), data, 0644)

err = installYAMLPackages()
if err != nil {
log.Fatalf("error: %v", err)
}
},
}

fmt.Printf("Installing %d commands...\n", len(commands))
commandNames := []string{}
// installYAMLPackages writes bash scripts for
// each of the commands listed in the dpm.yml file
func installYAMLPackages() error {
commands := parser.GetCommands(project.ProjectFilePath)
data, err := ioutil.ReadFile(project.ProjectFilePath)
if err != nil {
return err
}

for name, command := range commands {
commandNames = append(commandNames, name)
targetPath := path.Join(project.ProjectCmdPath, name)
contents := fmt.Sprintf("#!/bin/sh\nexec %s", commandToDockerCLI(command))
err = ioutil.WriteFile(targetPath, []byte(contents), 0755)
if err != nil {
log.Fatalf("error: %v", err)
}
}
// TODO: figure out what this is used for
err = ioutil.WriteFile(path.Join(project.ProjectCmdPath, "dpm.yml"), data, 0644)
if err != nil {
return err
}

fmt.Printf("Installed: %s\n", strings.Join(commandNames, ", "))
fmt.Printf("Installing %d commands...\n", len(commands))

switchProjectName, err := switcher.GetSwitchProjectName()
commandNames := []string{}

for name, command := range commands {
commandNames = append(commandNames, name)
cliCommands := commandToDockerCLIs(command)
err = writeDockerBashCommands(cliCommands)
if err != nil {
log.Fatalf("error: %v", err)
return err
}
if switchProjectName == "" {
fmt.Print("Now you can run `dpm activate` to start using your new commands\n")
}
},
}

fmt.Printf("Installed: %s\n", strings.Join(commandNames, ", "))

fmt.Print("Now you can run `dpm activate` to start using your new commands\n")

return nil
}

func commandToDockerCLI(command parser.Command) string {
// installListedPackages adds packages listed after
// install on the CLI to the dpm.yml file
func installListedPackages(packages []string) error {
commands := parser.GetCommandsFromCLI(packages)

return parser.AddCommands(project.ProjectFilePath, commands)
}

// commandToDockerCLIs takes a command and translates it into
// a docker cli command. It returns a map of the entrypoint to the
// docker command
func commandToDockerCLIs(command parser.Command) map[string]string {
volumes := ""
for _, volume := range command.Volumes {
volumes = fmt.Sprintf("%s -v %s", volumes, volume)
}
return fmt.Sprintf("docker run -it --rm -v $(pwd):%s %s -w %s --entrypoint %s %s \"$@\"",
command.Context, volumes, command.Context, command.Entrypoint, command.Image)

cliCommands := make(map[string]string)
for _, entrypoint := range command.Entrypoints {
cliCommands[entrypoint] = fmt.Sprintf("docker run -it --rm -v $(pwd):%s %s -w %s --entrypoint %s %s \"$@\"",
command.Context, volumes, command.Context, entrypoint, command.Image)
}

return cliCommands
}

// writeDockerBashCommands :
func writeDockerBashCommands(cliCommands map[string]string) error {
for entrypoint, bashCommand := range cliCommands {
targetPath := path.Join(project.ProjectCmdPath, entrypoint)
contents := fmt.Sprintf("#!/bin/sh\nexec %s", bashCommand)

err := ioutil.WriteFile(targetPath, []byte(contents), 0755)
if err != nil {
return err
}
}

return nil
}
23 changes: 9 additions & 14 deletions cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ package cmd

import (
"fmt"
"github.com/fermayo/dpm/parser"
"github.com/fermayo/dpm/switcher"
"github.com/spf13/cobra"
"log"
"os"
"path"
"text/tabwriter"

"github.com/JPZ13/dpm/internal/parser"
"github.com/JPZ13/dpm/internal/project"
"github.com/spf13/cobra"
)

func init() {
Expand All @@ -19,25 +19,20 @@ var listCmd = &cobra.Command{
Use: "list",
Short: "List available commands in the current project",
Run: func(cmd *cobra.Command, args []string) {
switchProjectName, err := switcher.GetSwitchProjectName()
isActive, err := project.IsProjectActive()
if err != nil {
log.Fatalf("error: %v", err)
log.Fatalf("error: %s", err)
}

if switchProjectName == "" {
if !isActive {
log.Fatal("error: no active project - please run `dpm activate` first from your project root")
}

switchProjectPath, err := switcher.GetSwitchProjectPath()
if err != nil {
log.Fatalf("error: %v", err)
}

commands := parser.GetCommands(path.Join(switchProjectPath, "dpm.yml"))
commands := parser.GetCommands(project.ProjectFilePath)
w := tabwriter.NewWriter(os.Stdout, 0, 8, 0, '\t', 0)
fmt.Fprintln(w, "COMMAND\tIMAGE\tENTRYPOINT")
for name, command := range commands {
fmt.Fprintf(w, "%s\t%s\t%s\n", name, command.Image, command.Entrypoint)
fmt.Fprintf(w, "%s\t%s\t%s\n", name, command.Image, command.Entrypoints)
}
w.Flush()
},
Expand Down
Loading