<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"time"

	"golang.org/x/oauth2"

	"github.com/google/go-github/github"
	"github.com/kelseyhightower/envconfig"
)

type commits []struct {
	Commit struct {
		Author struct {
			Name  string    `json:"name"`
			Email string    `json:"email"`
			Date  time.Time `json:"date"`
		} `json:"author"`
		Committer struct {
			Name  string    `json:"name"`
			Email string    `json:"email"`
			Date  time.Time `json:"date"`
		} `json:"committer"`
	} `json:"commit"`
}

type contribs []struct {
	Login         string `json:"login"`
	Contributions int    `json:"contributions"`
}

type stat struct {
	email   []string
	commits int
}

type Config struct {
	Token string
}

func main() {
	config := &Config{}
	err := envconfig.Process("scrape", config)
	if err != nil {
		log.Fatal(err)
	}
	if config.Token == "" {
		log.Fatal("needs an access token")
	}
	fmt.Println(config.Token)
	time.Sleep(time.Second * 5)

	ts := oauth2.StaticTokenSource(
		&oauth2.Token{AccessToken: config.Token},
	)
	tc := oauth2.NewClient(oauth2.NoContext, ts)

	client := github.NewClient(tc)

	//top100()
	getAllCommits(client)
	//rateLimit(client)
	//m := make(map[string]int)
	//for _, i := range listContributors() {
	//	//fmt.Println(i.Commit.Author.Name)
	//	a := i.Login
	//	_, ok := m[a]
	//	if !ok {
	//		m[a] = i.Contributions
	//		continue
	//	}
	//	m[a] += 1
	//}
	//fmt.Println(m)
	//top100()
}

func checkAndAddEmail(e string, emails []string) bool {
	for _, s := range emails {
		if e == s {
			return true
		}
	}
	return false
}

func getAllCommits(client *github.Client) {
	opt := &github.CommitsListOptions{
		ListOptions: github.ListOptions{
			PerPage: 100,
		},
	}

	//var allCommits []*github.RepositoryCommit
	m := make(map[string]*stat)
	for {
		commits, resp, err := client.Repositories.ListCommits("dmmcquay", "sqrl", opt)
		//commits, resp, err := client.Repositories.ListCommits("kubernetes", "kubernetes", opt)
		//commits, resp, err := client.Repositories.ListCommits("coreos", "dbtester", opt)
		//commits, resp, err := client.Repositories.ListCommits("coreos", "dex", opt)
		//commits, resp, err := client.Repositories.ListCommits("coreos", "torus", opt)
		//commits, resp, err := client.Repositories.ListCommits("coreos", "rkt", opt)
		if _, ok := err.(*github.RateLimitError); ok {
			log.Println("hit rate limit")
			return
		}
		if err != nil {
			log.Fatal(err)
		}
		for _, c := range commits {
			a := "username missing"
			e := "fake@fake.com"
			if c.Author != nil {
				a = *c.Author.Login
			}
			if c.Commit.Author != nil {
				e = *c.Commit.Author.Email
			}
			_, ok := m[a]
			if !ok {
				m[a] = &stat{email: []string{e}, commits: 1}
				continue
			}
			tmp := m[a]
			tmp.commits += 1
			if !checkAndAddEmail(e, tmp.email) {
				tmp.email = append(tmp.email, e)
			}
		}
		//allCommits = append(allCommits, commits...)
		if resp.NextPage == 0 {
			break
		}
		opt.ListOptions.Page = resp.NextPage
	}
	total := 0
	atotal := 0
	for k, v := range m {
		total += v.commits
		atotal += 1
		fmt.Printf("Author: %s Commits: %v\n", k, v)
	}
	fmt.Printf("TOTAL: %d\n", total)
	fmt.Printf("ATOTAL: %d\n", atotal)
}

func listContributors() contribs {
	r, err := http.Get("https://api.github.com/repos/kubernetes/kubernetes/contributors")
	if err != nil {
		log.Fatal(err)
	}

	if r.StatusCode != 200 {
		log.Fatal("Unexpected status code", r.StatusCode)
	}
	defer r.Body.Close()

	target := contribs{}

	err = json.NewDecoder(r.Body).Decode(&target)
	if err != nil {
		log.Fatal("error parsing response: %v", err)
	}
	return target
}

func listCommits() commits {
	r, err := http.Get("https://api.github.com/repos/kubernetes/kubernetes/commits")
	if err != nil {
		log.Fatal(err)
	}

	if r.StatusCode != 200 {
		log.Fatal("Unexpected status code", r.StatusCode)
	}
	defer r.Body.Close()

	target := commits{}

	err = json.NewDecoder(r.Body).Decode(&target)
	if err != nil {
		log.Fatal("error parsing response: %v", err)
	}
	return target
}

func rateLimit(client *github.Client) {
	r, _, err := client.RateLimit()
	if err != nil {
		log.Printf("error getting rate: %v", err)
		return
	}
	fmt.Printf("%d/%d\n", r.Remaining, r.Limit)
}

func top100(client *github.Client) {
	//stats, _, err := client.Repositories.ListContributorsStats("dmmcquay", "sqrl")
	stats, _, err := client.Repositories.ListContributorsStats("kubernetes", "kubernetes")
	if _, ok := err.(*github.RateLimitError); ok {
		log.Println("hit rate limit")
	}
	if err != nil {
		log.Fatal(err)
	}
	//if _, ok := err.(*github.AcceptedError); ok {
	//	log.Println("scheduled on GitHub side")
	//}
	fmt.Println(len(stats))
	for _, i := range stats {
		fmt.Printf(
			"Author: %v commits: %v\n",
			*i.Author.Login,
			*i.Total,
		)
	}
}
<commit_msg>added flags to get org, repo, and type of check<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"time"

	"golang.org/x/oauth2"

	"github.com/google/go-github/github"
	"github.com/kelseyhightower/envconfig"
)

type commits []struct {
	Commit struct {
		Author struct {
			Name  string    `json:"name"`
			Email string    `json:"email"`
			Date  time.Time `json:"date"`
		} `json:"author"`
		Committer struct {
			Name  string    `json:"name"`
			Email string    `json:"email"`
			Date  time.Time `json:"date"`
		} `json:"committer"`
	} `json:"commit"`
}

type contribs []struct {
	Login         string `json:"login"`
	Contributions int    `json:"contributions"`
}

type stat struct {
	email   []string
	commits int
}

type Config struct {
	Token string
}

var org = flag.String("o", "", "github orginization")
var repo = flag.String("r", "", "github repository")
var check = flag.String("c", "top100", "Type of check to run (top100 (default), allcommits, apirates")

func main() {
	flag.Parse()

	if *org == "" {
		log.Fatal("need to specify an org")
	}
	if *repo == "" {
		log.Fatal("need to specify an repo")
	}

	config := &Config{}
	err := envconfig.Process("scrape", config)
	if err != nil {
		log.Fatal(err)
	}
	if config.Token == "" {
		log.Fatal("needs an access token")
	}

	ts := oauth2.StaticTokenSource(
		&oauth2.Token{AccessToken: config.Token},
	)
	tc := oauth2.NewClient(oauth2.NoContext, ts)

	client := github.NewClient(tc)

	switch *check {
	case "top100":
		top100(client)
	case "allcommits":
		getAllCommits(client)
	case "apirates":
		rateLimit(client)
	default:
		log.Fatal("not a valid check")
	}
}

func rateLimit(client *github.Client) {
	r, _, err := client.RateLimit()
	if err != nil {
		log.Printf("error getting rate: %v", err)
		return
	}
	fmt.Printf("%d/%d\n", r.Remaining, r.Limit)
}

func checkAndAddEmail(e string, emails []string) bool {
	for _, s := range emails {
		if e == s {
			return true
		}
	}
	return false
}

func getAllCommits(client *github.Client) {
	opt := &github.CommitsListOptions{
		ListOptions: github.ListOptions{
			PerPage: 100,
		},
	}

	m := make(map[string]*stat)
	for {
		commits, resp, err := client.Repositories.ListCommits(*org, *repo, opt)
		if _, ok := err.(*github.RateLimitError); ok {
			log.Println("hit rate limit")
			return
		}
		if err != nil {
			log.Fatal(err)
		}
		for _, c := range commits {
			a := "username missing"
			e := "fake@fake.com"
			if c.Author != nil {
				a = *c.Author.Login
			}
			if c.Commit.Author != nil {
				e = *c.Commit.Author.Email
			}
			_, ok := m[a]
			if !ok {
				m[a] = &stat{email: []string{e}, commits: 1}
				continue
			}
			tmp := m[a]
			tmp.commits += 1
			if !checkAndAddEmail(e, tmp.email) {
				tmp.email = append(tmp.email, e)
			}
		}
		if resp.NextPage == 0 {
			break
		}
		opt.ListOptions.Page = resp.NextPage
	}
	total := 0
	atotal := 0
	for k, v := range m {
		total += v.commits
		atotal += 1
		fmt.Printf("Author: %s Commits: %v\n", k, v)
	}
	fmt.Printf("TOTAL: %d\n", total)
	fmt.Printf("ATOTAL: %d\n", atotal)
}

func top100(client *github.Client) {
	stats, _, err := client.Repositories.ListContributorsStats(*org, *repo)
	if _, ok := err.(*github.RateLimitError); ok {
		log.Println("hit rate limit")
	}
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(len(stats))
	for _, i := range stats {
		fmt.Printf(
			"Author: %v commits: %v\n",
			*i.Author.Login,
			*i.Total,
		)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"

	"github.com/PuerkitoBio/goquery"
)

const (
	WIKI_PREFIX       = "http://en.wikipedia.org"
	LINKS_AT_ONCE     = 25
	NUM_OF_ITERATIONS = 1

	RESULT_FILE = "links.txt"
)

func GrabLinks(wiki string, clinks chan []string) {
	doc, err := goquery.NewDocument(wiki)
	if err != nil {
		log.Fatal(err)
	}

	links := make([]string, 0, LINKS_AT_ONCE)
	oles := doc.Find("ol")
	oles.Find("li").Each(func(i int, s *goquery.Selection) {
		link, _ := s.Find("a").Eq(1).Attr("href")
		links = append(links, link)
	})
	clinks <- links
}

func ScrapeAllWikis() {
	clinks := make(chan []string, NUM_OF_ITERATIONS)
	for idx := 0; idx < NUM_OF_ITERATIONS; idx++ {
		offset := LINKS_AT_ONCE * idx
		//"https://en.wikipedia.org/w/index.php?title=Special:LongPages&limit=5000&offset=0"
		link := fmt.Sprintf("%s/w/index.php?title=Special:LongPages&limit=%d&offset=%d",
			WIKI_PREFIX, LINKS_AT_ONCE, offset)
		go GrabLinks(link, clinks)
	}

	f, err := os.OpenFile(RESULT_FILE, os.O_CREATE|os.O_WRONLY, 0600)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	for idx := 0; idx < NUM_OF_ITERATIONS; idx++ {
		select {
		case links := <-clinks:
			WriteLinksToFile(links, f)
		}
	}
	fmt.Printf("fin\n")
}

func WriteLinksToFile(links []string, file *os.File) {
	for _, link := range links {
		//		fmt.Printf("%s\n", link)
		file.WriteString(link + "\n")
	}
}

func main() {
	ScrapeAllWikis()
}
<commit_msg>local wiki<commit_after>package main

import (
	"fmt"
	"log"
	"os"

	"github.com/PuerkitoBio/goquery"
)

const (
	//	WIKI_PREFIX       = "http://en.wikipedia.org"
	WIKI_PREFIX       = "http://10.102.44.202"
	LINKS_AT_ONCE     = 50
	NUM_OF_ITERATIONS = 100

	RESULT_FILE = "links.txt"
)

func GrabLinks(wiki string, clinks chan []string) {
	doc, err := goquery.NewDocument(wiki)
	if err != nil {
		log.Fatal(err)
	}

	links := make([]string, 0, LINKS_AT_ONCE)
	oles := doc.Find("ol")

	oles.Find("li").Each(func(i int, s *goquery.Selection) {
		link, err := s.Find("a").Eq(1).Attr("href")
		//		log.Println(err)
		//		fmt.Printf("%s\n", link)
		links = append(links, link)
	})
	clinks <- links
}

func ScrapeAllWikis() {
	clinks := make(chan []string, NUM_OF_ITERATIONS)
	for idx := 0; idx < NUM_OF_ITERATIONS; idx++ {
		offset := LINKS_AT_ONCE * idx
		//"https://en.wikipedia.org/w/index.php?title=Special:LongPages&limit=5000&offset=0"
		link := fmt.Sprintf("%s/index.php?title=Special:LongPages&limit=%d&offset=%d",
			WIKI_PREFIX, LINKS_AT_ONCE, offset)
		//		fmt.Printf("Grabbing: %s\n", link)
		go GrabLinks(link, clinks)
	}

	f, err := os.OpenFile(RESULT_FILE, os.O_CREATE|os.O_WRONLY, 0600)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	for idx := 0; idx < NUM_OF_ITERATIONS; idx++ {
		select {
		case links := <-clinks:
			fmt.Printf("-")
			WriteLinksToFile(links, f)
		}
	}
	fmt.Printf("\n")
	fmt.Printf("fin\n")
}

func WriteLinksToFile(links []string, file *os.File) {
	for _, link := range links {
		//		fmt.Printf("%s\n", link)
		file.WriteString(WIKI_PREFIX + link + "\n")
	}
}

func main() {
	ScrapeAllWikis()
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"flag"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"

	stdprometheus "github.com/prometheus/client_golang/prometheus"
	"gopkg.in/mgo.v2"

	"github.com/go-kit/kit/log"
	kitprometheus "github.com/go-kit/kit/metrics/prometheus"

	"github.com/marcusolsson/goddd/booking"
	"github.com/marcusolsson/goddd/cargo"
	"github.com/marcusolsson/goddd/handling"
	"github.com/marcusolsson/goddd/inmem"
	"github.com/marcusolsson/goddd/inspection"
	"github.com/marcusolsson/goddd/location"
	"github.com/marcusolsson/goddd/mongo"
	"github.com/marcusolsson/goddd/routing"
	"github.com/marcusolsson/goddd/tracking"
	"github.com/marcusolsson/goddd/voyage"
)

const (
	defaultPort              = "8080"
	defaultRoutingServiceURL = "http://localhost:7878"
	defaultMongoDBURL        = "127.0.0.1"
	defaultDBName            = "dddsample"
)

func main() {
	var (
		addr   = envString("PORT", defaultPort)
		rsurl  = envString("ROUTINGSERVICE_URL", defaultRoutingServiceURL)
		dburl  = envString("MONGODB_URL", defaultMongoDBURL)
		dbname = envString("DB_NAME", defaultDBName)

		httpAddr          = flag.String("http.addr", ":"+addr, "HTTP listen address")
		routingServiceURL = flag.String("service.routing", rsurl, "routing service URL")
		mongoDBURL        = flag.String("db.url", dburl, "MongoDB URL")
		databaseName      = flag.String("db.name", dbname, "MongoDB database name")
		inmemory          = flag.Bool("inmem", false, "use in-memory repositories")

		ctx = context.Background()
	)

	flag.Parse()

	var logger log.Logger
	logger = log.NewLogfmtLogger(os.Stderr)
	logger = &serializedLogger{Logger: logger}
	logger = log.NewContext(logger).With("ts", log.DefaultTimestampUTC)

	// Setup repositories
	var (
		cargos         cargo.Repository
		locations      location.Repository
		voyages        voyage.Repository
		handlingEvents cargo.HandlingEventRepository
	)

	if *inmemory {
		cargos = inmem.NewCargoRepository()
		locations = inmem.NewLocationRepository()
		voyages = inmem.NewVoyageRepository()
		handlingEvents = inmem.NewHandlingEventRepository()
	} else {
		session, err := mgo.Dial(*mongoDBURL)
		if err != nil {
			panic(err)
		}
		defer session.Close()

		session.SetMode(mgo.Monotonic, true)

		cargos, _ = mongo.NewCargoRepository(*databaseName, session)
		locations, _ = mongo.NewLocationRepository(*databaseName, session)
		voyages, _ = mongo.NewVoyageRepository(*databaseName, session)
		handlingEvents = mongo.NewHandlingEventRepository(*databaseName, session)
	}

	// Configure some questionable dependencies.
	var (
		handlingEventFactory = cargo.HandlingEventFactory{
			CargoRepository:    cargos,
			VoyageRepository:   voyages,
			LocationRepository: locations,
		}
		handlingEventHandler = handling.NewEventHandler(
			inspection.NewService(cargos, handlingEvents, nil),
		)
	)

	// Facilitate testing by adding some cargos.
	storeTestData(cargos)

	fieldKeys := []string{"method"}

	var rs routing.Service
	rs = routing.NewProxyingMiddleware(ctx, *routingServiceURL)(rs)

	var bs booking.Service
	bs = booking.NewService(cargos, locations, handlingEvents, rs)
	bs = booking.NewLoggingService(log.NewContext(logger).With("component", "booking"), bs)
	bs = booking.NewInstrumentingService(
		kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
			Namespace: "api",
			Subsystem: "booking_service",
			Name:      "request_count",
			Help:      "Number of requests received.",
		}, fieldKeys),
		kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
			Namespace: "api",
			Subsystem: "booking_service",
			Name:      "request_latency_microseconds",
			Help:      "Total duration of requests in microseconds.",
		}, fieldKeys),
		bs,
	)

	var ts tracking.Service
	ts = tracking.NewService(cargos, handlingEvents)
	ts = tracking.NewLoggingService(log.NewContext(logger).With("component", "tracking"), ts)
	ts = tracking.NewInstrumentingService(
		kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
			Namespace: "api",
			Subsystem: "tracking_service",
			Name:      "request_count",
			Help:      "Number of requests received.",
		}, fieldKeys),
		kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
			Namespace: "api",
			Subsystem: "tracking_service",
			Name:      "request_latency_microseconds",
			Help:      "Total duration of requests in microseconds.",
		}, fieldKeys),
		ts,
	)

	var hs handling.Service
	hs = handling.NewService(handlingEvents, handlingEventFactory, handlingEventHandler)
	hs = handling.NewLoggingService(log.NewContext(logger).With("component", "handling"), hs)
	hs = handling.NewInstrumentingService(
		kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
			Namespace: "api",
			Subsystem: "handling_service",
			Name:      "request_count",
			Help:      "Number of requests received.",
		}, fieldKeys),
		kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
			Namespace: "api",
			Subsystem: "handling_service",
			Name:      "request_latency_microseconds",
			Help:      "Total duration of requests in microseconds.",
		}, fieldKeys),
		hs,
	)

	httpLogger := log.NewContext(logger).With("component", "http")

	mux := http.NewServeMux()

	mux.Handle("/booking/v1/", booking.MakeHandler(ctx, bs, httpLogger))
	mux.Handle("/tracking/v1/", tracking.MakeHandler(ctx, ts, httpLogger))
	mux.Handle("/handling/v1/", handling.MakeHandler(ctx, hs, httpLogger))

	http.Handle("/", accessControl(mux))
	http.Handle("/metrics", stdprometheus.Handler())

	errs := make(chan error, 2)
	go func() {
		logger.Log("transport", "http", "address", *httpAddr, "msg", "listening")
		errs <- http.ListenAndServe(*httpAddr, nil)
	}()
	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, syscall.SIGINT)
		errs <- fmt.Errorf("%s", <-c)
	}()

	logger.Log("terminated", <-errs)
}

func accessControl(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", "*")
		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
		w.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type")

		if r.Method == "OPTIONS" {
			return
		}

		h.ServeHTTP(w, r)
	})
}

func envString(env, fallback string) string {
	e := os.Getenv(env)
	if e == "" {
		return fallback
	}
	return e
}

func storeTestData(r cargo.Repository) {
	test1 := cargo.New("FTL456", cargo.RouteSpecification{
		Origin:          location.AUMEL,
		Destination:     location.SESTO,
		ArrivalDeadline: time.Now().AddDate(0, 0, 7),
	})
	if err := r.Store(test1); err != nil {
		panic(err)
	}

	test2 := cargo.New("ABC123", cargo.RouteSpecification{
		Origin:          location.SESTO,
		Destination:     location.CNHKG,
		ArrivalDeadline: time.Now().AddDate(0, 0, 14),
	})
	if err := r.Store(test2); err != nil {
		panic(err)
	}
}

type serializedLogger struct {
	mtx sync.Mutex
	log.Logger
}

func (l *serializedLogger) Log(keyvals ...interface{}) error {
	l.mtx.Lock()
	defer l.mtx.Unlock()
	return l.Logger.Log(keyvals...)
}
<commit_msg>Allow mongo pool size to be configurable<commit_after>package main

import (
	"context"
	"flag"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"

	stdprometheus "github.com/prometheus/client_golang/prometheus"
	"gopkg.in/mgo.v2"

	"github.com/go-kit/kit/log"
	kitprometheus "github.com/go-kit/kit/metrics/prometheus"

	"github.com/marcusolsson/goddd/booking"
	"github.com/marcusolsson/goddd/cargo"
	"github.com/marcusolsson/goddd/handling"
	"github.com/marcusolsson/goddd/inmem"
	"github.com/marcusolsson/goddd/inspection"
	"github.com/marcusolsson/goddd/location"
	"github.com/marcusolsson/goddd/mongo"
	"github.com/marcusolsson/goddd/routing"
	"github.com/marcusolsson/goddd/tracking"
	"github.com/marcusolsson/goddd/voyage"
)

const (
	defaultPort              = "8080"
	defaultRoutingServiceURL = "http://localhost:7878"
	defaultMongoDBURL        = "127.0.0.1"
	defaultDBName            = "dddsample"
)

func main() {
	var (
		addr             = envString("PORT", defaultPort)
		rsurl            = envString("ROUTINGSERVICE_URL", defaultRoutingServiceURL)
		dburl            = envString("MONGODB_URL", defaultMongoDBURL)
		dbname           = envString("DB_NAME", defaultDBName)
		mongoMaxPoolSize = envString("MONGO_MAXPOOLSIZE", "60")

		httpAddr          = flag.String("http.addr", ":"+addr, "HTTP listen address")
		routingServiceURL = flag.String("service.routing", rsurl, "routing service URL")
		mongoDBURL        = flag.String("db.url", dburl, "MongoDB URL")
		databaseName      = flag.String("db.name", dbname, "MongoDB database name")
		inmemory          = flag.Bool("inmem", false, "use in-memory repositories")

		ctx = context.Background()
	)

	flag.Parse()

	var logger log.Logger
	logger = log.NewLogfmtLogger(os.Stderr)
	logger = &serializedLogger{Logger: logger}
	logger = log.NewContext(logger).With("ts", log.DefaultTimestampUTC)

	// Setup repositories
	var (
		cargos         cargo.Repository
		locations      location.Repository
		voyages        voyage.Repository
		handlingEvents cargo.HandlingEventRepository
	)

	if *inmemory {
		cargos = inmem.NewCargoRepository()
		locations = inmem.NewLocationRepository()
		voyages = inmem.NewVoyageRepository()
		handlingEvents = inmem.NewHandlingEventRepository()
	} else {
		session, err := mgo.Dial(*mongoDBURL + "?maxPoolSize=" + mongoMaxPoolSize)
		if err != nil {
			panic(err)
		}
		defer session.Close()

		session.SetMode(mgo.Monotonic, true)

		cargos, err = mongo.NewCargoRepository(*databaseName, session)
		if err != nil {
			panic(err)
		}
		locations, err = mongo.NewLocationRepository(*databaseName, session)
		if err != nil {
			panic(err)
		}
		voyages, err = mongo.NewVoyageRepository(*databaseName, session)
		if err != nil {
			panic(err)
		}
		handlingEvents = mongo.NewHandlingEventRepository(*databaseName, session)
	}

	// Configure some questionable dependencies.
	var (
		handlingEventFactory = cargo.HandlingEventFactory{
			CargoRepository:    cargos,
			VoyageRepository:   voyages,
			LocationRepository: locations,
		}
		handlingEventHandler = handling.NewEventHandler(
			inspection.NewService(cargos, handlingEvents, nil),
		)
	)

	// Facilitate testing by adding some cargos.
	storeTestData(cargos)

	fieldKeys := []string{"method"}

	var rs routing.Service
	rs = routing.NewProxyingMiddleware(ctx, *routingServiceURL)(rs)

	var bs booking.Service
	bs = booking.NewService(cargos, locations, handlingEvents, rs)
	bs = booking.NewLoggingService(log.NewContext(logger).With("component", "booking"), bs)
	bs = booking.NewInstrumentingService(
		kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
			Namespace: "api",
			Subsystem: "booking_service",
			Name:      "request_count",
			Help:      "Number of requests received.",
		}, fieldKeys),
		kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
			Namespace: "api",
			Subsystem: "booking_service",
			Name:      "request_latency_microseconds",
			Help:      "Total duration of requests in microseconds.",
		}, fieldKeys),
		bs,
	)

	var ts tracking.Service
	ts = tracking.NewService(cargos, handlingEvents)
	ts = tracking.NewLoggingService(log.NewContext(logger).With("component", "tracking"), ts)
	ts = tracking.NewInstrumentingService(
		kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
			Namespace: "api",
			Subsystem: "tracking_service",
			Name:      "request_count",
			Help:      "Number of requests received.",
		}, fieldKeys),
		kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
			Namespace: "api",
			Subsystem: "tracking_service",
			Name:      "request_latency_microseconds",
			Help:      "Total duration of requests in microseconds.",
		}, fieldKeys),
		ts,
	)

	var hs handling.Service
	hs = handling.NewService(handlingEvents, handlingEventFactory, handlingEventHandler)
	hs = handling.NewLoggingService(log.NewContext(logger).With("component", "handling"), hs)
	hs = handling.NewInstrumentingService(
		kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
			Namespace: "api",
			Subsystem: "handling_service",
			Name:      "request_count",
			Help:      "Number of requests received.",
		}, fieldKeys),
		kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
			Namespace: "api",
			Subsystem: "handling_service",
			Name:      "request_latency_microseconds",
			Help:      "Total duration of requests in microseconds.",
		}, fieldKeys),
		hs,
	)

	httpLogger := log.NewContext(logger).With("component", "http")

	mux := http.NewServeMux()

	mux.Handle("/booking/v1/", booking.MakeHandler(ctx, bs, httpLogger))
	mux.Handle("/tracking/v1/", tracking.MakeHandler(ctx, ts, httpLogger))
	mux.Handle("/handling/v1/", handling.MakeHandler(ctx, hs, httpLogger))

	http.Handle("/", accessControl(mux))
	http.Handle("/metrics", stdprometheus.Handler())

	errs := make(chan error, 2)
	go func() {
		logger.Log("transport", "http", "address", *httpAddr, "msg", "listening")
		errs <- http.ListenAndServe(*httpAddr, nil)
	}()
	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, syscall.SIGINT)
		errs <- fmt.Errorf("%s", <-c)
	}()

	logger.Log("terminated", <-errs)
}

func accessControl(h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", "*")
		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
		w.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type")

		if r.Method == "OPTIONS" {
			return
		}

		h.ServeHTTP(w, r)
	})
}

func envString(env, fallback string) string {
	e := os.Getenv(env)
	if e == "" {
		return fallback
	}
	return e
}

func storeTestData(r cargo.Repository) {
	test1 := cargo.New("FTL456", cargo.RouteSpecification{
		Origin:          location.AUMEL,
		Destination:     location.SESTO,
		ArrivalDeadline: time.Now().AddDate(0, 0, 7),
	})
	if err := r.Store(test1); err != nil {
		panic(err)
	}

	test2 := cargo.New("ABC123", cargo.RouteSpecification{
		Origin:          location.SESTO,
		Destination:     location.CNHKG,
		ArrivalDeadline: time.Now().AddDate(0, 0, 14),
	})
	if err := r.Store(test2); err != nil {
		panic(err)
	}
}

type serializedLogger struct {
	mtx sync.Mutex
	log.Logger
}

func (l *serializedLogger) Log(keyvals ...interface{}) error {
	l.mtx.Lock()
	defer l.mtx.Unlock()
	return l.Logger.Log(keyvals...)
}
<|endoftext|>


<commit_before>package gopwt

import (
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/mattn/go-isatty"
)

var (
	termw    = 0
	verbose  = flag.Bool("v", false, "This will be passed to `go test`")
	testdata = flag.String("testdata", "testdata", "name of test data directories. e.g. -testdata testdata,migrations")
)

func Main() {
	dir, err := os.Getwd()
	if err != nil {
		return
	}
	if strings.HasPrefix(dir, os.TempDir()) {
		// XXX: dirty hack
		// Return if Main() is called from translated test to avoid recursive call.
		// I guess re-writing Main() func in tranlation is better.
		return
	}
	if err := doMain(); err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		os.Exit(2)
		return
	}
}
func doMain() error {
	if runtime.Version() == "go1.4" {
		return fmt.Errorf("go1.4 is not supported. please bump to go1.4.1 or later")
	}

	flag.Parse()

	if isatty.IsTerminal(os.Stdout.Fd()) {
		termw = getTermCols(os.Stdin.Fd())
	}

	tempGoPath, err := ioutil.TempDir(os.TempDir(), "")
	if err != nil {
		return err
	}
	defer os.RemoveAll(tempGoPath)

	root := flag.Arg(0)

	pkgInfo, err := newPackageInfo(root)
	if err != nil {
		return err
	}

	err = rewrite(tempGoPath, pkgInfo)
	if err != nil {
		return err
	}

	err = runTest(tempGoPath, pkgInfo, os.Stdout, os.Stderr)
	if err != nil {
		return err
	}

	return nil
}

func rewrite(tempGoPath string, pkgInfo *packageInfo) error {
	tempGoSrcDir := filepath.Join(tempGoPath, "src")

	err := filepath.Walk(pkgInfo.dirPath, func(path string, fInfo os.FileInfo, err error) error {
		if fInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
			return nil
		}

		if !fInfo.IsDir() {
			return nil
		}

		files, err := ioutil.ReadDir(path)
		if err != nil {
			return err
		}
		if !containsGoFile(files) {
			// sub-packages maybe have gofiles, even if itself don't has gofiles
			if containsDirectory(files) {
				return nil
			}
			return filepath.SkipDir
		}

		rel, err := filepath.Rel(pkgInfo.dirPath, path)
		if err != nil {
			return err
		}

		for _, tdata := range strings.Split(*testdata, ",") {
			if strings.Split(rel, "/")[0] == tdata {
				return filepath.SkipDir
			}
		}

		if rel != "." {
			if filepath.HasPrefix(rel, ".") {
				return filepath.SkipDir
			}

			if !pkgInfo.recursive {
				return filepath.SkipDir
			}
		}

		importPath := filepath.Join(pkgInfo.importPath, rel)

		err = os.MkdirAll(filepath.Join(tempGoSrcDir, importPath), os.ModePerm)
		if err != nil {
			return err
		}

		err = rewritePackage(path, importPath, tempGoSrcDir)
		if err != nil {
			return err
		}

		return nil
	})

	if err != nil {
		return err
	}

	return nil
}

func runTest(goPath string, pkgInfo *packageInfo, stdout, stderr io.Writer) error {
	// err := os.Setenv("GOPATH", os.Getenv("GOPATH"))
	// if err != nil {
	// 	return err
	// }

	cmd := exec.Command("go", "test")
	if *verbose {
		cmd.Args = append(cmd.Args, "-v")
	}
	cmd.Dir = path.Join(goPath, "src", pkgInfo.importPath)
	// cmd.Args = append(cmd.Args, pkgInfo.ToGoTestArg())
	cmd.Stdout = stdout
	cmd.Stderr = stderr
	return cmd.Run()
}
<commit_msg>fix(gopwt): set temporary gopath to $GOPATH<commit_after>package gopwt

import (
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/mattn/go-isatty"
)

var (
	termw    = 0
	verbose  = flag.Bool("v", false, "This will be passed to `go test`")
	testdata = flag.String("testdata", "testdata", "name of test data directories. e.g. -testdata testdata,migrations")
)

func Main() {
	dir, err := os.Getwd()
	if err != nil {
		return
	}
	if strings.HasPrefix(dir, os.TempDir()) {
		// XXX: dirty hack
		// Return if Main() is called from translated test to avoid recursive call.
		// I guess re-writing Main() func in tranlation is better.
		return
	}
	if err := doMain(); err != nil {
		fmt.Fprintln(os.Stderr, err.Error())
		os.Exit(2)
		return
	}
}
func doMain() error {
	if runtime.Version() == "go1.4" {
		return fmt.Errorf("go1.4 is not supported. please bump to go1.4.1 or later")
	}

	flag.Parse()

	if isatty.IsTerminal(os.Stdout.Fd()) {
		termw = getTermCols(os.Stdin.Fd())
	}

	tempGoPath, err := ioutil.TempDir(os.TempDir(), "")
	if err != nil {
		return err
	}
	defer os.RemoveAll(tempGoPath)

	root := flag.Arg(0)

	pkgInfo, err := newPackageInfo(root)
	if err != nil {
		return err
	}

	err = rewrite(tempGoPath, pkgInfo)
	if err != nil {
		return err
	}

	err = runTest(tempGoPath, pkgInfo, os.Stdout, os.Stderr)
	if err != nil {
		return err
	}

	return nil
}

func rewrite(tempGoPath string, pkgInfo *packageInfo) error {
	tempGoSrcDir := filepath.Join(tempGoPath, "src")

	err := filepath.Walk(pkgInfo.dirPath, func(path string, fInfo os.FileInfo, err error) error {
		if fInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
			return nil
		}

		if !fInfo.IsDir() {
			return nil
		}

		files, err := ioutil.ReadDir(path)
		if err != nil {
			return err
		}
		if !containsGoFile(files) {
			// sub-packages maybe have gofiles, even if itself don't has gofiles
			if containsDirectory(files) {
				return nil
			}
			return filepath.SkipDir
		}

		rel, err := filepath.Rel(pkgInfo.dirPath, path)
		if err != nil {
			return err
		}

		for _, tdata := range strings.Split(*testdata, ",") {
			if strings.Split(rel, "/")[0] == tdata {
				return filepath.SkipDir
			}
		}

		if rel != "." {
			if filepath.HasPrefix(rel, ".") {
				return filepath.SkipDir
			}

			if !pkgInfo.recursive {
				return filepath.SkipDir
			}
		}

		importPath := filepath.Join(pkgInfo.importPath, rel)

		err = os.MkdirAll(filepath.Join(tempGoSrcDir, importPath), os.ModePerm)
		if err != nil {
			return err
		}

		err = rewritePackage(path, importPath, tempGoSrcDir)
		if err != nil {
			return err
		}

		return nil
	})

	if err != nil {
		return err
	}

	return nil
}

func runTest(goPath string, pkgInfo *packageInfo, stdout, stderr io.Writer) error {
	err := os.Setenv("GOPATH", goPath+":"+os.Getenv("GOPATH"))
	if err != nil {
		return err
	}

	cmd := exec.Command("go", "test")
	if *verbose {
		cmd.Args = append(cmd.Args, "-v")
	}
	cmd.Dir = path.Join(goPath, "src", pkgInfo.importPath)
	// cmd.Args = append(cmd.Args, pkgInfo.ToGoTestArg())
	cmd.Stdout = stdout
	cmd.Stderr = stderr
	return cmd.Run()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"

	"github.com/julienschmidt/httprouter"
	"github.com/larsha/brynn.se-go/app/route"
)

type status struct {
	sync.RWMutex
	ready bool
}

func main() {
	shutdown := make(chan int)

	//create a notification channel to shutdown
	sigChan := make(chan os.Signal, 1)

	//start the main http server for serving traffic
	server := &http.Server{Addr: ":" + os.Getenv("PORT"), Handler: route.Load()}
	go func() {
		server.ListenAndServe()
		shutdown <- 1
	}()

	//start the system server for health checks and shutdowns
	s := &status{
		ready: false,
	}

	hRouter := httprouter.New()
	hRouter.GET("/ready", makeReady(s))
	hRouter.GET("/prestop", makePrestop(s))
	go func() {
		http.ListenAndServe(":3001", hRouter)
	}()

	//register for interupt (Ctrl+C) and SIGTERM (docker)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-sigChan
		fmt.Println("Shutting down...")
		server.Close()
	}()

	//move server to ready state
	s.Lock()
	s.ready = true
	s.Unlock()

	<-shutdown
}

func makeReady(s *status) func(http.ResponseWriter, *http.Request, httprouter.Params) {
	return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		s.RLock()
		defer s.RUnlock()
		if s.ready {
			w.WriteHeader(http.StatusOK)
		} else {
			w.WriteHeader(http.StatusInternalServerError)
		}
	}
}

func makePrestop(s *status) func(http.ResponseWriter, *http.Request, httprouter.Params) {
	return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		s.Lock()
		s.ready = false
		s.Unlock()

		time.Sleep(10 * time.Second)
	}
}
<commit_msg>Minor update to graceful shutdown<commit_after>package main

import (
	"context"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"sync"
	"syscall"
	"time"

	"github.com/julienschmidt/httprouter"
	"github.com/larsha/brynn.se-go/app/route"
)

type status struct {
	sync.RWMutex
	ready bool
}

func main() {
	shutdown := make(chan int)
	sigChan := make(chan os.Signal, 1)

	// start the main http server for serving traffic
	server := &http.Server{Addr: ":" + os.Getenv("PORT"), Handler: route.Load()}
	go func() {
		server.ListenAndServe()
		shutdown <- 1
	}()

	// start the system server for health checks and shutdowns
	s := &status{
		ready: false,
	}

	hRouter := httprouter.New()
	hRouter.GET("/ready", isReady(s))
	hRouter.GET("/prestop", makePrestop(s))
	go func() {
		http.ListenAndServe(":3001", hRouter)
	}()

	// register for interrupt (Ctrl+C) and SIGTERM (docker)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-sigChan
		fmt.Println("Shutting down...")
		server.Shutdown(context.Background())
	}()

	// server is ready to handle requests
	s.Lock()
	s.ready = true
	s.Unlock()

	<-shutdown
	os.Exit(0)
}

func isReady(s *status) func(http.ResponseWriter, *http.Request, httprouter.Params) {
	return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		s.RLock()
		defer s.RUnlock()
		if s.ready {
			w.WriteHeader(http.StatusOK)
		} else {
			w.WriteHeader(http.StatusInternalServerError)
		}
	}
}

func makePrestop(s *status) func(http.ResponseWriter, *http.Request, httprouter.Params) {
	return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
		s.Lock()
		s.ready = false
		s.Unlock()

		time.Sleep(10 * time.Second)
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2016 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

// Gitea (git with a cup of tea) is a painless self-hosted Git Service.
package main // import "code.gitea.io/gitea"

import (
	"os"
	"runtime"

	"code.gitea.io/gitea/modules/log"

	"code.gitea.io/gitea/cmd"
	"code.gitea.io/gitea/modules/setting"
	"github.com/urfave/cli"
)

// Version holds the current Gitea version
var Version = "1.1.0+dev"

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	setting.AppVer = Version
}

func main() {
	app := cli.NewApp()
	app.Name = "Gitea"
	app.Usage = "A painless self-hosted Git service"
	app.Version = Version
	app.Commands = []cli.Command{
		cmd.CmdWeb,
		cmd.CmdServ,
		cmd.CmdUpdate,
		cmd.CmdDump,
		cmd.CmdCert,
		cmd.CmdAdmin,
	}
	app.Flags = append(app.Flags, []cli.Flag{}...)
	err := app.Run(os.Args)
	if err != nil {
		log.Fatal(4, "Fail to run app with %s: %v", os.Args, err)
	}

}
<commit_msg>fix: Remove call to set GOMAXPROCS (#577)<commit_after>// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2016 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

// Gitea (git with a cup of tea) is a painless self-hosted Git Service.
package main // import "code.gitea.io/gitea"

import (
	"os"

	"code.gitea.io/gitea/cmd"
	"code.gitea.io/gitea/modules/log"
	"code.gitea.io/gitea/modules/setting"
	"github.com/urfave/cli"
)

// Version holds the current Gitea version
var Version = "1.1.0+dev"

func init() {
	setting.AppVer = Version
}

func main() {
	app := cli.NewApp()
	app.Name = "Gitea"
	app.Usage = "A painless self-hosted Git service"
	app.Version = Version
	app.Commands = []cli.Command{
		cmd.CmdWeb,
		cmd.CmdServ,
		cmd.CmdUpdate,
		cmd.CmdDump,
		cmd.CmdCert,
		cmd.CmdAdmin,
	}
	app.Flags = append(app.Flags, []cli.Flag{}...)
	err := app.Run(os.Args)
	if err != nil {
		log.Fatal(4, "Fail to run app with %s: %v", os.Args, err)
	}

}
<|endoftext|>


<commit_before>package main

import (
  "bufio"
  "fmt"
  "github.com/kedebug/LispEx/repl"
  "github.com/kedebug/LispEx/scope"
  "io/ioutil"
  "os"
)

func LoadStdlib() string {
  lib, err := ioutil.ReadFile("stdlib.ss")
  if err != nil {
    panic(fmt.Sprintf("failed reading file: %v", err))
  }
  return string(lib)
}

func EvalFile(filename string) {
  lib := LoadStdlib()
  exprs, err := ioutil.ReadFile(filename)
  if err != nil {
    panic(fmt.Sprintf("failed reading file: %v", err))
    return
  }
  fmt.Println(repl.REPL(string(lib)+string(exprs), scope.NewRootScope()))
}

func try(body func(), handler func(interface{})) {
  defer func() {
    if err := recover(); err != nil {
      handler(err)
    }
  }()
  body()
}

func main() {
  if len(os.Args) > 1 {
    EvalFile(os.Args[1])
    return
  }

  lib := LoadStdlib()
  env := scope.NewRootScope()
  repl.REPL(lib, env)
  reader := bufio.NewReader(os.Stdin)

  for {
    fmt.Print(">> ")
    line, _, _ := reader.ReadLine()
    try(
      func() { fmt.Println(repl.REPL(string(line), env)) },
      func(e interface{}) { fmt.Println(e) },
    )
  }
}
<commit_msg>LispEx 0.1.0<commit_after>package main

import (
  "bufio"
  "fmt"
  "github.com/kedebug/LispEx/repl"
  "github.com/kedebug/LispEx/scope"
  "io/ioutil"
  "os"
  "time"
)

const version = "LispEx 0.1.0"

func LoadStdlib() string {
  lib, err := ioutil.ReadFile("stdlib.ss")
  if err != nil {
    panic(fmt.Sprintf("failed reading file: %v", err))
  }
  return string(lib)
}

func EvalFile(filename string) {
  lib := LoadStdlib()
  exprs, err := ioutil.ReadFile(filename)
  if err != nil {
    panic(fmt.Sprintf("failed reading file: %v", err))
    return
  }
  fmt.Println(repl.REPL(string(lib)+string(exprs), scope.NewRootScope()))
}

func try(body func(), handler func(interface{})) {
  defer func() {
    if err := recover(); err != nil {
      handler(err)
    }
  }()
  body()
}

func main() {
  if len(os.Args) > 1 {
    EvalFile(os.Args[1])
    return
  }

  lib := LoadStdlib()
  env := scope.NewRootScope()
  repl.REPL(lib, env)
  reader := bufio.NewReader(os.Stdin)

  fmt.Printf("%s (%v)\n", version, time.Now().Format(time.RFC850))

  for {
    fmt.Print(">> ")
    line, _, _ := reader.ReadLine()
    try(
      func() {
        r := repl.REPL(string(line), env)
        if len(r) > 0 {
          fmt.Println(r)
        }
      },
      func(e interface{}) { fmt.Println(e) },
    )
    time.Sleep(120 * time.Millisecond)
  }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"runtime"
	"time"

	"github.com/ernestio/aws-definition-mapper/definition"
	"github.com/ernestio/aws-definition-mapper/mapper"
	"github.com/ernestio/aws-definition-mapper/output"
	ecc "github.com/ernestio/ernest-config-client"
	"github.com/ghodss/yaml"
	"github.com/nats-io/nats"
)

var nc *nats.Conn
var natsErr error

func main() {
	nc = ecc.NewConfig(os.Getenv("NATS_URI")).Nats()

	if _, err := nc.Subscribe("definition.map.creation.aws", createDefinitionHandler); err != nil {
		log.Println(err)
	}
	if _, err := nc.Subscribe("definition.map.deletion.aws", deleteDefinitionHandler); err != nil {
		log.Println(err)
	}
	if _, err := nc.Subscribe("definition.map.import.aws", importDefinitionHandler); err != nil {
		log.Println(err)
	}

	if _, err := nc.Subscribe("service.import.done", importDoneHandler); err != nil {
		log.Println(err)
	}

	runtime.Goexit()
}

func createDefinitionHandler(msg *nats.Msg) {
	var om output.FSMMessage

	p, err := definition.PayloadFromJSON(msg.Data)
	if err != nil {
		log.Println("ERROR: failed to parse payload")
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed to parse payload."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	err = p.Service.Validate()
	if err != nil {
		log.Println("ERROR: " + err.Error())
		if err := nc.Publish(msg.Reply, []byte(`{"error":"`+err.Error()+`"}`)); err != nil {
			log.Println(err)
		}
		return
	}

	// new fsm message
	m := mapper.ConvertPayload(p)

	// previous output message if it exists
	if p.PrevID != "" {
		om, err = getPreviousServiceMapping(p.PrevID)
		if err != nil {
			log.Println("ERROR: failed to get previous output")
			if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed to get previous output."}`)); err != nil {
				log.Println(err)
			}
			return
		}

		if p.Service.VpcID != "" && p.Service.VpcID != om.VPCs.Items[0].VpcID {
			log.Println("ERROR: VPC ID cannot change between builds.")
			if err := nc.Publish(msg.Reply, []byte(`{"error":"VPC ID cannot change between builds."}`)); err != nil {
				log.Println(err)
			}
			return
		}
	}

	// Map provider data from previous build
	mapper.MapProviderData(m, &om)

	// Check for changes and create workflow arcs
	m.Diff(om)

	err = m.GenerateWorkflow("create-workflow.json")
	if err != nil {
		log.Println(err.Error())
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Could not generate workflow."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	data, err := json.Marshal(m)
	if err != nil {
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed marshal output message."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	if err := nc.Publish(msg.Reply, data); err != nil {
		log.Println(err)
	}
}

func deleteDefinitionHandler(msg *nats.Msg) {
	p, err := definition.PayloadFromJSON(msg.Data)
	if err != nil {
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed to parse payload."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	m, err := getPreviousServiceMapping(p.PrevID)
	if err != nil {
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed to get previous output."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	// Assign all items to delete
	m.NetworksToDelete = m.Networks
	for i := range m.NetworksToDelete.Items {
		m.NetworksToDelete.Items[i].Status = ""
	}
	m.InstancesToDelete = m.Instances
	for i := range m.InstancesToDelete.Items {
		m.InstancesToDelete.Items[i].Status = ""
	}
	m.FirewallsToDelete = m.Firewalls
	for i := range m.FirewallsToDelete.Items {
		m.FirewallsToDelete.Items[i].Status = ""
	}
	m.NatsToDelete = m.Nats
	for i := range m.NatsToDelete.Items {
		m.NatsToDelete.Items[i].Status = ""
	}
	m.ELBsToDelete = m.ELBs
	for i := range m.ELBsToDelete.Items {
		m.ELBsToDelete.Items[i].Status = ""
	}
	m.S3sToDelete = m.S3s
	for i := range m.S3sToDelete.Items {
		m.S3sToDelete.Items[i].Status = ""
	}
	m.Route53sToDelete = m.Route53s
	for i := range m.Route53sToDelete.Items {
		m.Route53sToDelete.Items[i].Status = ""
	}

	m.RDSClustersToDelete = m.RDSClusters
	for i := range m.RDSClustersToDelete.Items {
		m.RDSClustersToDelete.Items[i].Status = ""
	}

	m.RDSInstancesToDelete = m.RDSInstances
	for i := range m.RDSInstancesToDelete.Items {
		m.RDSInstancesToDelete.Items[i].Status = ""
	}

	m.EBSVolumesToDelete = m.EBSVolumes
	for i := range m.EBSVolumesToDelete.Items {
		m.EBSVolumesToDelete.Items[i].Status = ""
	}

	// Generate delete workflow
	if err := m.GenerateWorkflow("delete-workflow.json"); err != nil {
		log.Println(err)
	}

	data, err := json.Marshal(m)
	if err != nil {
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed marshal output message."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	if err := nc.Publish(msg.Reply, data); err != nil {
		log.Println(err)
	}
}

func importDefinitionHandler(msg *nats.Msg) {
	var om output.FSMMessage

	p, err := definition.PayloadFromJSON(msg.Data)
	if err != nil {
		log.Println("ERROR: failed to parse payload")
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed to parse payload."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	// new fsm message
	m := mapper.ConvertPayload(p)

	// previous output message if it exists
	if p.PrevID != "" {
		om, err = getPreviousServiceMapping(p.PrevID)
		if err != nil {
			log.Println("ERROR: failed to get previous output")
			if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed to get previous output."}`)); err != nil {
				log.Println(err)
			}
			return
		}
	}

	err = m.GenerateWorkflow("import-workflow.json")
	if err != nil {
		log.Println(err.Error())
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Could not generate workflow."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	data, err := json.Marshal(m)
	if err != nil {
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed marshal output message."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	// Map provider data from previous build
	mapper.MapProviderData(m, &om)

	// Check for changes and create workflow arcs
	m.Diff(om)

	if err := nc.Publish(msg.Reply, data); err != nil {
		log.Println(err)
	}
}

func importDoneHandler(msg *nats.Msg) {
	var m output.FSMMessage
	var s output.Service

	err := json.Unmarshal(msg.Data, &m)
	if err != nil {
		log.Println(err)
		return
	}

	if m.Type != "aws" {
		return
	}

	d := mapper.ConvertFSMMessage(&m)

	dj, err := json.Marshal(d)
	if err != nil {
		log.Println(err)
		return
	}

	fmt.Println(string(dj))

	dy, err := yaml.JSONToYAML(dj)
	if err != nil {
		log.Println(err)
		return
	}

	s.ID = m.ID
	s.Definition = string(dy)

	data, err := json.Marshal(s)
	if err != nil {
		log.Println(err)
		return
	}

	if err := nc.Publish(msg.Reply, data); err != nil {
		log.Println(err)
	}

}

func getPreviousServiceMapping(id string) (output.FSMMessage, error) {
	var payload output.FSMMessage

	msg, err := nc.Request("service.get.mapping", []byte(`{"id":"`+id+`"}`), time.Second)
	if err != nil {
		log.Println(err.Error())
		return payload, err
	}

	if err := json.Unmarshal(msg.Data, &payload); err != nil {
		return payload, err
	}

	return payload, nil
}

func setServiceDefinition(s *output.Service) error {
	data, err := json.Marshal(s)
	if err != nil {
		return err
	}

	_, err = nc.Request("service.set.definition", data, time.Second)

	return err
}
<commit_msg>publishing edited service message<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"runtime"
	"time"

	"github.com/ernestio/aws-definition-mapper/definition"
	"github.com/ernestio/aws-definition-mapper/mapper"
	"github.com/ernestio/aws-definition-mapper/output"
	ecc "github.com/ernestio/ernest-config-client"
	"github.com/ghodss/yaml"
	"github.com/nats-io/nats"
)

var nc *nats.Conn
var natsErr error

func main() {
	nc = ecc.NewConfig(os.Getenv("NATS_URI")).Nats()

	if _, err := nc.Subscribe("definition.map.creation.aws", createDefinitionHandler); err != nil {
		log.Println(err)
	}
	if _, err := nc.Subscribe("definition.map.deletion.aws", deleteDefinitionHandler); err != nil {
		log.Println(err)
	}
	if _, err := nc.Subscribe("definition.map.import.aws", importDefinitionHandler); err != nil {
		log.Println(err)
	}

	if _, err := nc.Subscribe("service.import.done", importDoneHandler); err != nil {
		log.Println(err)
	}

	runtime.Goexit()
}

func createDefinitionHandler(msg *nats.Msg) {
	var om output.FSMMessage

	p, err := definition.PayloadFromJSON(msg.Data)
	if err != nil {
		log.Println("ERROR: failed to parse payload")
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed to parse payload."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	err = p.Service.Validate()
	if err != nil {
		log.Println("ERROR: " + err.Error())
		if err := nc.Publish(msg.Reply, []byte(`{"error":"`+err.Error()+`"}`)); err != nil {
			log.Println(err)
		}
		return
	}

	// new fsm message
	m := mapper.ConvertPayload(p)

	// previous output message if it exists
	if p.PrevID != "" {
		om, err = getPreviousServiceMapping(p.PrevID)
		if err != nil {
			log.Println("ERROR: failed to get previous output")
			if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed to get previous output."}`)); err != nil {
				log.Println(err)
			}
			return
		}

		if p.Service.VpcID != "" && p.Service.VpcID != om.VPCs.Items[0].VpcID {
			log.Println("ERROR: VPC ID cannot change between builds.")
			if err := nc.Publish(msg.Reply, []byte(`{"error":"VPC ID cannot change between builds."}`)); err != nil {
				log.Println(err)
			}
			return
		}
	}

	// Map provider data from previous build
	mapper.MapProviderData(m, &om)

	// Check for changes and create workflow arcs
	m.Diff(om)

	err = m.GenerateWorkflow("create-workflow.json")
	if err != nil {
		log.Println(err.Error())
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Could not generate workflow."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	data, err := json.Marshal(m)
	if err != nil {
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed marshal output message."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	if err := nc.Publish(msg.Reply, data); err != nil {
		log.Println(err)
	}
}

func deleteDefinitionHandler(msg *nats.Msg) {
	p, err := definition.PayloadFromJSON(msg.Data)
	if err != nil {
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed to parse payload."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	m, err := getPreviousServiceMapping(p.PrevID)
	if err != nil {
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed to get previous output."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	// Assign all items to delete
	m.NetworksToDelete = m.Networks
	for i := range m.NetworksToDelete.Items {
		m.NetworksToDelete.Items[i].Status = ""
	}
	m.InstancesToDelete = m.Instances
	for i := range m.InstancesToDelete.Items {
		m.InstancesToDelete.Items[i].Status = ""
	}
	m.FirewallsToDelete = m.Firewalls
	for i := range m.FirewallsToDelete.Items {
		m.FirewallsToDelete.Items[i].Status = ""
	}
	m.NatsToDelete = m.Nats
	for i := range m.NatsToDelete.Items {
		m.NatsToDelete.Items[i].Status = ""
	}
	m.ELBsToDelete = m.ELBs
	for i := range m.ELBsToDelete.Items {
		m.ELBsToDelete.Items[i].Status = ""
	}
	m.S3sToDelete = m.S3s
	for i := range m.S3sToDelete.Items {
		m.S3sToDelete.Items[i].Status = ""
	}
	m.Route53sToDelete = m.Route53s
	for i := range m.Route53sToDelete.Items {
		m.Route53sToDelete.Items[i].Status = ""
	}

	m.RDSClustersToDelete = m.RDSClusters
	for i := range m.RDSClustersToDelete.Items {
		m.RDSClustersToDelete.Items[i].Status = ""
	}

	m.RDSInstancesToDelete = m.RDSInstances
	for i := range m.RDSInstancesToDelete.Items {
		m.RDSInstancesToDelete.Items[i].Status = ""
	}

	m.EBSVolumesToDelete = m.EBSVolumes
	for i := range m.EBSVolumesToDelete.Items {
		m.EBSVolumesToDelete.Items[i].Status = ""
	}

	// Generate delete workflow
	if err := m.GenerateWorkflow("delete-workflow.json"); err != nil {
		log.Println(err)
	}

	data, err := json.Marshal(m)
	if err != nil {
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed marshal output message."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	if err := nc.Publish(msg.Reply, data); err != nil {
		log.Println(err)
	}
}

func importDefinitionHandler(msg *nats.Msg) {
	var om output.FSMMessage

	p, err := definition.PayloadFromJSON(msg.Data)
	if err != nil {
		log.Println("ERROR: failed to parse payload")
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed to parse payload."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	// new fsm message
	m := mapper.ConvertPayload(p)

	// previous output message if it exists
	if p.PrevID != "" {
		om, err = getPreviousServiceMapping(p.PrevID)
		if err != nil {
			log.Println("ERROR: failed to get previous output")
			if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed to get previous output."}`)); err != nil {
				log.Println(err)
			}
			return
		}
	}

	err = m.GenerateWorkflow("import-workflow.json")
	if err != nil {
		log.Println(err.Error())
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Could not generate workflow."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	data, err := json.Marshal(m)
	if err != nil {
		if err := nc.Publish(msg.Reply, []byte(`{"error":"Failed marshal output message."}`)); err != nil {
			log.Println(err)
		}
		return
	}

	// Map provider data from previous build
	mapper.MapProviderData(m, &om)

	// Check for changes and create workflow arcs
	m.Diff(om)

	if err := nc.Publish(msg.Reply, data); err != nil {
		log.Println(err)
	}
}

func importDoneHandler(msg *nats.Msg) {
	var m output.FSMMessage

	err := json.Unmarshal(msg.Data, &m)
	if err != nil {
		log.Println(err)
		return
	}

	if m.Type != "aws" {
		return
	}

	d := mapper.ConvertFSMMessage(&m)

	dj, err := json.Marshal(d)
	if err != nil {
		log.Println(err)
		return
	}

	fmt.Println(string(dj))

	dy, err := yaml.JSONToYAML(dj)
	if err != nil {
		log.Println(err)
		return
	}

	s := output.Service{
		ID:         m.ID,
		Definition: string(dy),
	}

	data, err := json.Marshal(s)
	if err != nil {
		log.Println(err)
		return
	}

	if err = nc.Publish("service.set.definition", data); err != nil {
		log.Println(err)
		return
	}

	mapping, err := json.Marshal(m)
	if err != nil {
		log.Println(err)
		return
	}

	s = output.Service{
		ID:      m.ID,
		Mapping: string(mapping),
	}

	data, err = json.Marshal(s)
	if err != nil {
		log.Println(err)
		return
	}

	if err := nc.Publish("service.set.mapping", data); err != nil {
		log.Println(err)
	}
}

func getPreviousServiceMapping(id string) (output.FSMMessage, error) {
	var payload output.FSMMessage

	msg, err := nc.Request("service.get.mapping", []byte(`{"id":"`+id+`"}`), time.Second)
	if err != nil {
		log.Println(err.Error())
		return payload, err
	}

	if err := json.Unmarshal(msg.Data, &payload); err != nil {
		return payload, err
	}

	return payload, nil
}

func setServiceDefinition(s *output.Service) error {
	data, err := json.Marshal(s)
	if err != nil {
		return err
	}

	_, err = nc.Request("service.set.definition", data, time.Second)

	return err
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	// "log"
	"github.com/urfave/cli"
)

type CmdHandler func(*Config, *cli.Context) error

func CmdNotImplemented(*Config, *cli.Context) error {
	return fmt.Errorf("Command not implemented")
}

func main() {
	// Now the setup for the application

	cliapp := cli.NewApp()
	cliapp.Name = "s3-cli"
	// cliapp.Usage = ""
	cliapp.Version = "0.1.0"

    cli.VersionFlag = cli.BoolFlag{
        Name: "version, V",
        Usage: "print version number",
    }

	cliapp.Flags = []cli.Flag{
		cli.StringSliceFlag{
			Name:  "config, c",
			Value: &cli.StringSlice{"$HOME/.s3cfg"},
			Usage: "Config `FILE` name.",
		},
		cli.StringFlag{
			Name:  "access-key",
			Usage: "AWS Access Key `ACCESS_KEY`",
            EnvVar: "AWS_ACCESS_KEY_ID,AWS_ACCESS_KEY",
		},
		cli.StringFlag{
			Name:  "secret-key",
			Usage: "AWS Secret Key `SECRET_KEY`",
            EnvVar: "AWS_SECRET_ACCESS_KEY,AWS_SECRET_KEY",
		},

		cli.BoolFlag{
			Name:  "recursive,r",
			Usage: "Recursive upload, download or removal",
		},
		cli.BoolFlag{
			Name:  "force",
			Usage: "Force overwrite and other dangerous operations.",
		},
		cli.BoolFlag{
			Name:  "skip-existing",
			Usage: "Skip over files that exist at the destination (only for [get] and [sync] commands).",
		},

		cli.BoolFlag{
			Name:  "verbose,v",
			Usage: "Verbose output (e.g. debugging)",
		},
		cli.BoolFlag{
			Name:  "dry-run,n",
			Usage: "Only show what should be uploaded or downloaded but don't actually do it. May still perform S3 requests to get bucket listings and other information though (only for file transfer commands)",
		},
		cli.BoolFlag{
			Name:  "check-md5",
			Usage: "Check MD5 sums when comparing files for [sync].  (default)",
		},
		cli.BoolFlag{
			Name:  "no-check-md5",
			Usage: "Do not check MD5 sums when comparing files for [sync].  Only size will be compared. May significantly speed up transfer but may also miss some changed files.",
		},
	}

	// The wrapper to launch a command -- take care of standard setup
	//  before we get going
	launch := func(handler CmdHandler) func(*cli.Context) error {
		return func(c *cli.Context) error {
			err := handler(NewConfig(c), c)
			if err != nil {
				fmt.Println(err.Error())
			}
			return err
		}
	}

	cliapp.Commands = []cli.Command{
		{
			Name:   "mb",
			Usage:  "Make bucket -- s3-cli mb s3://BUCKET",
			Action: launch(MakeBucket),
            Flags: cliapp.Flags,
		},
		{
			Name:   "rb",
			Usage:  "Remove bucket -- s3-cli mb s3://BUCKET",
			Action: launch(RemoveBucket),
            Flags: cliapp.Flags,
		},
		{
			Name:   "ls",
			Usage:  "List objects or buckets -- s3-cli ls [s3://BUCKET[/PREFIX]]",
			Action: launch(ListBucket),
            Flags: cliapp.Flags,
		},
		{
			Name:   "la",
			Usage:  "List all object in all buckets -- s3-cli la",
			Action: launch(ListAll),
            Flags: cliapp.Flags,
		},
		{
			Name:   "put",
			Usage:  "Put file from bucket (really 'cp') -- s3-cli put FILE [FILE....] s3://BUCKET/PREFIX",
			Action: launch(CmdCopy),
            Flags: cliapp.Flags,
		},
		{
			Name:   "get",
			Usage:  "Get file from bucket (really 'cp') -- s3-cli get s3://BUCKET/OBJECT LOCAL_FILE",
			Action: launch(CmdCopy),
            Flags: cliapp.Flags,
		},
		{
			Name:   "del",
			Usage:  "Delete file from bucket -- s3-cli del s3://BUCKET/OBJECT",
			Action: launch(DeleteObjects),
            Flags: cliapp.Flags,
		},
		{
			Name:   "rm",
			Usage:  "Delete file from bucket (del synonym) -- s3-cli rm s3://BUCKET/OBJECT",
			Action: launch(DeleteObjects),
            Flags: cliapp.Flags,
		},
		{
			Name:   "du",
			Usage:  "Disk usage by buckets -- [s3://BUCKET[/PREFIX]]",
			Action: launch(GetUsage),
            Flags: cliapp.Flags,
		},
		{
			Name:   "cp",
			Usage:  "copy files and directories -- SRC [SRC...] DST",
			Action: launch(CmdCopy),
            Flags: cliapp.Flags,
		},
		{
			Name:   "sync",
			Usage:  "Synchronize a directory tree to S3 -- LOCAL_DIR s3://BUCKET[/PREFIX] or s3://BUCKET[/PREFIX] LOCAL_DIR",
			Action: launch(CmdSync),
            Flags: cliapp.Flags,
		},
		{
			Name:   "modify",
			Usage:  "Modify object metadata -- s3://BUCKET1/OBJECT",
			Action: launch(Modify),
            Flags: cliapp.Flags,
		},
		{
			Name:   "info",
			Usage:  "Get various information about Buckets or Files -- s3://BUCKET[/OBJECT]",
			Action: launch(GetInfo),
            Flags: cliapp.Flags,
		},
        // info
        // mv
	}

	cliapp.Run(os.Args)
}
<commit_msg>bump version<commit_after>package main

import (
	"fmt"
	"os"
	// "log"
	"github.com/urfave/cli"
)

type CmdHandler func(*Config, *cli.Context) error

func CmdNotImplemented(*Config, *cli.Context) error {
	return fmt.Errorf("Command not implemented")
}

func main() {
	// Now the setup for the application

	cliapp := cli.NewApp()
	cliapp.Name = "s3-cli"
	// cliapp.Usage = ""
	cliapp.Version = "0.2.0"

    cli.VersionFlag = cli.BoolFlag{
        Name: "version, V",
        Usage: "print version number",
    }

	cliapp.Flags = []cli.Flag{
		cli.StringSliceFlag{
			Name:  "config, c",
			Value: &cli.StringSlice{"$HOME/.s3cfg"},
			Usage: "Config `FILE` name.",
		},
		cli.StringFlag{
			Name:  "access-key",
			Usage: "AWS Access Key `ACCESS_KEY`",
            EnvVar: "AWS_ACCESS_KEY_ID,AWS_ACCESS_KEY",
		},
		cli.StringFlag{
			Name:  "secret-key",
			Usage: "AWS Secret Key `SECRET_KEY`",
            EnvVar: "AWS_SECRET_ACCESS_KEY,AWS_SECRET_KEY",
		},

		cli.BoolFlag{
			Name:  "recursive,r",
			Usage: "Recursive upload, download or removal",
		},
		cli.BoolFlag{
			Name:  "force",
			Usage: "Force overwrite and other dangerous operations.",
		},
		cli.BoolFlag{
			Name:  "skip-existing",
			Usage: "Skip over files that exist at the destination (only for [get] and [sync] commands).",
		},

		cli.BoolFlag{
			Name:  "verbose,v",
			Usage: "Verbose output (e.g. debugging)",
		},
		cli.BoolFlag{
			Name:  "dry-run,n",
			Usage: "Only show what should be uploaded or downloaded but don't actually do it. May still perform S3 requests to get bucket listings and other information though (only for file transfer commands)",
		},
		cli.BoolFlag{
			Name:  "check-md5",
			Usage: "Check MD5 sums when comparing files for [sync].  (default)",
		},
		cli.BoolFlag{
			Name:  "no-check-md5",
			Usage: "Do not check MD5 sums when comparing files for [sync].  Only size will be compared. May significantly speed up transfer but may also miss some changed files.",
		},
	}

	// The wrapper to launch a command -- take care of standard setup
	//  before we get going
	launch := func(handler CmdHandler) func(*cli.Context) error {
		return func(c *cli.Context) error {
			err := handler(NewConfig(c), c)
			if err != nil {
				fmt.Println(err.Error())
			}
			return err
		}
	}

	cliapp.Commands = []cli.Command{
		{
			Name:   "mb",
			Usage:  "Make bucket -- s3-cli mb s3://BUCKET",
			Action: launch(MakeBucket),
            Flags: cliapp.Flags,
		},
		{
			Name:   "rb",
			Usage:  "Remove bucket -- s3-cli mb s3://BUCKET",
			Action: launch(RemoveBucket),
            Flags: cliapp.Flags,
		},
		{
			Name:   "ls",
			Usage:  "List objects or buckets -- s3-cli ls [s3://BUCKET[/PREFIX]]",
			Action: launch(ListBucket),
            Flags: cliapp.Flags,
		},
		{
			Name:   "la",
			Usage:  "List all object in all buckets -- s3-cli la",
			Action: launch(ListAll),
            Flags: cliapp.Flags,
		},
		{
			Name:   "put",
			Usage:  "Put file from bucket (really 'cp') -- s3-cli put FILE [FILE....] s3://BUCKET/PREFIX",
			Action: launch(CmdCopy),
            Flags: cliapp.Flags,
		},
		{
			Name:   "get",
			Usage:  "Get file from bucket (really 'cp') -- s3-cli get s3://BUCKET/OBJECT LOCAL_FILE",
			Action: launch(CmdCopy),
            Flags: cliapp.Flags,
		},
		{
			Name:   "del",
			Usage:  "Delete file from bucket -- s3-cli del s3://BUCKET/OBJECT",
			Action: launch(DeleteObjects),
            Flags: cliapp.Flags,
		},
		{
			Name:   "rm",
			Usage:  "Delete file from bucket (del synonym) -- s3-cli rm s3://BUCKET/OBJECT",
			Action: launch(DeleteObjects),
            Flags: cliapp.Flags,
		},
		{
			Name:   "du",
			Usage:  "Disk usage by buckets -- [s3://BUCKET[/PREFIX]]",
			Action: launch(GetUsage),
            Flags: cliapp.Flags,
		},
		{
			Name:   "cp",
			Usage:  "copy files and directories -- SRC [SRC...] DST",
			Action: launch(CmdCopy),
            Flags: cliapp.Flags,
		},
		{
			Name:   "sync",
			Usage:  "Synchronize a directory tree to S3 -- LOCAL_DIR s3://BUCKET[/PREFIX] or s3://BUCKET[/PREFIX] LOCAL_DIR",
			Action: launch(CmdSync),
            Flags: cliapp.Flags,
		},
		{
			Name:   "modify",
			Usage:  "Modify object metadata -- s3://BUCKET1/OBJECT",
			Action: launch(Modify),
            Flags: cliapp.Flags,
		},
		{
			Name:   "info",
			Usage:  "Get various information about Buckets or Files -- s3://BUCKET[/OBJECT]",
			Action: launch(GetInfo),
            Flags: cliapp.Flags,
		},
        // info
        // mv
	}

	cliapp.Run(os.Args)
}
<|endoftext|>


<commit_before>package linenotcat

import (
	"fmt"
	"os"
	"runtime"

	"github.com/jessevdk/go-flags"
)

var (
	ver string
	rev string
)

type opts struct {
	Message    string `short:"m" long:"message" default:"" description:"Send a text message directly"`
	ImageFile  string `short:"i" long:"image" default:"" description:"Send an image file"`
	Tee        bool   `short:"t" long:"tee" default:"false" description:"Print STDIN to screen before posting"`
	Stream     bool   `short:"s" long:"stream" default:"false" description:"Post messages to LINE Notify continuously"`
	ConfigFile string `long:"config_file" default:"" description:"Load the specified configuration file"`
	Status     bool   `long:"status" default:"false" description:"Show connection status that belongs to the token"`
}

func parseArgs(args []string) (opt *opts, remainArgs []string) {
	o := &opts{}
	p := flags.NewParser(o, flags.Default)
	p.Usage = fmt.Sprintf("\n\nVersion: %s\nRevision: %s", ver, rev)
	remainArgs, err := p.ParseArgs(args)
	if err != nil {
		os.Exit(1)
	}
	return o, remainArgs
}

func Run(args []string) {
	o, remainArgs := parseArgs(args)

	var token string
	var err error
	if o.ConfigFile == "" {
		token, err = readDefaultToken()
	} else {
		token, err = readToken(o.ConfigFile)
	}

	if err != nil {
		fmt.Printf(`[ERROR] Failed to load configuration file: %v
Is configuration file perhaps missing?
Please try:`, err)
		if runtime.GOOS == "windows" {
			fmt.Println(`	C:\>echo 'YOUR_ACCESS_TOKEN' > %USERPROFILE%\.linenotcat`)
		} else {
			fmt.Println(`	$ echo 'YOUR_ACCESS_TOKEN' > $HOME/.linenotcat`)
		}
		os.Exit(1)
	}

	arb := &apiRequestBuilder{token: token}

	if o.Status {
		status := &status{apiRequestBuilder: arb}
		err := status.getStatus()
		if err != nil {
			panic(err)
		}
		return
	}

	ln := &lineNotifier{
		apiRequestBuilder: arb,
	}

	if o.ImageFile != "" {
		warnIfStreamMode(o)
		warnIfArgumentRemained(remainArgs)

		msg := o.Message
		if msg == "" {
			msg = "Image file"
		}
		err := ln.notifyImage(o.ImageFile, msg, o.Tee)
		if err != nil {
			panic(err)
		}
		return
	}

	if o.Message != "" {
		// Send text message directly
		warnIfStreamMode(o)
		ln.notifyMessage(o.Message, o.Tee)
		return
	}

	if o.Stream {
		// Stream mode
		warnIfArgumentRemained(remainArgs)

		s := newStream(ln)
		go s.processStreamQueue(o.Tee)
		go s.watchStdin()
		go s.trap()
		select {}

		return
	}

	if len(remainArgs) > 0 {
		// Send file contents
		warnIfStreamMode(o)
		ln.notifyFile(remainArgs[0], o.Tee)
		return
	}

	// Send messages from STDIN
	lines := make(chan string)
	go readFromStdin(lines)

	tmpFilePath, err := writeTemp(lines)
	if err != nil {
		panic(err)
	}

	defer os.Remove(tmpFilePath)
	ln.notifyFile(tmpFilePath, o.Tee)
}

func warnIfStreamMode(o *opts) {
	if o.Stream {
		fmt.Println("Given stream option, but it is ignored when image sending mode")
	}
}

func warnIfArgumentRemained(remainArgs []string) {
	if len(remainArgs) > 0 {
		fmt.Println("Given file, but it is ignored when stream mode")
	}
}
<commit_msg>github.com/jessevdk/go-flags changed policy as that default:"false" is an error.<commit_after>package linenotcat

import (
	"fmt"
	"os"
	"runtime"

	"github.com/jessevdk/go-flags"
)

var (
	ver string
	rev string
)

type opts struct {
	Message    string `short:"m" long:"message" default:"" description:"Send a text message directly"`
	ImageFile  string `short:"i" long:"image" default:"" description:"Send an image file"`
	Tee        bool   `short:"t" long:"tee" description:"Print STDIN to screen before posting"`
	Stream     bool   `short:"s" long:"stream" description:"Post messages to LINE Notify continuously"`
	ConfigFile string `long:"config_file" default:"" description:"Load the specified configuration file"`
	Status     bool   `long:"status" description:"Show connection status that belongs to the token"`
}

func parseArgs(args []string) (opt *opts, remainArgs []string) {
	o := &opts{}
	p := flags.NewParser(o, flags.Default)
	p.Usage = fmt.Sprintf("\n\nVersion: %s\nRevision: %s", ver, rev)
	remainArgs, err := p.ParseArgs(args)
	if err != nil {
		os.Exit(1)
	}
	return o, remainArgs
}

func Run(args []string) {
	o, remainArgs := parseArgs(args)

	var token string
	var err error
	if o.ConfigFile == "" {
		token, err = readDefaultToken()
	} else {
		token, err = readToken(o.ConfigFile)
	}

	if err != nil {
		fmt.Printf(`[ERROR] Failed to load configuration file: %v
Is configuration file perhaps missing?
Please try:`, err)
		if runtime.GOOS == "windows" {
			fmt.Println(`	C:\>echo 'YOUR_ACCESS_TOKEN' > %USERPROFILE%\.linenotcat`)
		} else {
			fmt.Println(`	$ echo 'YOUR_ACCESS_TOKEN' > $HOME/.linenotcat`)
		}
		os.Exit(1)
	}

	arb := &apiRequestBuilder{token: token}

	if o.Status {
		status := &status{apiRequestBuilder: arb}
		err := status.getStatus()
		if err != nil {
			panic(err)
		}
		return
	}

	ln := &lineNotifier{
		apiRequestBuilder: arb,
	}

	if o.ImageFile != "" {
		warnIfStreamMode(o)
		warnIfArgumentRemained(remainArgs)

		msg := o.Message
		if msg == "" {
			msg = "Image file"
		}
		err := ln.notifyImage(o.ImageFile, msg, o.Tee)
		if err != nil {
			panic(err)
		}
		return
	}

	if o.Message != "" {
		// Send text message directly
		warnIfStreamMode(o)
		ln.notifyMessage(o.Message, o.Tee)
		return
	}

	if o.Stream {
		// Stream mode
		warnIfArgumentRemained(remainArgs)

		s := newStream(ln)
		go s.processStreamQueue(o.Tee)
		go s.watchStdin()
		go s.trap()
		select {}

		return
	}

	if len(remainArgs) > 0 {
		// Send file contents
		warnIfStreamMode(o)
		ln.notifyFile(remainArgs[0], o.Tee)
		return
	}

	// Send messages from STDIN
	lines := make(chan string)
	go readFromStdin(lines)

	tmpFilePath, err := writeTemp(lines)
	if err != nil {
		panic(err)
	}

	defer os.Remove(tmpFilePath)
	ln.notifyFile(tmpFilePath, o.Tee)
}

func warnIfStreamMode(o *opts) {
	if o.Stream {
		fmt.Println("Given stream option, but it is ignored when image sending mode")
	}
}

func warnIfArgumentRemained(remainArgs []string) {
	if len(remainArgs) > 0 {
		fmt.Println("Given file, but it is ignored when stream mode")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
)

import (
	"github.com/alfredxing/calc/compute"
)

import (
	"golang.org/x/crypto/ssh/terminal"
)

// Stores the state of the terminal before making it raw
var regularState *terminal.State

func main() {
	if len(os.Args) > 1 {
		input := strings.Replace(strings.Join(os.Args[1:], ""), " ", "", -1)
		res, err := compute.Evaluate(input)
		if err != nil {
			fmt.Println("Error: " + err.Error())
			return
		}
		fmt.Printf("%s\n", strconv.FormatFloat(res, 'G', -1, 64))
		return
	}

	var err error
	regularState, err = terminal.MakeRaw(0)
	if err != nil {
		panic(err)
	}
	defer terminal.Restore(0, regularState)

	term := terminal.NewTerminal(os.Stdin, "> ")
	term.AutoCompleteCallback = handleKey
	for {
		text, err := term.ReadLine()
		if err != nil {
			if err == io.EOF {
				// Quit without error on Ctrl^D
				fmt.Println()
				break
			}
			panic(err)
		}

		text = strings.Replace(text, " ", "", -1)
		if text == "exit" || text == "quit" {
			break
		}

		res, err := compute.Evaluate(text)
		if err != nil {
			term.Write([]byte(fmt.Sprintln("Error: " + err.Error())))
			continue
		}
		term.Write([]byte(fmt.Sprintln(strconv.FormatFloat(res, 'G', -1, 64))))
	}
}

func handleKey(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
	if key == '\x03' {
		fmt.Println()
		terminal.Restore(0, regularState)
		os.Exit(0)
	}
	return "", 0, false
}
<commit_msg>Better exits<commit_after>package main

import (
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
)

import (
	"github.com/alfredxing/calc/compute"
)

import (
	"golang.org/x/crypto/ssh/terminal"
)

// Stores the state of the terminal before making it raw
var regularState *terminal.State

func main() {
	if len(os.Args) > 1 {
		input := strings.Replace(strings.Join(os.Args[1:], ""), " ", "", -1)
		res, err := compute.Evaluate(input)
		if err != nil {
			return
		}
		fmt.Printf("%s\n", strconv.FormatFloat(res, 'G', -1, 64))
		return
	}

	var err error
	regularState, err = terminal.MakeRaw(0)
	if err != nil {
		panic(err)
	}
	defer terminal.Restore(0, regularState)

	term := terminal.NewTerminal(os.Stdin, "> ")
	term.AutoCompleteCallback = handleKey
	for {
		text, err := term.ReadLine()
		if err != nil {
			if err == io.EOF {
				// Quit without error on Ctrl^D
				exit()
			}
			panic(err)
		}

		text = strings.Replace(text, " ", "", -1)
		if text == "exit" || text == "quit" {
			break
		}

		res, err := compute.Evaluate(text)
		if err != nil {
			term.Write([]byte(fmt.Sprintln("Error: " + err.Error())))
			continue
		}
		term.Write([]byte(fmt.Sprintln(strconv.FormatFloat(res, 'G', -1, 64))))
	}
}

func handleKey(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
	if key == '\x03' {
		// Quit without error on Ctrl^C
		exit()
	}
	return "", 0, false
}

func exit() {
	terminal.Restore(0, regularState)
	fmt.Println()
	os.Exit(0)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"github.com/ActiveState/tail"
	"github.com/op/go-logging"
	"net/http"
	"regexp"
	"strings"
	"sync"
)

type Datasource struct {
	Create_date string // for now, obv needs to be different
	Name        string
	Params      string
}

type state struct {
	*sync.RWMutex // inherits locking methods
	Vals          []Datasource
}

// declare a globally scoped State variable, otherwise
// the request handlers can't get to it. If there is a better
// way to do this, plmk.
var State = &state{&sync.RWMutex{}, []Datasource{}}

func viewHandler(w http.ResponseWriter, r *http.Request) {
	var log = logging.MustGetLogger("example")

	log.Notice("viewHandler: acquiring read-lock")
	State.RLock()         // grab a lock, but then don't forget to
	defer State.RUnlock() // unlock it again once we're done

	log.Info(fmt.Sprintf("Request for %s\n", r.URL.Path))
	js, err := json.Marshal(State.Vals)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

func addItemToState(ds Datasource) {
	var log = logging.MustGetLogger("example")
	log.Notice("addItemToState: acquiring write-lock")
	State.Lock()
	defer State.Unlock()
	defer log.Notice("addItemToState: released write-lock")
	State.Vals = append(State.Vals, ds)
}

func tailLogfile(dss []string, c chan string) {
	var log = logging.MustGetLogger("example")

	var dataPath = regexp.MustCompile(`\[creates\] creating (database) file .*/whisper/(.*)\.wsp`)
	t, err := tail.TailFile("./creates.log", tail.Config{Follow: true, ReOpen: true, MustExist: true})
	if err == nil {
		for line := range t.Lines {
			match := dataPath.FindStringSubmatch(line.Text)
			if len(match) > 0 {
				log.Info(line.Text)
				ds := fmt.Sprintf("%v", strings.Replace(match[2], `/`, `.`, -1))
				addItemToState(Datasource{Name: ds, Create_date: "adsfsdfs"})
				dss = append(dss, ds)
				log.Notice(fmt.Sprintf("Found new datasource, total: %v, newly added: %s", len(dss), ds))
			}
		}
	}
	c <- fmt.Sprintf("%s", err)
}

func main() {
	error_channel := make(chan string)
	var dss []string
	var log = logging.MustGetLogger("example")
	var format = "%{color}%{time:15:04:05.000000} [%{pid}] ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}"

	// Setup logger https://github.com/op/go-logging/blob/master/examples/example.go
	logging.SetFormatter(logging.MustStringFormatter(format))
	log.Info("Graphite News -- Showing which new metrics are available since 2014\n")
	log.Notice("Graphite News -- Serving UI on: http://localhost:2934\n")

	// http://stackoverflow.com/questions/18487923/golang-storing-caching-values-to-be-served-in-following-http-requests

	http.HandleFunc("/view/", viewHandler)
	go http.ListenAndServe(":2934", nil)
	go tailLogfile(dss, error_channel)

	log.Notice("Graphite News -- Showing which new metrics are available since 2014\n")

	// Wait for errors to appear then shut down
	log.Error(<-error_channel)
}
<commit_msg>Fixed parsing a little better<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/ActiveState/tail"
	"github.com/op/go-logging"
	"net/http"
	"regexp"
	"strings"
	"sync"
)

type Datasource struct {
	Name        string
	Create_date string // for now, obv needs to be different
	Params      string
}

type state struct {
	*sync.RWMutex // inherits locking methods
	Vals          []Datasource
}

// declare a globally scoped State variable, otherwise
// the request handlers can't get to it. If there is a better
// way to do this, plmk.
var State = &state{&sync.RWMutex{}, []Datasource{}}

func viewHandler(w http.ResponseWriter, r *http.Request) {
	var log = logging.MustGetLogger("example")

	log.Notice("viewHandler: acquiring read-lock")
	State.RLock()         // grab a lock, but then don't forget to
	defer State.RUnlock() // unlock it again once we're done

	log.Info(fmt.Sprintf("Request for %s\n", r.URL.Path))
	js, err := json.Marshal(State.Vals)

	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

func addItemToState(ds Datasource) {
	var log = logging.MustGetLogger("example")
	log.Notice("addItemToState: acquiring write-lock")
	State.Lock()
	defer State.Unlock()
	defer log.Notice("addItemToState: released write-lock")
	State.Vals = append(State.Vals, ds)
}

func tailLogfile(dss []string, c chan string) {
	var log = logging.MustGetLogger("example")

	var dataPath = regexp.MustCompile(`.*out:(.*) :: \[creates\] creating database file .*/whisper/(.*)\.wsp (.*)`)
	t, err := tail.TailFile("./creates.log", tail.Config{Follow: true, ReOpen: true, MustExist: true})
	if err == nil {
		for line := range t.Lines {
			match := dataPath.FindStringSubmatch(line.Text)
			if len(match) > 0 {
				log.Info(line.Text)
				log.Info(fmt.Sprintf("%s -- %s -- %s -- %s",  match[1], match[2], match[3]))
				log.Info("  ^----")
				ds := fmt.Sprintf("%s", strings.Replace(match[2], `/`, `.`, -1))
				addItemToState(Datasource{Name: ds, Create_date: match[1], Params: match[3] })
				dss = append(dss, ds)
				log.Notice(fmt.Sprintf("Found new datasource, total: %v, newly added: %s", len(dss), ds))
			}
		}
	}
	c <- fmt.Sprintf("%s", err)
}

func main() {
	error_channel := make(chan string)
	var dss []string
	var log = logging.MustGetLogger("example")
	var format = "%{color}%{time:15:04:05.000000} [%{pid}] ▶ %{level:.4s} %{id:03x}%{color:reset} %{message}"

	// Setup logger https://github.com/op/go-logging/blob/master/examples/example.go
	logging.SetFormatter(logging.MustStringFormatter(format))
	log.Info("Graphite News -- Showing which new metrics are available since 2014\n")
	log.Notice("Graphite News -- Serving UI on: http://localhost:2934\n")

	// http://stackoverflow.com/questions/18487923/golang-storing-caching-values-to-be-served-in-following-http-requests

	http.HandleFunc("/view/", viewHandler)
	go http.ListenAndServe(":2934", nil)
	go tailLogfile(dss, error_channel)

	log.Notice("Graphite News -- Showing which new metrics are available since 2014\n")

	// Wait for errors to appear then shut down
	log.Error(<-error_channel)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"os"
	//"path/filepath"
)

// Конфигурация - глобальные настроки.
type Config struct {
	// Максимальное количество одновременно выполняемых процессов.
	Parallel int `json:"parallel"`
	// Список переменных конфигурации, применяются в опциях процесса.
	Defs defines `json:"defs"`
	// Цепочка процессов (Этапов) обработки.
	Chain []ChainItem `json:"chain"`
}

func fatal(a ...interface{}) {
	fmt.Println(a...)
	os.Exit(1)
}

func check(msg string, err error) {
	if err != nil {
		fmt.Println(msg, err)
		os.Exit(1)
	}
}

func main() {
	// чтение опций
	// обработка каждого элемента цепочки:
	// подстановка глобальных переменных
	// поиск подходящих файлов
	// исключение неизменившихся + обновление кэша
	// для каждого найденого
	// инстанцирование имени файла
	// вызов инструмента

	// в текущей директории находится конфиг и кеш, она является целевой
	// root проекта указывается в параметре

	// чтение конфига
	conf := readConf()

	// получение целевой директории и директории проекта
	targetDir := "./"

	flag.Parse()
	rootDir := flag.Arg(0)

	setTargeDir(targetDir)
	setRootDir(rootDir)

	// разворачивание макроопределений
	conf.Defs.bootstrap()

	//fmt.Println(conf.Defs)

	// чтение кеша
	cache := ReadCache("gomakecache.json")

	// обработка цепочки
	for _, item := range conf.Chain {
		fmt.Println(item.Descr)
		item.SearchFiles(rootDir, targetDir, cache, conf.Defs)
		item.CacheOpts(conf.Defs)
		item.Exec()
	}

	// запись кеша
	cache.Write("gomakecache.json")
}

func readConf() *Config {
	f, err := os.Open("gomake.json")
	check("Unable open config file:", err)
	defer f.Close()

	conf := new(Config)
	err = json.NewDecoder(f).Decode(conf)
	check("Wrong config:", err)

	return conf
}
<commit_msg>Мажорные изменения + Реализован флаг -v +/- Переработана подсистема исключений +/-	Изменены аргумены вызова утилиты + Реализованы аргументы по умолчанию<commit_after>package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
)

var (
	verbose bool
)

func init() {
	const (
		usage_verbose = "enable verbose output"
	)
	flag.BoolVar(&verbose, "-verbose", false, usage_verbose)
	flag.BoolVar(&verbose, "v", false, usage_verbose)
}

// TODO: организовать хранение в репозитарии и обозначить направление развития
// TODO: сделать проверку зависимостей и построение с учетом зависимостей
// TODO: реализовать макрос ${#}
func main() {
	defer exit()

	flag.Parse()

	if verbose {
		log.SetFlags(log.Lmicroseconds)
	} else {
		log.SetOutput(ioutil.Discard)
	}

	scenario := "build.json"
	root := ".."
	if flag.NArg() > 0 {
		scenario = flag.Arg(0)
		if len(filepath.Ext(scenario)) == 0 {
			scenario += ".json"
		}
		if flag.NArg() > 1 {
			root = flag.Arg(1)
		}
	}

	if wd, err := os.Getwd(); err != nil {
		panic(err)
	} else {
		log.Println("work dir: ", wd)
	}
	log.Println("root dir: ", root)
	log.Println("scenario: ", scenario)

	conf := loadConfigs(scenario, root)

	conf.Defs.set(".", ".")
	conf.Defs.set("..", root)
	conf.Defs.bootstrap()

	cache := ReadCache("gomakecache.json")

	for _, item := range conf.Ops {
		fmt.Println(item.Descr)
		item.SearchFiles(root, ".", cache, conf.Defs)
		item.CacheOpts(conf.Defs)
		item.Exec()
	}

	cache.Write("gomakecache.json")
}
<|endoftext|>


<commit_before>// Copyright 2017 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package defaultrolemanager

import (
	"errors"

	"github.com/casbin/casbin/rbac"
	"github.com/casbin/casbin/util"
)

type RoleManager struct {
	allRoles             map[string]*Role
	maxHierarchyLevel    int
}

// NewRoleManager is the constructor for creating an instance of the
// default RoleManager implementation.
func NewRoleManager(maxHierarchyLevel int) rbac.RoleManager {
	rm := RoleManager{}
	rm.allRoles = make(map[string]*Role)
	rm.maxHierarchyLevel = maxHierarchyLevel
	return &rm
}

func (rm *RoleManager) hasRole(name string) bool {
	_, ok := rm.allRoles[name]
	return ok
}

func (rm *RoleManager) createRole(name string) *Role {
	if !rm.hasRole(name) {
		rm.allRoles[name] = newRole(name)
	}

	return rm.allRoles[name]
}

// Clear clears all stored data and resets the role manager to the initial state.
func (rm *RoleManager) Clear() error {
	rm.allRoles = make(map[string]*Role)
	return nil
}

// AddLink adds the inheritance link between role: name1 and role: name2.
// aka role: name1 inherits role: name2.
// domain is a prefix to the roles.
func (rm *RoleManager) AddLink(name1 string, name2 string, domain ...string) error {
	if len(domain) == 1 {
		name1 = domain[0] + "::" + name1
		name2 = domain[0] + "::" + name2
	} else if len(domain) > 1 {
		return errors.New("error: domain should be 1 parameter")
	}

	role1 := rm.createRole(name1)
	role2 := rm.createRole(name2)
	role1.addRole(role2)
	return nil
}

// DeleteLink deletes the inheritance link between role: name1 and role: name2.
// aka role: name1 does not inherit role: name2 any more.
// domain is a prefix to the roles.
func (rm *RoleManager) DeleteLink(name1 string, name2 string, domain ...string) error {
	if len(domain) == 1 {
		name1 = domain[0] + "::" + name1
		name2 = domain[0] + "::" + name2
	} else if len(domain) > 1 {
		return errors.New("error: domain should be 1 parameter")
	}

	if !rm.hasRole(name1) || !rm.hasRole(name2) {
		return errors.New("error: name1 or name2 does not exist")
	}

	role1 := rm.createRole(name1)
	role2 := rm.createRole(name2)
	role1.deleteRole(role2)
	return nil
}

// HasLink determines whether role: name1 inherits role: name2.
// domain is a prefix to the roles.
func (rm *RoleManager) HasLink(name1 string, name2 string, domain ...string) (bool, error) {
	if len(domain) == 1 {
		name1 = domain[0] + "::" + name1
		name2 = domain[0] + "::" + name2
	} else if len(domain) > 1 {
		return false, errors.New("error: domain should be 1 parameter")
	}

	if name1 == name2 {
		return true, nil
	}

	if !rm.hasRole(name1) || !rm.hasRole(name2) {
		return false, nil
	}

	role1 := rm.createRole(name1)
	return role1.hasRole(name2, rm.maxHierarchyLevel), nil
}

// GetRoles gets the roles that a subject inherits.
// domain is a prefix to the roles.
func (rm *RoleManager) GetRoles(name string, domain ...string) ([]string, error) {
	if len(domain) == 1 {
		name = domain[0] + "::" + name
	} else if len(domain) > 1 {
		return nil, errors.New("error: domain should be 1 parameter")
	}

	if !rm.hasRole(name) {
		return nil, errors.New("error: name does not exist")
	}

	roles := rm.createRole(name).getRoles()
	if len(domain) == 1 {
		for i := range roles {
			roles[i] = roles[i][len(domain[0])+2:]
		}
	}
	return roles, nil
}

// GetUsers gets the users that inherits a subject.
// domain is an unreferenced parameter here, may be used in other implementations.
func (rm *RoleManager) GetUsers(name string, domain ...string) ([]string, error) {
	if !rm.hasRole(name) {
		return nil, errors.New("error: name does not exist")
	}

	names := []string{}
	for _, role := range rm.allRoles {
		if role.hasDirectRole(name) {
			names = append(names, role.name)
		}
	}
	return names, nil
}

// PrintRoles prints all the roles to log.
func (rm *RoleManager) PrintRoles() error {
	for _, role := range rm.allRoles {
		util.LogPrint(role.toString())
	}
	return nil
}

// Role represents the data structure for a role in RBAC.
type Role struct {
	name  string
	roles []*Role
}

func newRole(name string) *Role {
	r := Role{}
	r.name = name
	return &r
}

func (r *Role) addRole(role *Role) {
	for _, rr := range r.roles {
		if rr.name == role.name {
			return
		}
	}

	r.roles = append(r.roles, role)
}

func (r *Role) deleteRole(role *Role) {
	for i, rr := range r.roles {
		if rr.name == role.name {
			r.roles = append(r.roles[:i], r.roles[i+1:]...)
			return
		}
	}
}

func (r *Role) hasRole(name string, hierarchyLevel int) bool {
	if r.name == name {
		return true
	}

	if hierarchyLevel <= 0 {
		return false
	}

	for _, role := range r.roles {
		if role.hasRole(name, hierarchyLevel-1) {
			return true
		}
	}
	return false
}

func (r *Role) hasDirectRole(name string) bool {
	for _, role := range r.roles {
		if role.name == name {
			return true
		}
	}

	return false
}

func (r *Role) toString() string {
	names := ""
	for i, role := range r.roles {
		if i == 0 {
			names += role.name
		} else {
			names += ", " + role.name
		}
	}
	return r.name + " < " + names
}

func (r *Role) getRoles() []string {
	names := []string{}
	for _, role := range r.roles {
		names = append(names, role.name)
	}
	return names
}
<commit_msg>Fix default role manager concurrency<commit_after>// Copyright 2017 The casbin Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package defaultrolemanager

import (
	"errors"
	"sync"

	"github.com/casbin/casbin/rbac"
	"github.com/casbin/casbin/util"
)

type RoleManager struct {
	allRoles          *sync.Map
	maxHierarchyLevel int
}

// NewRoleManager is the constructor for creating an instance of the
// default RoleManager implementation.
func NewRoleManager(maxHierarchyLevel int) rbac.RoleManager {
	rm := RoleManager{}
	rm.allRoles = &sync.Map{}
	rm.maxHierarchyLevel = maxHierarchyLevel
	return &rm
}

func (rm *RoleManager) hasRole(name string) bool {
	_, ok := rm.allRoles.Load(name)
	return ok
}

func (rm *RoleManager) createRole(name string) *Role {
	role, _ := rm.allRoles.LoadOrStore(name, newRole(name))
	return role.(*Role)
}

// Clear clears all stored data and resets the role manager to the initial state.
func (rm *RoleManager) Clear() error {
	rm.allRoles = &sync.Map{}
	return nil
}

// AddLink adds the inheritance link between role: name1 and role: name2.
// aka role: name1 inherits role: name2.
// domain is a prefix to the roles.
func (rm *RoleManager) AddLink(name1 string, name2 string, domain ...string) error {
	if len(domain) == 1 {
		name1 = domain[0] + "::" + name1
		name2 = domain[0] + "::" + name2
	} else if len(domain) > 1 {
		return errors.New("error: domain should be 1 parameter")
	}

	role1 := rm.createRole(name1)
	role2 := rm.createRole(name2)
	role1.addRole(role2)
	return nil
}

// DeleteLink deletes the inheritance link between role: name1 and role: name2.
// aka role: name1 does not inherit role: name2 any more.
// domain is a prefix to the roles.
func (rm *RoleManager) DeleteLink(name1 string, name2 string, domain ...string) error {
	if len(domain) == 1 {
		name1 = domain[0] + "::" + name1
		name2 = domain[0] + "::" + name2
	} else if len(domain) > 1 {
		return errors.New("error: domain should be 1 parameter")
	}

	if !rm.hasRole(name1) || !rm.hasRole(name2) {
		return errors.New("error: name1 or name2 does not exist")
	}

	role1 := rm.createRole(name1)
	role2 := rm.createRole(name2)
	role1.deleteRole(role2)
	return nil
}

// HasLink determines whether role: name1 inherits role: name2.
// domain is a prefix to the roles.
func (rm *RoleManager) HasLink(name1 string, name2 string, domain ...string) (bool, error) {
	if len(domain) == 1 {
		name1 = domain[0] + "::" + name1
		name2 = domain[0] + "::" + name2
	} else if len(domain) > 1 {
		return false, errors.New("error: domain should be 1 parameter")
	}

	if name1 == name2 {
		return true, nil
	}

	if !rm.hasRole(name1) || !rm.hasRole(name2) {
		return false, nil
	}

	role1 := rm.createRole(name1)
	return role1.hasRole(name2, rm.maxHierarchyLevel), nil
}

// GetRoles gets the roles that a subject inherits.
// domain is a prefix to the roles.
func (rm *RoleManager) GetRoles(name string, domain ...string) ([]string, error) {
	if len(domain) == 1 {
		name = domain[0] + "::" + name
	} else if len(domain) > 1 {
		return nil, errors.New("error: domain should be 1 parameter")
	}

	if !rm.hasRole(name) {
		return nil, errors.New("error: name does not exist")
	}

	roles := rm.createRole(name).getRoles()
	if len(domain) == 1 {
		for i := range roles {
			roles[i] = roles[i][len(domain[0])+2:]
		}
	}
	return roles, nil
}

// GetUsers gets the users that inherits a subject.
// domain is an unreferenced parameter here, may be used in other implementations.
func (rm *RoleManager) GetUsers(name string, domain ...string) ([]string, error) {
	if !rm.hasRole(name) {
		return nil, errors.New("error: name does not exist")
	}

	names := []string{}
	rm.allRoles.Range(func(_, value interface{}) bool {
		role := value.(*Role)
		if role.hasDirectRole(name) {
			names = append(names, role.name)
		}
		return true
	})
	return names, nil
}

// PrintRoles prints all the roles to log.
func (rm *RoleManager) PrintRoles() error {
	rm.allRoles.Range(func(_, value interface{}) bool {
		util.LogPrint(value.(*Role).toString())
		return true
	})
	return nil
}

// Role represents the data structure for a role in RBAC.
type Role struct {
	name  string
	roles []*Role
}

func newRole(name string) *Role {
	r := Role{}
	r.name = name
	return &r
}

func (r *Role) addRole(role *Role) {
	for _, rr := range r.roles {
		if rr.name == role.name {
			return
		}
	}

	r.roles = append(r.roles, role)
}

func (r *Role) deleteRole(role *Role) {
	for i, rr := range r.roles {
		if rr.name == role.name {
			r.roles = append(r.roles[:i], r.roles[i+1:]...)
			return
		}
	}
}

func (r *Role) hasRole(name string, hierarchyLevel int) bool {
	if r.name == name {
		return true
	}

	if hierarchyLevel <= 0 {
		return false
	}

	for _, role := range r.roles {
		if role.hasRole(name, hierarchyLevel-1) {
			return true
		}
	}
	return false
}

func (r *Role) hasDirectRole(name string) bool {
	for _, role := range r.roles {
		if role.name == name {
			return true
		}
	}

	return false
}

func (r *Role) toString() string {
	names := ""
	for i, role := range r.roles {
		if i == 0 {
			names += role.name
		} else {
			names += ", " + role.name
		}
	}
	return r.name + " < " + names
}

func (r *Role) getRoles() []string {
	names := []string{}
	for _, role := range r.roles {
		names = append(names, role.name)
	}
	return names
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"http"
	"opts"
	"os"
	"path"
	//"template"
)

var port = opts.Option("p", "port", "the port to use", "8080")
var blogroot = opts.Option("r",
	"blogroot",
	"the root directory for blog data",
	"/usr/share/obsidian")

func main() {
	// option setup
	opts.Description("lightweight http blog server")
	// parse and handle options
	opts.Parse()

	fmt.Fprintf(os.Stderr, "Reading data...\n")
	readData()

	fmt.Fprintf(os.Stderr, "Serving!\n")
	// set up the extra servers
	http.HandleFunc("/test", TestServer)
	http.HandleFunc("/", NotFoundServer)
	// start the server
	err := http.ListenAndServe(":"+*port, nil)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", err.String())
	}
}

// The various templates.
var (
	genTemplate      string
	adminTemplate    string
	indexTemplate    string
	postTemplate     string
	tagTemplate      string
	categoryTemplate string
)

func readTemplate(name string) string {
	templateDirectory := path.Join(*blogroot, "templates")
	return readFile(path.Join(templateDirectory, name))
}

func readTemplates() {
	// read the templates
	genTemplate = readTemplate("gen.html")
	adminTemplate = readTemplate("admin.html")
	indexTemplate = readTemplate("index.html")
	postTemplate = readTemplate("post.html")
	tagTemplate = readTemplate("tag.html")
	categoryTemplate = readTemplate("category.html")
}

func readData() {
	readTemplates()
}

func TestServer(c *http.Conn, req *http.Request) {
	fmt.Fprintf(c, "Hello, world!\n")
}

func NotFoundServer(c *http.Conn, req *http.Request) {
	c.WriteHeader(404)
	fmt.Fprintf(c, "404 not found\n")
}
<commit_msg>reading posts<commit_after>package main

import (
	"container/vector"
	"fmt"
	"http"
	"opts"
	"os"
	"path"
	"strings"
	"template"
)

var port = opts.Option("p", "port", "the port to use", "8080")
var blogroot = opts.Option("r",
	"blogroot",
	"the root directory for blog data",
	"/usr/share/obsidian")

func main() {
	// option setup
	opts.Description("lightweight http blog server")
	// parse and handle options
	opts.Parse()

	fmt.Fprintf(os.Stderr, "Reading data...\n")
	readTemplates()
	readPosts()

	fmt.Fprintf(os.Stderr, "Compiling site...\n")

	fmt.Fprintf(os.Stderr, "Serving!\n")
	// set up the extra servers
	http.HandleFunc("/test", TestServer)
	http.HandleFunc("/", NotFoundServer)
	// start the server
	err := http.ListenAndServe(":"+*port, nil)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", err.String())
	}
}

// The various templates.
var (
	genTemplate      *template.Template
	adminTemplate    *template.Template
	indexTemplate    *template.Template
	postTemplate     *template.Template
	excerptTemplate  *template.Template
	tagTemplate      *template.Template
	categoryTemplate *template.Template
	notFoundTemplate *template.Template
)

func readTemplate(name string) *template.Template {
	templateDirectory := path.Join(*blogroot, "templates")
	templatePath := path.Join(templateDirectory, name)
	templateText := readFile(templatePath)
	template, err := template.Parse(templateText, nil)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", err.String())
		os.Exit(1)
	}
	return template
}

func readTemplates() {
	// read the templates
	genTemplate = readTemplate("gen.html")
	adminTemplate = readTemplate("admin.html")
	indexTemplate = readTemplate("index.html")
	postTemplate = readTemplate("post.html")
	tagTemplate = readTemplate("tag.html")
	categoryTemplate = readTemplate("category.html")
	excerptTemplate = readTemplate("excerpt.html")
	notFoundTemplate = readTemplate("404.html")
}

type Post struct {
	title string
	category string
	tags vector.StringVector
	content string
}

var posts = map[string] *Post{}

type PostVisitor struct {
	root string
}

func (v PostVisitor) VisitDir(path string, f *os.FileInfo) bool {
	return true
}

func readPost(content string) *Post {
	post := &Post{}
	return post
}

func (v PostVisitor) VisitFile(path string, f *os.FileInfo) {
	relPath := strings.Replace(path, v.root, "", 1)
	// read in the posts
	posts[relPath] = readPost(readFile(path))
}

func readPosts() {
	postDir := path.Join(*blogroot, "posts")
	walkDir(postDir, PostVisitor{postDir})
}

func TestServer(c *http.Conn, req *http.Request) {
	fmt.Fprintf(c, "Hello, world!\n")
}

func NotFoundServer(c *http.Conn, req *http.Request) {
	c.WriteHeader(404)
	fmt.Fprintf(c, "404 not found\n")
}
<|endoftext|>