text:
How can store complex entity into database with ozzo properly?

If I populate Actor with Actor and Person attributes, how can I store (INSERT, UPDATE) it into db tables actor and person with the same structure?
type Actor struct{
	Id         int64
	deleted    bool
	ParsonId   int64
	Alias      string
	CreateDate string
	UpdatedAt  time.Time
	Person
}

type Person struct {
	Id 	       int64
	LastName   string
	FirstName  string
	Patronymic string
	Birthday   string
	Gender     string
	AvatarUrl  string
}

...or I can create:
type Actor struct{
    Id         int64
    deleted    bool
    ParsonId   int64
    Alias      string
    CreateDate string
    UpdatedAt  time.Time
    Person Person
}

This is not supported as ozzo-dbx is not an ORM and does not support relational mapping.
You would need to manually call Insert/Update for each model.

Thanks!

How to populate objects properly in this case (struct has the same field names and I need only Actor CreatedAt and UpdatedAt fields)? Or it's a wrong way at all?
and this expression LeftJoin("person", dbx.NewExp("`person`.`id` = `actor`.`person_id`")). is correct?
type Actor struct{
	Id int
	deleted bool
	PersonId int
	Alias string
	CreatedAt time.Time
	UpdatedAt time.Time
        Person
}

type Person struct {
	Id 	   int
	UserId 	   int
	LastName   string
	FirstName  string
	Patronymic string
	Birthday   string
	Gender     string
	AvatarUrl  string
	CreatedAt time.Time
	UpdatedAt time.Time
}

func (m *Actor) GetAll(from, limit int64) []Actor {
	var actors []Actor
	q := db.Select().
		LeftJoin("person", dbx.NewExp("`person`.`id` = `actor`.`person_id`")).
		Limit(limit).
		Offset(from)

	err := q.All(&actors)
	if err != nil {
		println("Exec err:", err.Error())
	}
	return actors
}

If Person is in the last, its Id field will be masked by Actor.Id when being populated, unless you alias the selected column as person.id.
In general, dbx is not an ORM. Each model should usually be associated with a single table. If you want to handle the relational case like your example, I would avoid JOIN and use two single-table SELECTs.

Did you mean: SELECT FROM `actor` LIMIT, then SELECT from `person` WHERE actor.person_id = person.id each row in cycle?

Yes. The second query should also filter according to the selected actor IDs from the first query result.

Whether it will be much slower?

Is this correct in my case?
You say:

If Person is in the last, its Id field will be masked by Actor.Id when being populated, unless you alias the selected column as person.id.

Query SQL: SELECT `actor`.`id`, `alias`, `actor`.`created_at`, `actor`.`updated_at`, `last_name`, `first_name`, `patronymic` FROM `actor` LEFT JOIN `person` ON `person`.`id` = `actor`.`person_id` LIMIT 5

And AvatarUrl populated as expected...

SELECT actor.id, alias, actor.created_at, actor.updated_at, last_name, first_name, patronymic, actor.avatar_urlFROMactorLEFT JOINpersonONperson.id=actor.person_id LIMIT 5

There are two ways.

Embed Person as an anonymous field in Actor (as you are already doing). For Person.Id field, define a struct tag to associate it with a db column named person_id.

Embed Person in Actor as a non-anonymous field type Actor struct {Person Person, ...}. And then SELECT person.id AS "person.id"...

Yes it worked partly (1 way), but what about if I want to SELECT data from Person with separate query? And what about CreatedAt and UpdatedAt fields?

Not good, but it usable...
type Actor struct{
	Id int
	deleted bool
	PersonId int
	Alias string
	/*AvatarUrl string
	CreatedAt time.Time
	UpdatedAt time.Time*/
	Person
}

It would be nice to come up with some interesting solution ...)

If you are using the first approach, you may also tag the anonymous Person field as person and then do SELECT person.id AS "person.id"...

Ok, I will try this now.
One question more...
type User struct {
	Id        int
	UserName  string
	CreatedAt time.Time
	UpdatedAt time.Time
}

func (u *User) BeforeInsert(){
	u.CreatedAt = time.Now()
	u.UpdatedAt= u.CreatedAt
}

func (u *User) BeforeUpdate(){
	u.UpdatedAt = time.Now()
}

func (u *User) Create() error{
	u.BeforeInsert()
	err:= db.Model(u).Insert()
	if err != nil{
		println("Exec err:", err.Error())
	}
	return err
}

Why time is not quoted?
INSERT INTO `user` (`created_at`, `updated_at`, `user_name`) VALUES (2016-08-10 18:09:31.1670022 +0300 MSK, 2016-08-10 18:09:31.1670022 +0300 MSK, '')

If you are using the first approach, you may also tag the anonymous Person field as person and then do SELECT person.id AS "person.id"...
Yes! This is the best solution now.

The SQL you see is only for logging purpose. It is not the actual SQL being executed.
I will add a fix for this.

The SQL you see is only for logging purpose. It is not the actual SQL being executed.
I will add a fix for this.

Ok! But I has a error when try inserting by my app...
Thanks a lot!

what error?

While not fully understand ... (
2016/08/10 18:31:37 http: TLS handshake error from 127.0.0.1:2356: EOF
[mysql] 2016/08/10 18:37:16 packets.go:124: write tcp 127.0.0.1:2359->127.0.0.1:3306: wsasend: An established connection was aborted by the software in your host machine.
[mysql] 2016/08/10 18:37:16 packets.go:124: write tcp 127.0.0.1:2359->127.0.0.1:3306: wsasend: An established connection was aborted by the software in your host machine.
2016-08-10T18:37:16+03:00 [Info][app] [3.00ms] Query SQL: SELECT `actor`.`id`, `alias`, `actor`.`created_at`, `actor`.`updated_at`, `last_name` AS `person.last_name`, `first_name` AS `person.first_name`, `patronymic` AS `person.patronymic`, `actor`.`avatar_url`, `person`.`id` AS `person.id`, `birthday` AS `person.birthday`, `gender` AS `person.gender` FROM `actor` LEFT JOIN `person` ON `person`.`id` = `actor`.`person_id` LIMIT 0
2016-08-10T18:37:16+03:00 [Info][app] [0.00ms] Query SQL: SELECT count(*) FROM `actor`
2016-08-10T18:37:16+03:00 [Info][app.webserver] [127.0.0.1] [3.002ms] GET /api/v1/actor/pagination HTTP/2.0 200 25
2016-08-10T18:37:17+03:00 [Info][app.webserver] [127.0.0.1] [0.501ms] GET /app/private/base/actor/new.html HTTP/2.0 200 4039
2016-08-10T18:37:42+03:00 [Info][app] [4.00ms] Execute SQL: INSERT INTO `user` (`created_at`, `updated_at`, `user_name`) VALUES (2016-08-10 18:37:42.6526322 +0300 MSK, 2016-08-10 18:37:42.6526322 +0300 MSK, '')
Exec err: Error 1452: Cannot add or update a child row: a foreign key constraint fails (`inframe`.`person`, CONSTRAINT `person_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON UPDATE CASCADE)
2016-08-10T18:37:42+03:00 [Info][app] [1.50ms] Execute SQL: INSERT INTO `person` (`avatar_url`, `birthday`, `created_at`, `first_name`, `gender`, `id`, `last_name`, `patronymic`, `updated_at`, `user_id`) VALUES ('', '', 2016-08-10 18:37:42.6526322 +0300 MSK, '', '', 9, '', '', 2016-08-10 18:37:42.6526322 +0300 MSK, 0)
Exec err: Error 1054: Unknown column 'person.avatar_url' in 'field list'
2016-08-10T18:37:42+03:00 [Info][app] [0.00ms] Execute SQL: INSERT INTO `actor` (`alias`, `person`.`avatar_url`, `person`.`birthday`, `person`.`created_at`, `person`.`first_name`, `person`.`gender`, `person`.`last_name`, `person`.`patronymic`, `person`.`updated_at`, `person`.`user_id`, `person_id`) VALUES ('', '', '2012-12-31T21:00:00.000Z', 0001-01-01 00:00:00 +0000 UTC, 'test', 'male', 'test', 'test', 0001-01-01 00:00:00 +0000 UTC, 0, 9)
2016-08-10T18:37:42+03:00 [Info][app.webserver] Error 1054: Unknown column 'person.avatar_url' in 'field list'

Seems there are a few errors. Please try to isolate them first.

SELECT actor.id, alias, actor.created_at, actor.updated_at, last_name AS person.last_name, first_name AS person.first_name, patronymic AS person.patronymic, actor.avatar_url, person.id AS person.id, birthday AS person.birthday, gender AS person.gender FROM actor LEFT JOIN person ON person.id = actor.person_id LIMIT 0: why limit 0 here?
Exec err: Error 1452: Cannot add or update a child row: a foreign key constraint fails (inframe.person, CONSTRAINT person_ibfk_1 FOREIGN KEY (user_id) REFERENCES user (id) ON UPDATE CASCADE)
Exec err: Error 1452: Cannot add or update a child row: a foreign key constraint fails (inframe.person, CONSTRAINT person_ibfk_1 FOREIGN KEY (user_id) REFERENCES user (id) ON UPDATE CASCADE)

Not very convenient, first I get an error from
err := db.Model(m).Insert()
	if err != nil {
		fmt.Println("Exec err:", err.Error())
	}

Ang then from ozzo-log))
I found first! )
person.id = user.id )) changed to person.UserId = user.Id

why limit 0 here?

it's a bug in my Angular app. Thanks!

Now there was one mistake 'person.avatar_url'
2016-08-10T19:33:53+03:00 [Info][app] [3.50ms] Execute SQL: INSERT INTO `user` (`created_at`, `updated_at`, `user_name`) VALUES (2016-08-10 19:33:53.5873129 +0300 MSK, 2016-08-10 19:33:53.5873129 +0300 MSK, '')
2016-08-10T19:33:53+03:00 [Info][app] [1.50ms] Execute SQL: INSERT INTO `person` (`avatar_url`, `birthday`, `created_at`, `first_name`, `gender`, `last_name`, `patronymic`, `updated_at`, `user_id`) VALUES ('', '', 2016-08-10 19:33:53.5873129 +0300 MSK, '', '', '', '', 2016-08-10 19:33:53.5873129 +0300 MSK, 13)
Exec err: Error 1054: Unknown column 'person.avatar_url' in 'field list'
2016-08-10T19:33:53+03:00 [Info][app] [0.50ms] Execute SQL: INSERT INTO `actor` (`alias`, `person`.`avatar_url`, `person`.`birthday`, `person`.`created_at`, `person`.`first_name`, `person`.`gender`, `person`.`last_name`, `person`.`patronymic`, `person`.`updated_at`, `person`.`user_id`, `person_id`) VALUES ('', '', '2016-08-03T21:00:00.000Z', 0001-01-01 00:00:00 +0000 UTC, 'test3', 'male', 'test3', 'test3', 0001-01-01 00:00:00 +0000 UTC, 0, 7)
2016-08-10T19:33:53+03:00 [Info][app.webserver] Error 1054: Unknown column 'person.avatar_url' in 'field list'
2016-08-10T19:33:53+03:00 [Info][app.webserver] [127.0.0.1] [6.504ms] POST /api/v1/actor/save HTTP/2.0 500 89

And if I change to:
type Actor struct{
	Id int
	deleted bool
	PersonId int
	Alias string
	AvatarUrl string
	CreatedAt time.Time
	UpdatedAt time.Time
	Person `db:"person"`
}

func (m *Actor) Create() error {
	m.beforeInsert()
	err := db.Model(m).Insert("person_id", "avatar_url", "alias", "created_at", "updated_at")
	if err != nil {
		fmt.Println("Exec err:", err.Error())
	}
	return err
}

Error is:
Exec err: Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DEFAULT VALUES' at line 1
2016-08-10T20:02:55+03:00 [Info][app] [1.00ms] Execute SQL: INSERT INTO `actor` DEFAULT VALUES
2016-08-10T20:02:55+03:00 [Info][app.webserver] Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DEFAULT VALUES' at line 1

db.Model(m).Insert(...) should list the struct field names, not db column names.
The error shows you don't have a table column named avatar_url.

Yes! But how can I prevent this?
2016-08-10T22:37:57+03:00 [Info][app] [2.50ms] Execute SQL: INSERT INTO `user` (`created_at`, `updated_at`, `user_name`) VALUES (2016-08-10 22:37:57.4409857 +0300 MSK, 2016-08-10 22:37:57.4409857 +0300 MSK, '')
2016-08-10T22:37:57+03:00 [Info][app] [1.00ms] Execute SQL: INSERT INTO `person` (`avatar_url`, `birthday`, `created_at`, `first_name`, `gender`, `last_name`, `patronymic`, `updated_at`, `user_id`) VALUES ('', '2016-08-09T21:00:00.000Z', 2016-08-10 22:37:57.4409857 +0300 MSK, 'test10', 'male', 'test10', 'test10', 2016-08-10 22:37:57.4409857 +0300 MSK, 22)
Exec err: Error 1054: Unknown column 'person.avatar_url' in 'field list'
2016-08-10T22:37:57+03:00 [Info][app] [0.00ms] Execute SQL: INSERT INTO `actor` (`alias`, `person`.`avatar_url`, `person`.`created_at`, `person`.`updated_at`, `person_id`) VALUES ('', '', 0001-01-01 00:00:00 +0000 UTC, 0001-01-01 00:00:00 +0000 UTC, 16)
2016-08-10T22:37:57+03:00 [Info][app.webserver] Error 1054: Unknown column 'person.avatar_url' in 'field list'

type Actor struct{
	Id int
	deleted bool
	PersonId int
	Alias string
	AvatarUrl string
	CreatedAt time.Time
	UpdatedAt time.Time
	Person `db:"person"`
}

func (m *Actor) Create() error {
	/*tx, _ := db.Begin()*/
	m.beforeInsert()
	err := db.Model(m).Insert("PersonId", "AvatarUrl", "Alias", "CreatedAt", "UpdatedAt")
	if err != nil {
		fmt.Println("Exec err:", err.Error())
	}
	return err
}

Are you saying the line     err := db.Model(m).Insert("PersonId", "AvatarUrl", "Alias", "CreatedAt", "UpdatedAt")
executes the following SQL?
INSERT INTO `actor` (`alias`, `person`.`avatar_url`, `person`.`created_at`, `person`.`updated_at`, `person_id`) VALUES ('', '', 0001-01-01 00:00:00 +0000 UTC, 0001-01-01 00:00:00 +0000 UTC, 16)

I want to save only Actor fields without Person lields...

I tried this construction:
err := db.Model(m).Exclude("Person").Insert()
No changes...(

I think we need to change logic of this function. Add only columns not present into exclude []string.
And then use like db.Model(model).Select().Exclude("Person"). Now first we create all columns and then remove excluded from map.
// columns returns the struct field values indexed by their corresponding DB column names.
func (s *structValue) columns(include, exclude []string) map[string]interface{} {
	v := map[string]interface{}{}
	if len(include) == 0 {
		for _, fi := range s.nameMap {
			v[fi.dbName] = fi.getValue(s.value)
		}
	} else {
		for _, attr := range include {
			if fi, ok := s.nameMap[attr]; ok {
				v[fi.dbName] = fi.getValue(s.value)
			}
		}
	}
	if len(exclude) > 0 {
		for _, name := range exclude {
			if fi, ok := s.nameMap[name]; ok {
				delete(v, fi.dbName)
			}
		}
	}
	return v
}

Sorry ( This is not possible at this place(
&{structInfo:0xc0423d8c90 value:{typ:0x8ef0e0 ptr:0xc042000400 flag:409} tableName:actor}
map[Birthday:0xc042237980 Gender:0xc0422379c0 Id:0xc042237840 Alias:0xc042237780 CreatedAt:0xc042237a40 UpdatedAt:0xc042237a80 LastName:0xc0422378c0 PersonId:0xc042237740 UserId:0xc042237880 FirstName:0xc042237900 Patronymic:0xc042237940 AvatarUrl:0xc042237a00]

I see the problem: when populating Actor, you want to populate Person as well by tagging it with a prefix "person."; when inserting Actor, you want to skip Person - but Person and Actor have some fields with the same name. I do not have a good solution for this problem now, but I will think about it.

There is a blessing in disguise, as they say in Russia ("нет худа без добра")!
But now I know how ozzo-dbx works inside)))

I think the best solution is to tag fields only for reading and only for writing separately.
At moment we have solution for change column name Person `db:"person"`  and Person `db:"-"`  for disable reading and writing.
It will be good idea to have solution like this: Person `db:"<"`  field only for reading and Person `db:">"`  field only for writing.
I don't know is it possible?
In my opinion it maybe possible at stage where we creating table structure:
func getStructInfo(a reflect.Type, mapper FieldMapFunc) *structInfo {
	muStructInfoMap.Lock()
	defer muStructInfoMap.Unlock()

	key := structInfoMapKey{a, reflect.ValueOf(mapper)}
	if si, ok := structInfoMap[key]; ok {
		return si
	}

	si := &structInfo{
		nameMap:   map[string]*fieldInfo{},
		dbNameMap: map[string]*fieldInfo{},
	}
	si.build(a, make([]int, 0), "", "", mapper)
	structInfoMap[key] = si

	return si
}

func (si *structInfo) build(a reflect.Type, path []int, namePrefix, dbNamePrefix string, mapper FieldMapFunc) {
	n := a.NumField()
	for i := 0; i < n; i++ {
		field := a.Field(i)
		tag := field.Tag.Get(DbTag)

		// only handle anonymous or exported fields
		if !field.Anonymous && field.PkgPath != "" || tag == "-" {
			continue
		}

		path2 := make([]int, len(path), len(path)+1)
		copy(path2, path)
		path2 = append(path2, i)

		ft := field.Type
		if ft.Kind() == reflect.Ptr {
			ft = ft.Elem()
		}

		name := field.Name
		dbName, isPK := parseTag(tag)
		if dbName == "" && !field.Anonymous {
			if mapper != nil {
				dbName = mapper(field.Name)
			} else {
				dbName = field.Name
			}
		}
		if field.Anonymous {
			name = ""
		}

		if isNestedStruct(ft) {
			// dive into non-scanner struct
			si.build(ft, path2, concat(namePrefix, name), concat(dbNamePrefix, dbName), mapper)
		} else if dbName != "" {
			// non-anonymous scanner or struct field
			fi := &fieldInfo{
				name:   concat(namePrefix, name),
				dbName: concat(dbNamePrefix, dbName),
				path:   path2,
			}
			si.nameMap[fi.name] = fi
			si.dbNameMap[fi.dbName] = fi
			if isPK {
				si.pkNames = append(si.pkNames, fi.name)
			}
		}
	}
	if len(si.pkNames) == 0 {
		if _, ok := si.nameMap["ID"]; ok {
			si.pkNames = append(si.pkNames, "ID")
		} else if _, ok := si.nameMap["Id"]; ok {
			si.pkNames = append(si.pkNames, "Id")
		}
	}
}

And then in the q.model.columns(attrs, q.exclude) we can scan fields structure for labels only "for reading" and "only for writing" and take only necessary columns. Is it possible?
func (q *ModelQuery) Insert(attrs ...string) error {
	if q.lastError != nil {
		return q.lastError
	}
	cols := q.model.columns(attrs, q.exclude)
	pkName := ""
	for name, value := range q.model.pk() {
		if isAutoInc(value) {
			delete(cols, name)
			pkName = name
			break
		}
	}

	if pkName == "" {
		_, err := q.builder.Insert(q.model.tableName, Params(cols)).Execute()
		return err
	}

	// handle auto-incremental PK
	query := q.builder.Insert(q.model.tableName, Params(cols))
	pkValue, err := insertAndReturnPK(q.db, query, pkName)
	if err != nil {
		return err
	}
	indirect(q.model.dbNameMap[pkName].getField(q.model.value)).SetInt(pkValue)
	return nil
}

Or may be through change functioning of exclude statment data.Model(m).Exclude("Person").Insert()

It's possible, but I'm afraid this introduces more complexity to the usage.
The real problem here is that you are trying to use the same struct for both reading and writing purposes. It can be solved in the following way:
type Actor struct {...}  // do not embed Person here
type Person struct {...}
type ActorPerson struct {
    Actor
    Person  `db:"person"`
}

You use Actor and Person for writing purpose (or reading purpose if you do not need the relational data). And you use ActorPerson for reading purpose when you want to have the relational data ready.

Thank you! Interesting idea)

authors: kolkov qiangxue

repo: go-ozzo/ozzo-dbx


text:
day / time validation

Suggest adding Date / Time validation rules, with a way to specify the format of the date, perhaps copy the https://golang.org/pkg/time/#Time.Format layout.

Are you looking for a string validator? Will regex rule work for you?

Or are you looking for a rule that validates the range of a date?

I suppose a regex can work.. something along these lines http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/  .. lots of other versions of a date regex about as well.

source: gharchive/issue

authors: dwoske qiangxue

repo: go-ozzo/ozzo-validation

license: mit

license_type: permissive

license_source: bigquery


text:
maybe recvICMP func return packet with a slice byte array?

do U think "recv <- &packet{bytes: bytes[:n], nbytes: n, ttl: ttl}" replace of "recv <- &packet{bytes: bytes, nbytes: n, ttl: ttl}" will be better?

it might, any reason in particular you'd like to make that change?

Arguably these should always be the same and we should return an error if n != len(bytes).

On second thoughts, no they shouldn't. That method will receive other kinds of ICMP messages not necessarily sent by the Pinger. For example someone could ping an endpoint using the UNIX ping command with a size of 56 and also ping it using our Go Pinger with a size of 1472. We discard the packets from the UNIX ping command because their ID and tracker don't match but we still need to deserialise them correctly so we can pass them to the (*Pinger).processPacket(*packet) method.
Also this would be entirely resolved by #138 so I shall close in favour of merging that.

authors: CHTJonas lstaasRM sparrc

repo: go-ping/ping

license: MIT

license_source: github-api


text:
Use covermode atomic with -race

I believe the current default of -covermode=count with -race can cause race conditions. See this gist for an example.
https://gist.github.com/mmcloughlin/6ec7d19a354ff2869350432f37628663

Well @mmcloughlin that is interesting, your example suggests a race condition with go test itself with count covermode.
Is there a more verbose data race message? and have you tried running just go test -race on your program to verify no race conditions exist?(shouldn't be but....)

See report.md in the gist. With atomic there are no errors.
If this is a real problem and not my mistake, perhaps go test should warn. It's not just a problem with overalls.
Excerpt from go test -h
	-covermode set,count,atomic
	    Set the mode for coverage analysis for the package[s]
	    being tested. The default is "set" unless -race is enabled,
	    in which case it is "atomic".
	    The values:
		set: bool: does this statement run?
		count: int: how many times does this statement run?
		atomic: int: count, but correct in multithreaded tests;
			significantly more expensive.
	    Sets -cover.

As far as I understand, test coverage relies on code modification to insert counter variables. I believe there is a way to retain the modified code, I've done it before and forgotten the magic incantation. Let me research this and get back to you. That would allow us to prove the race is in the  coverage code.

Thanks @mmcloughlin your help in tracking this issue is appreciated :)
yes I did read the Gist, I just though the data race warning may have been truncated, I ran:
go test -v -race -covermode=count
and got
=== RUN   TestGreeting
==================
WARNING: DATA RACE
Read at 0x00000068e9f0 by goroutine 7:
  github.com/joeybloggs/proof-of-concept/coverage-race.Greeting()
      github.com/joeybloggs/proof-of-concept/coverage-race/_test/_obj_test/overallsrace.go:6 +0x47
  github.com/joeybloggs/proof-of-concept/coverage-race.TestGreeting.func1()
      /home/joeybloggs/go/src/github.com/joeybloggs/proof-of-concept/coverage-race/overallsrace_test.go:14 +0x47

Previous write at 0x00000068e9f0 by goroutine 16:
  github.com/joeybloggs/proof-of-concept/coverage-race.Greeting()
      github.com/joeybloggs/proof-of-concept/coverage-race/_test/_obj_test/overallsrace.go:6 +0x61
  github.com/joeybloggs/proof-of-concept/coverage-race.TestGreeting.func1()
      /home/joeybloggs/go/src/github.com/joeybloggs/proof-of-concept/coverage-race/overallsrace_test.go:14 +0x47

Goroutine 7 (running) created at:
  github.com/joeybloggs/proof-of-concept/coverage-race.TestGreeting()
      /home/joeybloggs/go/src/github.com/joeybloggs/proof-of-concept/coverage-race/overallsrace_test.go:19 +0xbc
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:657 +0x107

Goroutine 16 (finished) created at:
  github.com/joeybloggs/proof-of-concept/coverage-race.TestGreeting()
      /home/joeybloggs/go/src/github.com/joeybloggs/proof-of-concept/coverage-race/overallsrace_test.go:19 +0xbc
  testing.tRunner()
      /usr/local/go/src/testing/testing.go:657 +0x107
==================
--- FAIL: TestGreeting (0.00s)
	testing.go:610: race detected during execution of test
FAIL
coverage: 100.0% of statements
exit status 1
FAIL	github.com/joeybloggs/proof-of-concept/coverage-race	0.005s

I dug up the incantation to generate the coverage code. I've added it to the gist, so you can now see the offending line. The data race trace refers to overallsrace.go:6which is actually line 6 of overallsrace_cover_count.goin the gist.
https://gist.github.com/mmcloughlin/6ec7d19a354ff2869350432f37628663#file-overallsrace_cover_count-go-L6
I'll copy the whole thing here
package overallsrace

import "fmt"

func Greeting(who string) string {
	GoCover.Count[0]++
	return fmt.Sprintf("Hello %s!", who)
}

var GoCover = struct {
	Count     [1]uint32
	Pos       [3 * 1]uint32
	NumStmt   [1]uint16
} {
	Pos: [3 * 1]uint32{
		5, 7, 0x20022, // [0]
	},
	NumStmt: [1]uint16{
		1, // 0
	},
}

The line GoCover.Count[0]++ has a race.
This was generated with
go tool cover -mode=count overallsrace.go

Thanks @mmcloughlin
First off I would love for you to share your incantaion if possible, I'd love to explore that further on my own :)
What to do now though? go test clearly states atomic: int: count, but correct in multithreaded tests; significantly more expensive. and since this is a multi-threaded test, atomic should really be used rather than count

I hid it at the end of the last comment :) The files in the gist were generated with
go tool cover -mode=count overallsrace.go > overallsrace_cover_count.go
go tool cover -mode=atomic overallsrace.go > overallsrace_cover_atomic.go

Two subtly different options I'd suggest:

overalls looks for -race in the extra args to go test and if it finds it uses atomic instead
overalls itself has a -race flag which causes -race to be passed to go test and also uses atomic

Unsurprisingly this has come up before. I personally think go test should warn or error on -race -covermode=count but the go maintainers seem to think it's working as intended.
golang/go#12118
golang/go#12513
golang/go#19455
In the absence of a fix at the go test level, I still think it would be helpful if overalls stoped its users shooting themselves in the foot.

@mmcloughlin
I still have to continue to allow for people to use count as I have a few people with very large code bases using this library and performance is a concern. There is, after all, a reason the two distinct modes exist.
I think it is entirely appropriate that when cover mode count is being used with the -race argument that overalls produces a warning stating something to the affect of:
WARNING: when using coverprofile=count and the -race flag there is the potential for race
conditions to be reported from the coverage generated code when your tests contain
multithreaded logic; in which case coverprofile=atomic should be used.

let me know what you think :)
If someone can prove to me that there is little to no difference between count and atomic performance wise, I would prefer to just switch the coverprofile to atomic behind the scenes and call it a day.

I see why you might want to maintain behavior for backward compatibility. It's safer.
I think you'll want s/coverprofile/covermode/ in your warning message.
As a counterpoint, I'm not sure why anyone would ever want to do this. In my understanding

If you have any parallel code in your tests, -race will find a race when -covermode=count
If you don't have any parallel code in your tests, why are you using -race?

And to your other question, I'm sure there is a decent performance hit for atomic adds everywhere.

Actually my claim above is wrong:

If you have any parallel code in your tests, -race will find a race when -covermode=count

Probably more correct to say some common patterns in parallel code will trigger race conditions.
So yeah... warning sounds good to me.

Sounds good, I'll make that change this week some time.
Thanks for all your helps and suggestions!
On Wed, 26 Apr 2017, 4:47 pm Michael McLoughlin, notifications@github.com
wrote:

I see why you might want to maintain behavior for backward compatibility.
It's safer.
I think you'll want s/coverprofile/covermode/ in your warning message.
As a counterpoint, I'm not sure why anyone would ever want to do this. In
my understanding

If you have any parallel code in your tests, -race will find a
race when -covermode=count
If you don't have any parallel code in your tests, why are you using
-race?

And to your other question, I'm sure there is a decent performance hit for
atomic adds everywhere.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/go-playground/overalls/issues/19#issuecomment-297536504,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AHsdE6OkVEZz36xj-CaSaeN35eQKg-rpks5rz61-gaJpZM4NIW4p
.

--
Thanks,
Dean Karn

authors: joeybloggs mmcloughlin

repo: go-playground/overalls


text:
version 6.15.3+ is not usable with Go modules

I'm opening a new issue, because the problem is slightly different.
Before v6.15.2, the repository didn't use Go module, but it was usable in a project using Go modules.
Since v6.15.3, the repository contains a go.mod file that doesn't respect the Go module rules.
Since Go 1.13, the Go module rules are stricter.
You can't install anymore v6.15.3 and v6.15.4 with Go 1.13 (FYI it will be released very soon)
I've opened an issue about this https://github.com/golang/go/issues/34005 and they confirmed that the issue is on go-redis side.
I see a simple solution: remove entirely the Go module support from v6, and release a new tag v6.15.5.
It seems that v7 is using the Go module correctly, but it's still in beta.
WDYT ?

Works for me. Could you send a PR to the v6 branch?

Or maybe it's caused by the new go 1.13 line in go.mod, I don't know.
But anyway, v6 is not compatible with Go module, so we should remove go.mod.
I'll send a PR.

authors: pierrre vmihailenco

repo: go-redis/redis


text:
Solve Windows-related issues from #136

Based on my comments in #136 .
With these changes, make test-dc runs seamlessly on Windows.
If the patch is ok I can also author Windows-specific instructions for CONTRIBUTING.md

Thanks a lot!

source: gharchive/pull-request

authors: AlekSi AlekseyMartynov

repo: go-reform/reform


text:
Database architectures documentation

Your documentation about the different database architectures is wrong, I invite you to visit: https://learn.microsoft.com/en-us/azure/azure-sql/database/saas-tenancy-app-design- patterns?view=azuresql
Regards

Actually the pictures of my documentation are adapted from this link, and I already quote it as reference in https://github.com/go-saas/saas/blob/main/README.md#references
The shared means Catalog from the original one
The shared database may store more information then the catalog from the host side.
Would you please point out which part of the documentation is wrong or misunderstanding?

authors: Goxiaoy TebanHB

repo: go-saas/saas


text:
GetCommits can exclude commits in certain merge scenarios

Given a commit history such as:

When attempting to perform a semantic release once featureB is merged, the result is:
[go-semantic-release]: ci-condition plugin: default@1.2.2
[go-semantic-release]: provider plugin: GitHub@1.5.0
[go-semantic-release]: getting default branch...
[go-semantic-release]: found default branch: master
[go-semantic-release]: repo is private
[go-semantic-release]: found current branch: master
[go-semantic-release]: found current sha: master
[go-semantic-release]: getting latest release...
[go-semantic-release]: found version: 1.1.1
[go-semantic-release]: getting commits...
[go-semantic-release]: analyzing commits...
[go-semantic-release]: commit-analyzer plugin: default@1.3.1
[go-semantic-release]: calculating new version...
[go-semantic-release]: no change

I believe this is due to the implementation of GetCommits fetching commits chronologically from the current SHA to the last release's SHA instead of fetching the commit differences between the two SHAs, such as the result would be for git log A...B.
In the case of a commit history illustrated above, only the featureB merge and chore: commits are seen, resulting in the commit-analyzer determining that no change has occurred.
Perhaps the CompareCommits API could be used instead?

Hello everyone, it was necessary to revert this fix as it introduces a bug that made it impossible for semantic-release to create the initial release. I will investigate this further, but I am not sure if CompareCommits API solves that problem, as it is limited to 250 commits.

@christophwitzko what would you think about adding a config option or flag so we could specify to use CompareCommits instead of ListCommits? Maybe something like --provider-opt "compareCommits=true"
The limitations of CompareCommits has never impacted us as we are essentially creating new versions with almost every commit. So the 250 commit limit is not an issue for us.

Hey everyone, I just added the --provider-opt github_use_compare_commits=true option to enable the compare commits API in version 1.8.0. 🙌
Feel free to test it out and let me know if any issues arise. ☺

authors: christophwitzko jdolce lgreenway

repo: go-semantic-release/provider-github


text:
Getting started example not working

This project got my interest and wanted to give it a shot. Was attempting the getting started docker example and ran into issues:
LocalAI version:
Latest image
Environment, CPU architecture, OS, and Version:
Running in an ubuntu 22.04 VM with docker. Got an Xeon E3 with 4 cores+8threads; All threads are available for this VM with 16gig ram.
Describe the bug/reproduce
Ran this command:
docker run -p 8888:8080 -ti --rm quay.io/go-skynet/local-ai:latest --models-path /home/wouter/docker/LocalAI/models --context-size 700 --threads 4
Was assuming this would get my container up and running but ran into bugs as seen below is the output of the files.
Also attempted to pre-download a model using this:
wget https://gpt4all.io/models/ggml-gpt4all-j.bin -O models/ggml-gpt4all-j
Expected behavior
A running container :)
Logs
`CMake Error at tests/CMakeLists.txt:145 (set_target_properties):
set_target_properties called with incorrect number of arguments.
-- Configuring incomplete, errors occurred!
See also "/build/go-ggml-transformers/build/CMakeFiles/CMakeOutput.log".
See also "/build/go-ggml-transformers/build/CMakeFiles/CMakeError.log".
make[1]: *** [Makefile:144: ggml.o] Error 1
make[1]: Leaving directory '/build/go-ggml-transformers'
make: *** [Makefile:181: go-ggml-transformers/libtransformers.a] Error 2`
Additional context
Hope somebody knows the answer!

Hello @wouterverduin,
I run maybe in similar problems when I started to play around with this docker containers.
Have you tried to add the env variable
-e "REBUILD=false"
this prevent the rebuilding of the application inside of the container.
Currently I am not sure why this is possible, but my expectation is to just pull and run the container without recompile
all the stuff.
Maybe you can test:
docker run -e "REBUILD=false" -p 8888:8080 -ti --rm quay.io/go-skynet/local-ai:latest --models-path /home/wouter/docker/LocalAI/models --context-size 700 --threads 4
Also you can try to run it with:
docker run -v models:/build/models -e "REBUILD=false" -p 8888:8080 -ti --rm quay.io/go-skynet/local-ai:latest
If you want to pass more options take a look at: https://github.com/go-skynet/LocalAI/blob/master/.env
there you can see also the comment on
## Uncomment and set to false to disable rebuilding from source
# REBUILD=false

Hope that helps

@finger42
Thanks for the reply! I ran a docker command (havent triede a compose file yet) and is running now.
This is my output:
`Starting LocalAI using 4 threads, with models path: /home/wouter/docker/LocalAI/models
unexpected end of JSON input
7:34AM ERR error loading config files: open /home/wouter/docker/LocalAI/models: no such file or directory
┌───────────────────────────────────────────────────┐
│                   Fiber v2.47.0                   │
│               http://127.0.0.1:8080               │
│       (bound on host 0.0.0.0 and port 8080)       │
│                                                   │
│ Handlers ............ 31  Processes ........... 1 │
│ Prefork ....... Disabled  PID ................. 6 │
└───────────────────────────────────────────────────┘
`
So i made progress. When i go to my link it the webrowser it shows:
{"error":{"code":404,"message":"Cannot GET /","type":""}}
But when i curl http://localhost:8888/v1/models it says:
{"error":{"code":500,"message":"open /home/wouter/docker/LocalAI/models: no such file or directory","type":""}}
The things is when i cd into '/home/wouter/docker/LocalAI/models' i have two files:
-rw-r--r-- 1 root root 3785248281 Apr 15 15:17 ggml-gpt4all-j -rw-r--r-- 1 root root        180 Jul  5 09:26 ggml-gpt4all-j.tmpl
Are these the wrong files? Or is there another reason it cant acces this folder?
Yet again; Any help would be greatly appreciated!

@wouterverduin I haven't tried it without docker-compose, but it seems like your local models folder (/home/.../models) has to be mapped as a volume (/models), and then the models-path env variable should point to that volume ?
I'm having a similar problem getting the GPT4ALL-J model running locally using Docker on a 2021 MacBook M1 Pro.
First I noticed the unexpected end of JSON input error in the Docker logs, but that got fixed after uncommenting more env variables in .env (I think it was the GALLERIES that fixed it).
Now I'm having no errors:
$ docker-compose up --pull always
[+] Running 1/1
 ✔ api Pulled                                                                                1.6s
[+] Running 1/1
 ✔ Container localai-api-1  Created                                                                                0.0s
Attaching to localai-api-1
localai-api-1  | Starting LocalAI using 4 threads, with models path: /models
localai-api-1  | <nil>
localai-api-1  |
localai-api-1  |  ┌───────────────────────────────────────────────────┐
localai-api-1  |  │                   Fiber v2.47.0                   │
localai-api-1  |  │               http://127.0.0.1:8080               │
localai-api-1  |  │                                                   │
localai-api-1  |  │ Handlers ............ 33  Processes ........... 1 │
localai-api-1  |  │ Prefork ....... Disabled  PID ................. 7 │
localai-api-1  |  └───────────────────────────────────────────────────┘
localai-api-1  |
localai-api-1  | [127.0.0.1]:43294  200  -  GET      /readyz
localai-api-1  | [127.0.0.1]:39004  200  -  GET      /readyz
localai-api-1  | [127.0.0.1]:43076  200  -  GET      /readyz
localai-api-1  | [127.0.0.1]:34776  200  -  GET      /readyz
localai-api-1  | [127.0.0.1]:35052  200  -  GET      /readyz
localai-api-1  | [127.0.0.1]:54114  200  -  GET      /readyz

but, I get no response from the API:
$ curl http://127.0.0.1:8080/v1/models
curl: (52) Empty reply from server

Did anyone get the GPT4ALL-J example working using Docker?

-v models:/build/models
      ^             ^
      |               path inside of your container
      path in your host

The host path should be something like: /home/wouter/docker/LocalAI/models
The path inside of the container should be /build/models
I get also these errors at the start of the container:
unexpected end of JSON input
But I ignore it currently.
@wouterverduin  Can you post your complete docker command + the output ?
My current way to spin it up is:
docker run -it --rm -v ~/LLM/models:/build/models:cached -p 8080:8080 -e "ADDRESS=0.0.0.0:8080" -e "DEBUG=true" -e "CORS=true"  -e "THREADS=8" -e "REBUILD=false"  quay.io/go-skynet/local-ai:v1.20.1

You can play arrount with the -e options
Starting LocalAI using 8 threads, with models path: /build/models
unexpected end of JSON input

 ┌───────────────────────────────────────────────────┐
 │                   Fiber v2.47.0                   │
 │               http://127.0.0.1:8080               │
 │       (bound on host 0.0.0.0 and port 8080)       │
 │                                                   │
 │ Handlers ............ 33  Processes ........... 1 │
 │ Prefork ....... Disabled  PID ................. 7 │
 └───────────────────────────────────────────────────┘
[172.17.0.1]:44416  200  -  GET      /v1/models

Also to get the list of loaded models:
curl http://localhost:8080/v1/models
{"object":"list","data":[{"id":"ggml-nous-gpt4-vicuna-13b.bin","object":"model"}]}

For me the issue is fixed. I just restarted the container with the default env vars and waited quite a bit longer, then suddenly the API started responding, with no change in the logs.

Thank you guys' feedback.
The binary inside the image is rebuilt at the start of the container to enable CPU optimizations for the execution environment, you can set the environment variable REBUILD to false to prevent this behavior.
And about the model path @finger42 already given a clear answer.

Because the whole thing does not work for me in docker, I am now trying to build it locally.
However, I am running into the same error as OP (just outside of docker, on the host machine).
Cmake throws a ton of warnings before it stops with
`CMake Error at tests/CMakeLists.txt:145 (set_target_properties):
set_target_properties called with incorrect number of arguments.'
Any ideas?

Okay, I figured it out.
Mind you, OP and I stumbled across
CMake Error at tests/CMakeLists.txt:145 (set_target_properties): set_target_properties called with incorrect number of arguments.
Which happens when you rebuild local-ai (either in docker or outside) and which is set as the default behaviour.
The solution presented here so far is to avoid rebuilding local-ai. Unfortunately, that didn't work for me as I needed to rebuild local-ai without avx2 support (which is active per default).
So, without further ado, the solution:
There is a set of double quotes missing in go-ggllm/ggllm.cpp/CMakeLists.txt in line 145:
It reads in the repo
 set(LLAMA_EXTRA_LIBS ${LLAMA_EXTRA_LIBS} ${ACCELERATE_FRAMEWORK})
but should read
 set(LLAMA_EXTRA_LIBS "${LLAMA_EXTRA_LIBS} ${ACCELERATE_FRAMEWORK}")
With this change, for me the build process goes through without the error.
Not being a software developer, unfortunately, I don't know yet how to make a PR to correct this myself. I am going to learn that but I thought it would be better to provide the solution faster. @mudler will have this fixed in no time whereas I would probably need a couple of days to set up an IDE, git, etc. just to make the PR.
Thanks @mudler for this wonderful project! I really admire what you have created here.

Hi, @gitwittidbit , thanks for your feedback. I wonder if this line would work if you do not rebuild the project? Here, go-ggllm/ggllm.cpp is an bounding project, and it was loaded by make command. It should not have this kind of issue.

Hi, @gitwittidbit , thanks for your feedback. I wonder if this line would work if you do not rebuild the project? Here, go-ggllm/ggllm.cpp is an bounding project, and it was loaded by make command. It should not have this kind of issue.

Yes, if you don't rebuild the project, an error in the source/build code won't be a problem. For me it was a problem because I needed to rebuild the project.
And if you do rebuild it and the build process stop with the error
CMake Error at tests/CMakeLists.txt:145 (set_target_properties): set_target_properties called with incorrect number of arguments.
the you can fix this by correcting line 145 in CMakeLists.txt.

Okay, I figured it out.
Mind you, OP and I stumbled across
CMake Error at tests/CMakeLists.txt:145 (set_target_properties): set_target_properties called with incorrect number of arguments.
Which happens when you rebuild local-ai (either in docker or outside) and which is set as the default behaviour.
The solution presented here so far is to avoid rebuilding local-ai. Unfortunately, that didn't work for me as I needed to rebuild local-ai without avx2 support (which is active per default).
So, without further ado, the solution:
There is a set of double quotes missing in go-ggllm/ggllm.cpp/CMakeLists.txt in line 145:
It reads in the repo  set(LLAMA_EXTRA_LIBS ${LLAMA_EXTRA_LIBS} ${ACCELERATE_FRAMEWORK})
but should read  set(LLAMA_EXTRA_LIBS "${LLAMA_EXTRA_LIBS} ${ACCELERATE_FRAMEWORK}")
With this change, for me the build process goes through without the error.
Not being a software developer, unfortunately, I don't know yet how to make a PR to correct this myself. I am going to learn that but I thought it would be better to provide the solution faster. @mudler will have this fixed in no time whereas I would probably need a couple of days to set up an IDE, git, etc. just to make the PR.
Thanks @mudler for this wonderful project! I really admire what you have created here.

I'll try to have a look soon - however you can skip building the gglm backend if you don't need it like this:
make BUILD_TYPE=... GRPC_BACKENDS="backend-assets/grpc/langchain-huggingface backend-assets/grpc/falcon-ggml backend-assets/grpc/bert-embeddings backend-assets/grpc/bloomz backend-assets/grpc/llama backend-assets/grpc/gpt4all backend-assets/grpc/dolly backend-assets/grpc/gpt2 backend-assets/grpc/gptj backend-assets/grpc/gptneox backend-assets/grpc/mpt backend-assets/grpc/replit backend-assets/grpc/starcoder backend-assets/grpc/rwkv backend-assets/grpc/whisper" build

Using the fix listed above fixed it for me

Adding the " didn't seem to fix it for me

For those trying this out on the Windows OS and facing the above issue, I got it working by following the below steps:

Replace the $PWD with the absolute path while mounting the volume and change the internal container path to /build/models
Remove the environment variable MODELS_PATH since this defaults to the mentioned value within the .env file in the repo

Sample command while using the CUDA enabled image is shared below. Note that I've manually downloaded the models along with the config yaml file into the ./models folder within the cloned repo.
docker run -ti --gpus all -p 8080:8080 -e THREADS=1 -v "C:\Users\XXX\YYY\LocalAI\models":/build/models localai/localai:v2.6.0-cublas-cuda12-ffmpeg-core

authors: Aisuko Darin755 finger42 gitwittidbit mudler spatanjali vankeer wouterverduin

repo: go-skynet/LocalAI


text:
feat: fix CUDA images and update go-llama to use full GPU offloading

nvcc is not compatible with GCC 12 yet. golang:1.20 images got upgraded to debian bookworm, that uses GCC-12 by default. This PR downgrades images to use bullseye.
Fixes: https://github.com/go-skynet/LocalAI/issues/611

I have tested this PR on Linux(x86_64) with docker build -t localai . and docker build --build-arg BUILD_TYPE=cublas localai . but it is still not working very well.

Don't get that. What's not working well? CI builds fine.

I have tested this PR on Linux(x86_64) with docker build -t localai . and docker build --build-arg BUILD_TYPE=cublas localai . but it is still not working very well.

Don't get that. What's not working well? CI builds fine.

I test it again, it works for me now.

After 6-7 requests i stumbled upon
CUDA error 12 at /build/go-llama/llama.cpp/ggml-cuda.cu:2127: invalid pitch argument
https://github.com/ggerganov/llama.cpp/blob/d411968e990c37f51328849c96a743dd78f3c3dd/ggml-cuda.cu#L2127
Not sure if its a memory issue on my end, since i push it quite a bit right now and it works reliable on the first few ones

Running into this same problem

authors: Aisuko BAHLZ m4xw mudler


text:
Tiles missing data when multiple rows have same id

Some tiles are empty with no apparent reason. Although only one rendered tile is visible here, others are scattered around.

In an effort to debug I ran with TEGOLA_OPTIONS=DontSimplifyGeo SQL_DEBUG=EXECUTE_SQL and had no changes.
After a bit of debugging, I looked at the geojson, and it's odd. I got this, where translucent green is polygons in the tile

The lower-left is the only data from the water layer.

There's something odd going on when I zoom in close, with several things happening

The purple polygons overlap on the tile edge. This is intentional, but makes it look more complex.
Red dots are on vertexes of the original data, but you can see the vector tile has introduced additional ones. Coordinates look slightly off but that could be because it's zoomed in so much the vector tile grid resolution matters.
Shell commands for converting were
curl 'http://192.168.1.1:8080/maps/bolder/7/19/43.pbf?debug=true' -o 7_19_43.pbf
vt2geojson -z 7 -x 19 -y 43 7_19_43.pbf > 7_19_43.geojson

Oh, for SQL-side debugging, I checked that particular tile with
select osm_id, st_area(way::geometry) from (SELECT
      0::bigint AS osm_id,
      ST_AsBinary(way) AS way
    FROM simplified_ocean_polygons
    WHERE way && ST_MakeEnvelope(-1.4093765021372069e+07,6.57969939387207e+06,-1.3770895013940427e+07,6.25682938644043e+06,3857)) as _;

Results were
┌────────┬──────────────────┐
│ osm_id │     st_area      │
├────────┼──────────────────┤
│      0 │ 359223880333.241 │
│      0 │ 15631132.2569061 │
│      0 │ 377659.520064561 │
│      0 │ 5031.66775602203 │
│      0 │ 632656537.448886 │
│      0 │ 53202350.4275055 │
│      0 │ 155817611103.982 │
│      0 │ 17527459038.9674 │
│      0 │ 607717.938907239 │
│      0 │ 856719.443274425 │
│      0 │ 6386050769.74848 │
│      0 │ 60422364.8476324 │
│      0 │ 13837482.8106902 │
│      0 │ 1479355.45746988 │
└────────┴──────────────────┘

For scale, at traditional z7 pixel is 1490116 square Mercator meters, and a 4096 grid square is 5776. Several of the rows there are of significant size.

@pnorman as always, thanks for the detailed submission. I'm wondering if the fact that all the features have the same osm_id might be causing the issue? I believe that the feature ID needs to be unique or it can cause problems. If this is the case, then we need to add a log statement when this occurs.

I believe that the feature ID needs to be unique or it can cause problems.

Having a unique ID is only a SHOULD in the spec, it's not required at all.

@pnorman this has been fixed on the v0.8.x branch.

Confirming fixed.

authors: ARolek pnorman

repo: go-spatial/tegola


text:
generate: Ref property in response doesn't have a description

Problem statement
If a response contains a reference to a model, and the field in the response has a comment, that comment is ignored and not included as a description.
Swagger specification
responses:
  CreateUserResponse:
    description: ""
    schema:
      properties:
        error:
          description: An error message describing what went wrong
          type: string
        user:
          # Missing description field
          $ref: '#/definitions/User'
      type: object

Steps to reproduce
// swagger:model
type User struct {
	ID    int64  `json:"id"`
	Email string `json:"email"`
}

// swagger:response
type CreateUserResponse struct {
	// in: body
	Body struct {
		// An error message describing what went wrong
		Error string `json:"error,omitempty"`

		// The created user
		User User `json:"user"`
	}
}

swagger generate spec -o ./swagger.yml

Environment
swagger version: v0.29.0
go version: go1.18 linux/amd64
OS: Pop!_OS 21.04

unfortunately that's how jsonschema works per specification. Once a $ref field is present no other fields should be present.

@casualjim Ah good to know, thanks!

authors: Kangaroux casualjim

repo: go-swagger/go-swagger


text:
cannot find -lpng /usr/bin/ld:

Please speak English, this is the language everybody of us can speak and write.
Please ask questions or config/deploy problems on our Gitter channel: https://gitter.im/go-vgo/robotgo
Please take a moment to search that an issue doesn't already exist.
Please give all relevant information below for bug reports, incomplete details will be handled as an invalid report.

You MUST delete the content above including this line before posting, otherwise your issue will be invalid.

Robotgo version (or commit ref):
Go version: 1.10.1
Gcc version: gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.10)
Operating system and bit:Linux R 4.4.0-119-generic #143-Ubuntu SMP Mon Apr 2 16:08:24 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Can you reproduce the bug at Examples:

[ ] Yes (provide example code)
[* ] No
[ ] Not relevant

Provide example code:

package main

import (
	"fmt"
	"github.com/go-vgo/robotgo"
)

func main(){
	robotgo.ScrollMouse(10, "up")
	robotgo.MouseClick("left", true)

	x, y := robotgo.GetMousePos()
	fmt.Println("pos:",x,y)
	robotgo.KeyTap("i", "alt", "command")
	arr := []string{"alt", "command"}
	robotogo.KeyTap("i", arr)
}

Log gist:

github.com/go-vgo/robotgo
/usr/bin/ld: cannot find -lpng
/usr/bin/ld: cannot find -lz
/usr/bin/ld: cannot find -lX11
/usr/bin/ld: cannot find -lXtst
/usr/bin/ld: cannot find -lX11-xcb
/usr/bin/ld: cannot find -lxcb
/usr/bin/ld: cannot find -lxcb-xkb
/usr/bin/ld: cannot find -lxkbcommon
/usr/bin/ld: cannot find -lxkbcommon-x11
collect2: error: ld returned 1 exit status
Description
Not example problem, when I use go get xxx, it will report below problem, but I can find these lib in my system
...

Please ensure that the dependencies are installed correctly and present.

sudo apt-get install gcc libc6-dev

sudo apt-get install libx11-dev xorg-dev libxtst-dev libpng++-dev

sudo apt-get install xcb libxcb-xkb-dev x11-xkb-utils libx11-xcb-dev libxkbcommon-x11-dev libxkbcommon-dev

sudo apt-get install xsel xclip

I tested it on my Ubuntu, If the problem persists, please tell me how to reproduce it.

I do have a very similar problem. I verified that all the packages mentioned above are installed and executed GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ go build -x ./ in a folder that only contained one .go file that was the Keyboard example from the readme.
Log:
WORK=/tmp/go-build015071652
mkdir -p $WORK/b029/
cd /home/frieder/go/src/github.com/go-vgo/robotgo
CGO_LDFLAGS='"-g" "-O2" "-lgdi32" "-luser32" "-L/home/frieder/go/src/github.com/go-vgo/robotgo/cdeps/win64" "-lpng" "-lz"' /usr/local/go/pkg/tool/linux_amd64/cgo -objdir $WORK/b029/ -importpath github.com/go-vgo/robotgo -- -I $WORK/b029/ -g -O2 ./robotgo.go
cd $WORK
x86_64-w64-mingw32-gcc -fno-caret-diagnostics -c -x c - || true
x86_64-w64-mingw32-gcc -Qunused-arguments -c -x c - || true
x86_64-w64-mingw32-gcc -fdebug-prefix-map=a=b -c -x c - || true
x86_64-w64-mingw32-gcc -gno-record-gcc-switches -c -x c - || true
cd $WORK/b029
TERM='dumb' x86_64-w64-mingw32-gcc -I /home/frieder/go/src/github.com/go-vgo/robotgo -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I ./ -g -O2 -o ./_x001.o -c _cgo_export.c
TERM='dumb' x86_64-w64-mingw32-gcc -I /home/frieder/go/src/github.com/go-vgo/robotgo -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I ./ -g -O2 -o ./_x002.o -c robotgo.cgo2.c
cd /home/frieder/go/src/github.com/go-vgo/robotgo
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I $WORK/b029/ -g -O2 -o $WORK/b029/_x003.o -c adler32.c
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I $WORK/b029/ -g -O2 -o $WORK/b029/_x004.o -c compress.c
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I $WORK/b029/ -g -O2 -o $WORK/b029/_x005.o -c crc32.c
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I $WORK/b029/ -g -O2 -o $WORK/b029/_x006.o -c deflate.c
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I $WORK/b029/ -g -O2 -o $WORK/b029/_x007.o -c gzclose.c
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I $WORK/b029/ -g -O2 -o $WORK/b029/_x008.o -c gzlib.c
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I $WORK/b029/ -g -O2 -o $WORK/b029/_x009.o -c gzread.c
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I $WORK/b029/ -g -O2 -o $WORK/b029/_x010.o -c gzwrite.c
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I $WORK/b029/ -g -O2 -o $WORK/b029/_x011.o -c infback.c
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I $WORK/b029/ -g -O2 -o $WORK/b029/_x012.o -c inffast.c
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I $WORK/b029/ -g -O2 -o $WORK/b029/_x013.o -c inflate.c
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I $WORK/b029/ -g -O2 -o $WORK/b029/_x014.o -c inftrees.c
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I $WORK/b029/ -g -O2 -o $WORK/b029/_x015.o -c trees.c
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I $WORK/b029/ -g -O2 -o $WORK/b029/_x016.o -c uncompr.c
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I $WORK/b029/ -g -O2 -o $WORK/b029/_x017.o -c zutil.c
cd $WORK/b029
TERM='dumb' x86_64-w64-mingw32-gcc -I /home/frieder/go/src/github.com/go-vgo/robotgo -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -I ./ -g -O2 -o ./_cgo_main.o -c _cgo_main.c
cd /home/frieder/go/src/github.com/go-vgo/robotgo
TERM='dumb' x86_64-w64-mingw32-gcc -I . -m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=$WORK/b029=/tmp/go-build -gno-record-gcc-switches -o $WORK/b029/_cgo_.o $WORK/b029/_cgo_main.o $WORK/b029/_x001.o $WORK/b029/_x002.o $WORK/b029/_x003.o $WORK/b029/_x004.o $WORK/b029/_x005.o $WORK/b029/_x006.o $WORK/b029/_x007.o $WORK/b029/_x008.o $WORK/b029/_x009.o $WORK/b029/_x010.o $WORK/b029/_x011.o $WORK/b029/_x012.o $WORK/b029/_x013.o $WORK/b029/_x014.o $WORK/b029/_x015.o $WORK/b029/_x016.o $WORK/b029/_x017.o -g -O2 -lgdi32 -luser32 -L/home/frieder/go/src/github.com/go-vgo/robotgo/cdeps/win64 -lpng -lz
# github.com/go-vgo/robotgo
/usr/bin/x86_64-w64-mingw32-ld: cannot find -lz
collect2: error: ld returned 1 exit status

I also have the  mingw-w64 packages installed.
My Operating System is Ubuntu 18.04 bionic with the x86_64 Linux 4.10.0-42-generic kernel
go version go1.11 linux/amd64
gcc version: gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0

authors: frieder-audriga qianguozheng vcaesar

repo: go-vgo/robotgo


text:
Update Task bucket_id

I want to move a task to another project and another bucket based on the bucket it was moved to on the update trigger.
So I created a switch for the 3 bucket_ids in my inbox-project but I cannot update project/bucket_id is there a workaround for this or do I have to wait for it getting implemented?

Which Vikunja version are you using?

It sounds like a bug, but I did't try it out. Since the views will change in the next release, the behaviour here needs adjustments as well. I'll keep that in mind while fixing it.

I explained it very bad sorry. I think it's not a bug but not implemented yet. I want to move a task to another bucket in another project. I just don't find an action in n8n-nodes-vikunja allowing me to do so. Even the action "Update Task" just lets me update for example the title or due date... but not the bucket.

This was implemented in https://github.com/go-vikunja/n8n-vikunja-nodes/commit/683cc599fd6d28cb4f3eb4b6260925813c80a913. I'll release a new version of this package shortly, but it will contain breaking changes for the next Vikunja release - that means you'll need to run an unstable build until the stable version is released to use it with this node.

Thank you very much, I'll give it a try.

authors: djagoo kolaente


text:
Fix Tencent COS Endpoint

Fix: https://github.com/gobackup/gobackup/issues/233

authors: Anbool huacnlee

repo: gobackup/gobackup


text:
Unify to CantYieldWithoutBlockFormat

First PR to reduce inconsistent error message literals in Goby's codebase.

@hachi8833 only one case for this PR?

I'm creating the next PRs 😃

repo: goby-lang/goby


text:
节点资源超卖

使用crane scheduler，不改变pod的默认调度器，仅加入filter和score plugin，是否可以使节点部署超过request的pod

要达到不修改request完成超卖装箱，只能对节点进行容量放大。内部版本我们有这个能力，目前还没有开源出来。因为涉及到对节点容量的修改，要么需要增加webhook拦截节点汇报资源的请求并且放大，要么修改kubelet admit插件，允许pod request和>节点allocatable resource。
因为侵入性比较大，所以尚未开源。如果有类似需求，可在此issue下+1，如果是共性需求，我们可以规划开源此能力。

authors: lkfadeaway mfanjie

repo: gocrane/crane-scheduler


text:
Script editor crashing when performing autocomplete

Operating system or device, Godot version, GPU Model and driver (if graphics related): Windows 10, Godot Git https://github.com/godotengine/godot/commit/dd7145b778ea4884fd52f5efaf79dc55375c8465 compiled with MSVC 2017
Issue description:
The script editor always crashes when performing autocomplete, which is usually done by editing characters in a script.
Steps to reproduce: In the example project (see below), edit the autoload/console.gd script at line 55. Specifically, try editing the string that is passed to the append_bbcode() function there. Editing the script in other places (such as comments, or variable declarations) does not seem to cause a crash.
Stack trace:

Link to minimal example project: godot-console.zip

I found the issue, making a PR.

authors: Calinou hpvb

repo: godotengine/godot


text:
Can't Save Code without Tree Root

Operating system or device, Godot version, GPU Model and driver (if graphics related):
Windows 10
Godot 3.0 Beta Build 1
Issue description:
Can't save GDScript when there is no tree root
Steps to reproduce:

Close all scenes
Edit a script and try to save it, you'll get this message: "This operation can't be done without a tree root."

Link to minimal example project:
Can't Save Code Without Tree Root.zip

Press Ctrl+Alt+S instead of Shift+S (or use the File menu)

Good that works, but is there a reason there is a different shortcut for saving scripts without a tree root?

This is a general "save scripts" shortcut.


text:
imporve uniform of shader language

default value dispaly in inspect windows

uniform float zoom  =5.0;

hint_range support min value /max value

uniform float zoom : hint_range(0,FLOAT_MAX);

support default value set when set hint_range

uniform float zoom : hint_range(0,1) =5.0;

hint_range support vec type

uniform vec2 zoom : (hint_range(0,1), hint_range(0,1));

I really like the idea but I think it will be easier to implement something like,
uniform float zoom : hint_range(0, 1, default_value); and for vecs, uniform vec2 zoom : hint_range(0,1,0,1);   // for x min, max and then y min, max

already achieve at lastest build.

authors: swarnimarun ywaby


text:
Missing a mouse/cursor node

I don't now if this was suggested before but I'm missing a mouse/cursor node.
Idea behind:

camera follow mouse
change mouse cursor
mouse can be animated with animationplayer
hide and show mouse (in game movie)
catch mouse (tutorial)
and more

I know you can do this with GDScript but I'm a visually programmer! :-)

well you can make a cursor follow the mouse pretty easily with a few lines of code, and make it work in any way you want so I would rather make a specific way as a node

I have done someting like that
extends Sprite

export(int,"MOUSE_MODE_VISIBLE","MOUSE_MODE_HIDDEN","MOUSE_MODE_CAPTURED") var mouse_mode
export(bool) var invert_y
export(bool) var invert_x
export(float) var sensitive_y
export(float) var sensitive_x
export(Texture) var normal
export(Texture) var waiting

func _ready():
	self.set_pos(Vector2(get_viewport_rect().size.width/2,get_viewport_rect().size.height/2))
	set_mode(mouse_mode)
	set_texture(normal)
	set_process_input(true)

func _input(ev):
	if (ev.type==InputEvent.MOUSE_BUTTON and ev.button_index==BUTTON_LEFT and ev.pressed):
		set_scale(Vector2(0.8,0.8))
	elif (ev.type==InputEvent.MOUSE_BUTTON and ev.button_index==BUTTON_LEFT and !ev.pressed):
		set_scale(Vector2(1,1))
	elif (ev.type==InputEvent.MOUSE_MOTION):
		var fake_x = ev.pos.x * sensitive_x
		var fake_y = ev.pos.y * sensitive_y
		if(invert_y):
			fake_y = get_viewport_rect().size.height - ev.pos.y * sensitive_y
		if(invert_x):
			fake_x = get_viewport_rect().size.width - ev.pos.x * sensitive_x
		set_pos(Vector2(fake_x,fake_y))
	if (ev.is_action_released("ui_cancel")):
		set_mode(1)

func set_mode(in_mouse_mode):
	Input.set_mouse_mode(in_mouse_mode)

func set_waiting():
	set_texture(waiting)

func set_normal():
	set_texture(normal)

but I have problem with changing color of cursor depending what color is behind.
Perhaps I should start a forum post about that.
I've thought it would be more consistent if such a node would exist.

but I have problem with changing color of cursor depending what color is behind.

Not sure why you would want to do that, because mouse cursors don't normally change colors based on the background. So, even if such node existed, you'd face the exact same problem.
You have the possibility of making a cursor node via C++ module though you likely can do the same behavior with just GDScript in a standard node.
I don't think there's any need for a cursor node and its utility is not very clear. An API to deal with the OS cursor is preferable (if doesn't currently exist) and in the platforms without mouse it wouldn't be needed anyway.
Let's talk about what's currently possible:

camera follow mouse
catch mouse (tutorial)
hide and show mouse

The Window Management demo is a good start to see how to do these.

change mouse cursor

You can do that via Project Settings with display/custom_mouse_cursor property, though it's not hardware accelerated AFAIK.
You can't use the Animation Player to make a cursor and that's a good request, but would a cursor node be needed for that? One possibility would be to use a custom scene as cursor (since node and scene are pretty much the same thing).

For our LudumDare 34 game  we have created a scene for the mouse and added it to the game gui scene (canvasLayer)
We can't go with the Project Settings "custom_mouse_cursor" because we have had the same [issue] (https://github.com/godotengine/godot/issues/3082) and don't get around it.
I closing this issues. Everything can easily be obtained inside the editor. Thanks!

authors: puppetmaster- reduz vnen


text:
Unable to run under (or attach) LLDB debugger on macOS starting with 3.3 due to missing entitlement

When I upgraded from 3.2.3 to 3.3 I lost the ability to run Godot under lldb (debugger) or attach afterward. From what I can tell so far, I think it's because of the way binaries are signed. Specifically, without the "com.apple.security.get-task-allow" entitlement, lldb doesn't have permission to attach.
I've also tested this on 3.3.1 and have the same problem, but 3.2.3 still works fine.
I'm new to the whole concept of "entitlements" on macOS, so I haven't yet figured out how to fix this or if I'd need to compile the engine myself to do it.
I'm running on macOS 11.3.1.
To reproduce (on Mac only):

Open Terminal
Install xcode command-line tools if you haven't already: xcode-select --install
Change directory to the location of the Godot binary (inside the Godot.app package, i.e.: cd /Applications/Godot.app/Contents/MacOS
Run the following: lldb ./Godot
Enter the following command: run

Observed on 3.3 (the problem):
"error: process exited with status -1 (Error 1)"
Observed on 3.2.3 (working as expected):
"Process #### launched" message, followed by Godot appearing after a short delay.
Why this matters:
I'm using GDNative and need to debug my C++ code running within Godot's process.

cc @bruvzg

This is expected, missing com.apple.security.get-task-allow prevents debugging, but you can't notarize app with this entitlement (see: Avoid the Get-Task-Allow Entitlement).
There's no need to rebuild the editor (but might be useful to do so anyway, since official binaries do not have symbols included), you can instead:

remove signature entirely, use: codesign --remove-signature /path/to/Godot.app
resign it with the new entitlements and ad-hoc signature codesign --sign - --force --options=runtime --entitlements /path/to/editor.entitlements /path/to/Godot.app. Use a copy of entitlements file from the https://github.com/godotengine/godot-build-scripts/tree/master/build-macosx, with the com.apple.security.get-task-allow added.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
 <key>com.apple.security.device.audio-input</key>
 <true/>
 <key>com.apple.security.device.camera</key>
 <true/>
 <key>com.apple.security.cs.disable-library-validation</key>
 <true/>
 <key>com.apple.security.get-task-allow</key>
 <true/>
</dict>
</plist>

This should probably be documented somewhere.
BTW @bruvzg, this made me think that we should probably move the .entitlements file used for the official binaries to this repo, instead of godot-build-scripts.

Thanks for the clarification and workaround!

authors: Calinou Thoughtquake akien-mga bruvzg


text:
Corruption on VRAM-compressed texture mipmaps (S3TC compression)

Godot version
eb318d3e04ac6d3bb01b0f2a8311d06ba55c3a2b
System information
Windows 10, Vulkan, Nvidia GTX 1080 (471.11)
Issue description
It appears that the mipmaps of textures imported as VRAM Compressed can appear with odd skewing distortion.

The cube in the centre is using a texture with VRAM compression, while the other cubes are using the other four options. This issue does not appear to affect all textures, but it seems consistently broken on the example texture provided.
Steps to reproduce
Simply open the example project and observe the middle cube with VRAM Compressed version of the texture at an appropriate distance to see the mipmaps.
Minimal reproduction project
mipmaps.zip

I don't know exactly how long this has been an issue, but it seems to have been around for a while at least.

A bit more follow-up info, the main reason this particular texture seems to fail is due to it being non-power-of-two. I've also been informed that this particular issue is likely specific to S3TC compression.

It is probably just that the texture compression works in blocks (e.g. 4x4), so you will often get compression artifacts across these borders in the base level or mipmaps. As you say, using a power of 2 texture size makes them less likely.

The khronos OpenGL wiki claims the following:

S3TC is a block-based format. The image is broken up into 4x4 blocks. For non-power-of-two images that aren't a multiple of 4 in size, the other colors of the 4x4 block are taken to be black. Each 4x4 block is independent of any other, so it can be decompressed independently.

From what I can tell, on OpenGL, there seems to be no hard requirement about dimensions of S3TC compressed textures being powers of two or multiples of four... However, apparently DX11 and WebGL impose some limitations to prevent it [except for 2x2 and 1x1 mipmaps since those are special]. I can't find any info on Vulkan, however.
The problem Godot has is it also allows mipmaps for non-power of two textures... which means, even if LOD 0 is a multiple of 4, some of the lower resolution LODs might be odd dimensions. I don't know if there is a good way around this contradiction, other than either ignore the DX11 requirement, or block VRAM Compression for any non-power of two texture with mipmaps enabled?
Just to see what other engines do in these cases, interestingly, Unity completely doesn't allow mipmaps for non-power of two textures (it defaults to resizing to nearest power-of-two when mipmaps are enabled), and it also does not allow compression for non-multiple-of-4... so they went the easy route of just not allowing this case.

Regardless of what is compatible with ANGLE and DX11, it seems fair to me that Godot shouldn't produce incorrect results or crash on non-multiple-of-4 S3TC compression. So while Godot might want to consider applying stricter rules, there's still a bug here that should be fixable, I would think. See also: #48509

I tested importing a 958x552 image in both Godot 3 and 4 to compare the results.
Source image: https://tcrf.net/images/f/fc/SCU-TEST_RR_areaMap-bg.png
Godot 3: Creates a DXT1 format texture, looks correct.
Godot 4: Creates a DXT5 format texture, has skewed output and broken colors.
It seems Godot 4's DXTn encoder isn't padding the last tiles. (958 should be padded out to 960)
================================
Godot 3.3 has DXTn compression in module_compress_squish.cpp:
https://github.com/godotengine/godot/blob/9d0e0fe783f05b7ea504f0d233afc7441a74c535/modules/squish/image_compress_squish.cpp#L187
which calls out to the third-party squish module for the actual compression:
https://github.com/godotengine/godot/blob/3.3/thirdparty/squish/squish.cpp#L181
Squish is given the original unaligned width/height, not a padded width/height, and it pads the last 4x4 tile correctly.
================================
Godot 4 has DXTn compression in image_compress_etcpak.cpp:
https://github.com/godotengine/godot/blob/e5c6c773e99e3f9aae4ac8a804f392416c871285/modules/etcpak/image_compress_etcpak.cpp#L148
_compress_etcpak() ends up calling either CompressDxt1Dither() or CompressDxt5() with a mipmap size value that's been aligned to 4 pixels. However, this is telling the compression function that the original image is (in this case) 960 pixels, but it's actually 958 pixels. This is why the image ends up broken.

I also noticed transparent textures with VRAM compression completely fail to render mipmaps, when it worked in Godot 3:

Is this the same issue or should it be a different one?

Just to see what other engines do in these cases, interestingly, Unity completely doesn't allow mipmaps for non-power of two textures (it defaults to resizing to nearest power-of-two when mipmaps are enabled), and it also does not allow compression for non-multiple-of-4... so they went the easy route of just not allowing this case.
Regardless of what is compatible with ANGLE and DX11, it seems fair to me that Godot shouldn't produce incorrect results or crash on non-multiple-of-4 S3TC compression. So while Godot might want to consider applying stricter rules, there's still a bug here that should be fixable, I would think. See also: #48509

It looks like Unreal doesn't even let you use mipmaps if your texture is non power of two https://docs.unrealengine.com/4.27/en-US/RenderingAndGraphics/Textures/Importing/ (also tested using the texture from OP)
From the Unity docs: https://docs.unity3d.com/560/Documentation/Manual/ImportingTextures.html

It is possible to use NPOT (non-power of two) Texture sizes with Unity; however, NPOT Texture sizes generally take slightly more memory and might be slower for the GPU to sample, so it’s better for performance to use power of two sizes whenever you can. If the platform or GPU does not support NPOT Texture sizes, Unity scales and pads the Texture up to the next power of two size. This process uses more memory and makes loading slower (especially on older mobile devices). In general, you should only use NPOT sizes for GUI purposes.

So I agree, we porbably need to be stricter about texture dimensions as well. In the short term, we should give the user an appropriate error and disable mipmaps. In the medium run, we should have a nicer UX that allows users to automatically pad nonpot textures

Regarding being strict, I agree that it's better to fail the import tell the user to fix their art so they aren't surprised when it's blurry (due to scaling by a few pixels. I like that Unity lets you choose how to deal with power-of-two. Currently, in Godot, you can use the "Max Size" setting but that resizes in both dimensions, and it applies a separate resize from the power-of-two one, effectively causing two resizes, so it might not be optimal (since both width and height might need to be resized differently).
About your comment, two things to note:

Before etcpak was merged, Godot actually enforced the same rules as Unity. However, it did it by automatically scaling up to the nearest power-of-two if mipmaps enabled, and scaling to the nearest multiple-of-four if not (which probably causes aliasing)

My draft PR at #46931 only tries to restore this old behavior.

Even if you are strict about dimensions, there will still be mipmap levels for 2x2 and 1x1 (or Nx1 if not square). These are allowed out of necessity, but because they still use integer blocks, it expects to compress a 4x4 block, which means that we need to pass a padded buffer.

The old "modules/etc" library took in width&height in pixels, so I think it somehow handled this case, while "etcpak" is more strict. Once I add the code to scale Nx2 and Nx1 buffers to multiple of 4, I'll submit that PR.

authors: GerbilSoft SaracenOne Zylann clayjohn lawnjelly lyuma


text:
Extending script in editor doesn't generate new script in Visual Studio 2022

Godot version
3.4
System information
Windows 10
Issue description

Clicking "Extend Script" in the editor opens up existing base script when using Visual Studio as an external editor instead of creating a new inherited script. Window focus does switch, however. This is potentially dangerous if you believe that a new script has been generated when you are instead editing the base script
Steps to reproduce
Open visual studio, open godot, right click on node, click extend script
Visual studio will open to the existing base script without opening a new one
Minimal reproduction project
No response

Is this GDScript or C#?

I have tested if I click "extend script" then it doesn't happen.  I am still staying on godot and won't open Visual Studio. I think you have set up extend editor in project setting. That's not bug. I have downloaded and built and tested. It works as well under Windows 10 Pro x64

Is this GDScript or C#?

Sorry, this is C#. I'll edit the title


text:
Order of shader uniform properties is alphabetical, not in shader-code order

Godot version
v4.0.alpha12.official [2c11e6d9e]
System information
Win10
Issue description
The shader uniform properties are being structured in an alphabetical order instead of the actual written order in the shader code.
The actual desired effect (shown here with GDScript):

What instead happens:

@Chaosus mentioned here already that this is due to the Shader Uniforms being stored in a HashMap instead of a Vector: https://github.com/godotengine/godot/pull/62972#issuecomment-1183026786
Steps to reproduce

Create a new shader in a new project or open up the minimal reproduction project
create a uniform that starts with a letter like "W"
create another uniform that starts with a letter like "A" that comes in the alphabet before the above letter in the next line
look at the inspector and the order of the uniforms

Minimal reproduction project
Godot4Alpha12Test.zip

Duplicate of https://github.com/godotengine/godot/issues/69949

authors: akien-mga paddy-exe


text:
awaiting in EditorScript._run() doesn't work.

Godot version
4.0.beta1
System information
Win11
Issue description
Run editor script like this:
@tool
extends EditorScript

func _run():
	var tree = get_editor_interface().get_tree()
	await tree.create_timer(1.0).timeout
	print("timeout")

The script is freed immediately, and after 1sec the editor prints error Resumed function '_run()' after await, but class instance is gone. At script: res://await_bug.gd:6
=====
It will works fine if you reference() the script manually:
func _run():
	reference()
	var tree = get_editor_interface().get_tree()
	await tree.create_timer(1.0).timeout
	print("timeout")
	unreference()

Steps to reproduce
N/A
Minimal reproduction project
No response

This is kind of expected. EditorScript is RefCounted, so it's destroyed when nothing references it.
We could maybe ensure that the EditorScript exists until function is finished or just document this.

This now documented thanks to https://github.com/godotengine/godot/pull/66326, but I'm reopening due to the discussion above (do we want a fix that makes EditorScripts references until the function is finished?).
Editor team: feel free to close this if you decide against implementing a fix.

Hi, is there any update about this one?
I stumbled across this issue while trying to test a simple HTTPRequest in an EditorScript (awaiting on the connected signal). This is virtually impossible currently, without explicitly calling the reference methods.

Not sure how viable it is to wait until a function is finished, but I came up with this solution: add make_persistent() method to EditorScript, which would store its ref somewhere (e.g. in SceneTree meta). When another script calls this method, the old one will be replaced. There would be complementary clear_persistence() method that removes the script reference. This way it's safer to use than reference methods, because at worst you end up with one lingering script (which can still be cleared).

Debugged this behaiviour 2 hours until I got to the conclusion that it got eaten by Garbage Collection. I din't found anything in the docs. Would be cool to have a solution like described above. For now I make a custom editor window with a button as work around.
Other Idea just make a method to queue_free the instance manually then you could have also long running stuff in general.

authors: KoBeWi fenix-hub kanimaru mhilbrunner zaevi


text:
Crash To Desktop on switching focus in GridContainer containing complex buttons.

Operating system or device - Godot version:
Mac OSX El Capitan. Godot v2.1.stable.official
Issue description (what happened, and what was expected):
I am making a slightly more complex button. It has to support lighting, and animations, and thus is a complex tree including a couple of Node2D nodes. When putting a bunch of instances of them on a GridContainer, and trying to switch focus using tab produces a Crash to Desktop
Steps to reproduce:
To do this I created two scenes:
-one with a container and a GridContainer.
-one that is the button. It has a Container, a Node2D and a Button.

I add several instances of the button to the GridContainer on its _ready method. Then launch it, click on one of the buttons and press "tab". Crash to Desktop and OSX asks to fill a report.

Do note that moving around with the keys (reaaaally nice feature jesus christ thanks to whoever did this) does not produce a crash.
Link to minimal example project (optional but very welcome):
https://www.dropbox.com/s/9b1o0tnok33i479/crashDemo.zip?dl=0
The report is huge, I am posting the first lines
Process:               Godot [11438]
Path:                  /Applications/Godot.app/Contents/MacOS/Godot
Identifier:            org.godotengine.godot
Version:               2.1 (2.1)
Code Type:             X86-64 (Native)
Parent Process:        Godot [10030]
Responsible:           Godot [11438]
User ID:               502
Date/Time:             2016-10-04 23:47:21.189 -0300
OS Version:            Mac OS X 10.11.5 (15F34)
Report Version:        11
Anonymous UUID:        61065F14-7955-A5AC-554A-D9CA127CE984
Time Awake Since Boot: 7500 seconds
System Integrity Protection: enabled
Crashed Thread:        0  Dispatch queue: com.apple.main-thread
Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000228
Exception Note:        EXC_CORPSE_NOTIFY
VM Regions Near 0x228:
-->
__TEXT                 00000001076b6000-0000000109c0e000 [ 37.3M] r-x/rwx SM=COW  /Applications/Godot.app/Contents/MacOS/Godot
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   org.godotengine.godot           0x00000001082ece89 Control::find_next_valid_focus() const + 617
1   org.godotengine.godot           0x00000001082945d0 Viewport::gui_input_event(InputEvent) + 2544
2   org.godotengine.godot           0x0000000108292a89 Viewport::input(InputEvent const&) + 313
3   org.godotengine.godot           0x0000000108292943 Viewport::vp_input(InputEvent const&) + 355
4   org.godotengine.godot           0x00000001082a3d95 MethodBind1<Viewport, InputEvent const&>::call(Object, Variant const_, int, Variant::CallError&) + 469
5   org.godotengine.godot           0x0000000108cdc4d2 Object::call(StringName const&, Variant const_*, int, Variant::CallError&) + 642
6   org.godotengine.godot           0x0000000108cdc1aa Object::call(StringName const&, Variant const&, Variant const&, Variant const&, Variant const&, Variant const&) + 106
7   org.godotengine.godot           0x000000010827051b SceneTree::call_group(unsigned int, StringName const&, StringName const&, Variant const&, Variant const&, Variant const&, Variant const&, Variant const&) + 1627
8   org.godotengine.godot           0x000000010827161a SceneTree::input_event(InputEvent const&) + 330
9   org.godotengine.godot           0x00000001076c07d1 InputDefault::parse_input_event(InputEvent const&) + 1201
10  org.godotengine.godot           0x00000001076b8ec0 -[GodotContentView keyDown:] + 528
11  com.apple.AppKit                0x00007fff916b1b15 -[NSWindow _reallySendEvent:isDelayedEvent:] + 2108
12  com.apple.AppKit                0x00007fff910f0539 -[NSWindow sendEvent:] + 517
13  com.apple.AppKit                0x00007fff9107116a -[NSApplication sendEvent:] + 4382
14  org.godotengine.godot           0x00000001076b7988 -[GodotApplication sendEvent:] + 136
15  org.godotengine.godot           0x00000001076bbd7b OS_OSX::run() + 235
16  org.godotengine.godot           0x00000001076be0ab main + 523
17  libdyld.dylib                   0x00007fff8a14a5ad start + 1

I opened #6717, which at least fixes the crash.
However the issue that it doesn't find a valid "next control" in this case still remains.

Is this issue still valid (it's been a while)? Should we close it in favour for another one or retitle it?

Does this still happen?

I opened the crash demo on 2.1.3 stable and it doesn't happen anymore, so yay!

authors: Hinsbart bojidar-bg floydnunez reduz


text:
Input names autocomplete gives extra " at the end of the string

Godot version
4.0 beta 10
System information
Windows 11
Issue description
On the text editor when using autocomplete on function arguments that receive Input Map names after autocompleting the function name, the string autocompleted appears with an extra " at the end.
This doesnt happen if you write " and then accept the Input name in the dropdown
Steps to reproduce

On the script editor
Start writing Input.get_vector but when the dropdown appears with the autocomplete suggestion for Input.get_vector press enter to accept it, then press enter again to accept the Input map suggestion
The autocompleted input name should have an extra "

Minimal reproduction project
N/A

Recording of the issue

This is a duplicate of https://github.com/godotengine/godot/issues/48436, but for the built-in editor. I can reproduce this on 4.0.beta8-9-10, but I think there's another open issue for this already.

authors: Calinou hilias


text:
Crash on fullscreen switch due to_update_swap_chain() fail when thread model is Multi-Threaded

Godot version
v4.0.beta14.official [28a24639c]
System information
Arch and Fedora Linux, Geforce 2080 and 3080
Issue description
Setting the window mode to Window.MODE_FULLSCREEN crashes due to:
E 0:00:03:0491   _update_swap_chain: Condition "err" is true. Returning: ERR_CANT_CREATE
  <C++ Source>   drivers/vulkan/vulkan_context.cpp:1912 @ _update_swap_chain()

source link
ERROR: Condition "err" is true. Returning: ERR_CANT_CREATE
   at: _update_swap_chain (drivers/vulkan/vulkan_context.cpp:1912)

================================================================
handle_crash: Program crashed with signal 11
Engine version: Godot Engine v4.0.beta14.official (28a24639c3c6a95b5b9828f5f02bf0dc2f5ce54b)
Dumping the backtrace. Please include this when reporting the bug to the project developer.
[1] /lib64/libc.so.6(+0x3cb20) [0x7f6f5f4c7b20] (??:0)
[2] /lib64/libnvidia-glcore.so.525.78.01(+0x17bc339) [0x7f6f39fbc339] (??:0)
[3] /lib64/libnvidia-glcore.so.525.78.01(+0x17bc401) [0x7f6f39fbc401] (??:0)
[4] /lib64/libGLX_nvidia.so.0(+0x9c7bc) [0x7f6f484ea7bc] (??:0)
[5] /home/micha/Apps/Godot_v4.0-beta14_linux.x86_64() [0x4b472eb] (??:0)
[6] /home/micha/Apps/Godot_v4.0-beta14_linux.x86_64() [0x1a95173] (??:0)
[7] /home/micha/Apps/Godot_v4.0-beta14_linux.x86_64() [0x1a96224] (??:0)
[8] /home/micha/Apps/Godot_v4.0-beta14_linux.x86_64() [0x3a3f0fa] (??:0)
[9] /home/micha/Apps/Godot_v4.0-beta14_linux.x86_64() [0x398f4c1] (??:0)
[10] /home/micha/Apps/Godot_v4.0-beta14_linux.x86_64() [0x3a610c2] (??:0)
[11] /home/micha/Apps/Godot_v4.0-beta14_linux.x86_64() [0x3a3af53] (??:0)
[12] /home/micha/Apps/Godot_v4.0-beta14_linux.x86_64() [0x40d9b15] (??:0)
[13] /home/micha/Apps/Godot_v4.0-beta14_linux.x86_64() [0x4c7a1e0] (??:0)
[14] /lib64/libc.so.6(+0x8b12d) [0x7f6f5f51612d] (??:0)
[15] /lib64/libc.so.6(+0x10cbc0) [0x7f6f5f597bc0] (??:0)
-- END OF BACKTRACE --
================================================================

Steps to reproduce

Set "rendering/driver/threads/thread_model" to multi-threaded in the project settings.
At runtime set window.mode to Window.MODE_FULLSCREEN (after ~1 sec)
Observe error in the debugger or app crash.

May crash the app or not.
Depends on the scene resources / complexity ?
Minimal reproduction project
fullscreen-toggle-bug.zip

update_swap_chain is not the cause of the crash – it's a consequence of the renderer not being able to initialize after the resolution/window mode change.

authors: Calinou michael-nischt


text:
[FIXED in master] [Godot 4 RC2] Directional shadow twitches when the camera moves

Godot version
4.0 RC2
System information
Arch Linux + X11+ KDE Plasma + Radeon RX6800XT
Issue description
I've tested and it does not happen in RC1 - this is clearly a regression in RC2.
Demonstration in RC2:
https://youtu.be/7RK0D4woyMI
In RC1 there is no such issue:
https://youtu.be/Jl5q6M_i2Ao
Steps to reproduce
Probably just use a directional light I guess?
Minimal reproduction project
N/A

What do you mean by "FIXED in master"?

@unfa Please upload a minimal reproduction project to make this easier to troubleshoot.
Also, check if this only occurs when the light's angular distance is greater than 0 (PCSS-style shadows).

@akien-mga That means me building Godot from git after the RC2 release doesn't show this problem. I assume it was a mistake that was noticed and promptly fixed after the RC2 release. I decided to still post the issue in case it's not that simple.
@Calinou Ok, I'll try to do that.

Here's an MRP:
Twitching Shadows.zip

Duplicate of https://github.com/godotengine/godot/issues/59232.

Thanks!

What about the comment that it's fixed in master? Is #59232 too?

I didn't test that one.

I tested and the MRP from https://github.com/godotengine/godot/issues/73572#issuecomment-1437643757 does reproduce the bug, so it doesn't appear to be fixed (and thus can indeed be a duplicate of #59232).

authors: Calinou akien-mga unfa


text:
variable in autoload is recognized as constant

Operating system or device - Godot version:
Godot 2.2 alpha with current master head c9366f8b563c186b4d0ab09088d09d47580f749d
Issue description (what happened, and what was expected):
variable in autoload script is recognized as constant, so can't assign it
Steps to reproduce:
global.gd (autoload)
extends Node

var not_const_var

func _ready():
	pass

node.gd
extends Node

func _ready():
	global.not_const_var = []

when run, debugger says Parser Error: Can't assign to constant
maybe regression with #7390?
Link to minimal example project (optional but very welcome):

@bojidar-bg would you check for this?

I tested with back to false on https://github.com/godotengine/godot/blob/master/modules/gdscript/gd_parser.cpp#L2026
Node *expression = _parse_and_reduce_expression(p_block,p_static,false,true);
global.gd (autoload)
extends Node

const const_var = 1
var not_const_var

node.gd
extends Node

const const_local = 1

func _ready():
	const_local = 2 # no error
	prints("const_local=",const_local) # prints 2

	global.not_const_var = [] # no error
	prints("const_var=",global.const_var) # prints 1
	global.const_var = 2 # error : Invalid set index 'const_var' (on base: 'Node (global.gd)').


text:
parse_property autocomplete raise bad signature error

Godot version
4.1.dev (4640b553a21) but present since 4.0
System information
MacOS 13.1 M1 Pro
Issue description
when autocompleting the _parse_property function with types it will raise bad signature error.

This is because instead of completing with enum types it completes with int types. I don't know if this is a bug only in this function or in all function containing variable typed with enums as I don't know of any other virtuam function typed with enums
Steps to reproduce

activate add type hint
create a script inheriting EditorInspectorPlugin
start typing func _parse_property
autocomplete the rest

Minimal reproduction project
N/A

Thanks for your report, this is a duplicate of https://github.com/godotengine/godot/issues/75311.

authors: YuriSizov ajreckof


text:
Editor Crashes using floating script window while refocusing it

Godot version
4.1.1
System information
Windows 10 - Godot v4.1.1.stable -Vulkan (Forward+)
Issue description
Editor crashes when the scripting window is in a floating state and un/focusing it with alt + tab.
Steps to reproduce
I've been able to reproduce this every time:

Open Godots script editor.
Put the script editor in floating window state.
Alt + Tab.
Refocus editor.

Minimal reproduction project
N/A

Cannot reproduce in 4.1.1 or other 4.1.x versions.
At most I can get an error to show platform/windows/display_server_windows.cpp:1160 - Condition "wd_window.transient_parent == p_parent" is true., but I can't get it to crash.

Closing as resolved, if someone can replicate this on a supported version please comment

authors: AThousandShips hoywren kitbdev


text:
False positive unsafe_call_argument with variant

Tested versions
4.2.1.stable.arch_linux
System information
Linux 6.7.2-arch1-1
Issue description
func foo(_a):
	pass

func bar():
	var x = []
	foo(x)

The last line shows the warning:
(UNSAFE_CALL_ARGUMENT): The argument 1 of the function "foo()" requires the subtype "Variant" but the supertype "Variant" was provided.

It should be safe to pass a variant to a function with no type annotation. The error message seems to contradict itself anyhow.
Steps to reproduce

Enable unsafe_call_argument warning
Write the code in the issue description

Minimal reproduction project (MRP)
N/A

This seems to be by design, it goes away if you do:
func foo(_a: Variant):
	pass

func bar():
	var x = []
	foo(x)

Which makes sense to me, because it's unsafe in the sense that the argument can be anything, but I think the documentation and error message might be made better as it's quite cryptic in its current form

What's the difference between a: Variant and a? I figured untyped args/variables were implicitly Variant-typed.

The difference is that the former is explicit, the type is the same but the hard typedness isn't

I don't think passing a variant to fn(a) is any less safe than passing a variant to fn(a: Variant), so I'd argue that if the latter is not a warning, the former should not be either.
However, if that's not possible, then a more clear error message would be an improvement.

It's still unsafe though as there's no information given, so it could actually want some other specific type, but with Variant you make a declaration that any Variant will be accepted and will work, that's the difference here
With no typing no statement is made, but with a static type the message you send is that the type should be accepted

At the moment we don't have a good way to distinguish between Variant and unknown types (hard/weak Variant), especially for target/source. Therefore, false warnings are possible. The DataType class needs some refactoring.

For comparison, I'd argue this logic is correct, and that explicit typing as Variant matters:
func foo(arg):
    var arr : Array = arg
    # Do something assuming arr is valid

Is "legal code", but
func foo(arg: Variant):
    var arr : Array = arg
    # Do something assuming arr is valid

Isn't, explicit typing makes a statement that the method will handle the specified type graciously
So the former is unsafe code, because you're not given any guarantees about the treatment of the argument

authors: AThousandShips dalexeev rcorre


text:
The value of INV_VIEW_MATRIX in double build version is different from usual

Tested versions
4.3.dev [71699e08c9df78b7203fa4ef9cede28e995d6ace]
System information
Windows10[22H2] - godot.windows.editor.dev.double.x86_64.exe - Vulkan(Forward+)
Issue description
The INV_VIEW_MATRIX value is different in double build version, it looks wrong.
double build: godot.windows.editor.dev.double.x86_64.exe
regular build: godot.windows.editor.dev.x86_64.exe
Use Nsight Graphics 2024.1.0, Get the render info, I see the INV_VIEW_MATRIX is different in double version.
the regular version:

the double version:

Steps to reproduce

use scons platform=windows dev_build=yes precision=double build a double version and scons platform=windows dev_build=yes build a regular version.
create a scene, place some mesh.
use this shader for screen quad mesh (postprocess):

shader_type spatial;
render_mode unshaded;

uniform sampler2D DepthTex : hint_depth_texture;

void vertex() {
	// Called for every vertex the material is visible on.
	POSITION = vec4(VERTEX.xy, 1.0, 1.0);
}

void fragment() {
	// Called for every pixel the material is visible on.
	float depth_ndc = texture(DepthTex, SCREEN_UV).x;
	vec3 ndc = vec3(SCREEN_UV * 2.0 - 1.0, depth_ndc);
	vec4 view = INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
	view.xyzw /= view.w;
	vec4 world = INV_VIEW_MATRIX * view;
	ALBEDO = world.xyz;
}

run scene with double version and regular version, the two render results are different:

the scene:

regular:

double:

Minimal reproduction project (MRP)
inv_view_test.zip

I guess it's because of the extra minus sign here, but after the modification, the editor window screen will be reversed.

Thank you for reporting, consolidating in:

https://github.com/godotengine/godot/issues/85711

See there for more details, if you think something was missed about this and it's not the same issue, please comment here and it can be reopened

@Khasehemwy Can you test https://github.com/godotengine/godot/pull/93108 and confirm it it fixes the problem you are seeing?

@Khasehemwy Can you test #93108 and confirm if it fixes the problem you are seeing?

Yes, it fixed. I also deleted the minus sign before, but did not modify the glsl code, it causes the editor  window to look flipped.

authors: AThousandShips Khasehemwy clayjohn