Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

cli: streamline autostart ux#2251

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
johnstcn merged 14 commits intomainfromcj/1647/autostart-set-unset
Jun 13, 2022
Merged

Conversation

johnstcn
Copy link
Member

@johnstcnjohnstcn commentedJun 10, 2022
edited
Loading

This PR makes the following changes:

  • autostart enable|disable =>autostart set|unset
  • autostart enable now accepts a more natual schedule format:<time> <days-of-week> <location>
  • autostart show now shows configured timezone
  • 🎉 automatic timezone detection across mac, windows, linux 🎉

Fixes#1647

@johnstcnjohnstcn requested a review froma teamJune 10, 2022 17:21
@johnstcnjohnstcn marked this pull request as ready for reviewJune 10, 2022 17:21
@johnstcnjohnstcn self-assigned thisJun 10, 2022
@johnstcnjohnstcn requested a review fromammarioJune 10, 2022 18:08
Comment on lines 24 to 54
funcTimezoneIANA() (*time.Location,error) {
iftzEnv,found:=os.LookupEnv("TZ");found {
iftzEnv=="" {
returntime.UTC,nil
}
loc,err:=time.LoadLocation(tzEnv)
iferr!=nil {
returnnil,xerrors.Errorf("load location from TZ env: %w",err)
}
returnloc,nil
}

lp,err:=filepath.EvalSymlinks(etcLocaltime)
iferr!=nil {
returnnil,xerrors.Errorf("read location of %s: %w",etcLocaltime,err)
}

// On Darwin, /var/db/timezone/zoneinfo is also a symlink
realZoneInfoPath,err:=filepath.EvalSymlinks(zoneInfoPath)
iferr!=nil {
returnnil,xerrors.Errorf("read location of %s: %w",zoneInfoPath,err)
}

stripped:=strings.Replace(lp,realZoneInfoPath,"",-1)
stripped=strings.TrimPrefix(stripped,string(filepath.Separator))
loc,err:=time.LoadLocation(stripped)
iferr!=nil {
returnnil,xerrors.Errorf("invalid location %q guessed from %s: %w",stripped,lp,err)
}
returnloc,nil
}
Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Review: at a glance, the Darwin and Linux versions of these functions seems identical. Be assured they are not.

Comment on lines 26 to 71
funcTimezoneIANA() (*time.Location,error) {
iftzEnv,found:=os.LookupEnv("TZ");found {
iftzEnv=="" {
returntime.UTC,nil
}
loc,err:=time.LoadLocation(tzEnv)
iferr!=nil {
returnnil,xerrors.Errorf("load location from TZ env: %w",err)
}
returnloc,nil
}

// https://superuser.com/a/1584968
cmd:=exec.Command("powershell.exe","-NoLogo","-NoProfile","-NonInteractive")
stdin,err:=cmd.StdinPipe()
iferr!=nil {
returnnil,xerrors.Errorf("run powershell: %w",err)
}

done:=make(chanstruct{})
gofunc() {
deferstdin.Close()
deferclose(done)
_,_=fmt.Fprintln(stdin,cmdTimezone)
}()

<-done

outBytes,err:=cmd.CombinedOutput()
iferr!=nil {
returnnil,xerrors.Errorf("execute powershell command %q: %w",cmdTimezone,err)
}

outLines:=strings.Split(string(outBytes),"\n")
iflen(outLines)<2 {
returnnil,xerrors.Errorf("unexpected output from powershell command %q: %q",cmdTimezone,outLines)
}
// What we want is the second line of output
locStr:=strings.TrimSpace(outLines[1])
loc,err:=time.LoadLocation(locStr)
iferr!=nil {
returnnil,xerrors.Errorf("invalid location %q from powershell: %w",locStr,err)
}

returnloc,nil
}
Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Review: just don't stare too closely at this

}

// Schedule represents a cron schedule.
// It's essentially a thin wrapper for robfig/cron/v3 that implements Stringer.
Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Review: This wrapper is no longer thin.

Comment on lines +143 to +161
func (sSchedule)DaysOfWeek()string {
dow:=strings.Fields(s.cronStr)[4]
ifdow=="*" {
return"daily"
}
for_,weekday:=range []time.Weekday{
time.Sunday,
time.Monday,
time.Tuesday,
time.Wednesday,
time.Thursday,
time.Friday,
time.Saturday,
} {
dow=strings.Replace(dow,fmt.Sprintf("%d",weekday),weekday.String()[:3],1)
}
returndow
}

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Review: For display purposes, this just replaces the day-of-week numbers with their abbreviated equivalents.

testCase:=testCase
//nolint:paralleltest // t.Setenv
t.Run(testCase.name,func(t*testing.T) {
t.Setenv("TZ",testCase.tzEnv)
Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Review: Doingsetenv here to validate that the timezone specified in the schedule is used

Comment on lines +80 to +84
{
name:"TimezoneProvidedInsteadOfLocation",
input: []string{"09:00AM","Sun-Sat","CST"},
expectedError:errUnsupportedTimezone.Error(),
},
Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@Emyrk this one just for you :-)

Emyrk reacted with heart emoji
Copy link
Member

@mafredrimafredri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

A few suggestions and questions, but in general looks good! 👍🏻

Default: * (every day)
* Location (optional) must be a valid location in the IANA timezone database.
If omitted, we will fall back to either the TZ environment variable or /etc/localtime.
You can check your corresponding location by visiting https://ipinfo.io - it shows in the demo widget on the right.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This help is ❤️.

johnstcn reacted with heart emoji
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yes, this is excellent.

_,_=fmt.Fprintf(cmd.OutOrStdout(),
"%s will automatically start at %s %s (%s)\n",
workspace.Name,
schedNext.In(sched.Location()).Format(time.Kitchen),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Do we always want to show am/pm here, even if 24h was used to define it? Or perhaps vary depending on defaults for the users system or selected location? Or perhaps we should have a user preference down the line?

johnstcn reacted with thumbs up emoji
Copy link
MemberAuthor

@johnstcnjohnstcnJun 13, 2022
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This sounds like an internationalization problem to me, which I'm going to place inside a tin can and kick down the road for later. 😅

But yes, yes we should.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I think preference is very location-dependent. It would be unfortunate to add more state for am/pm.


varerrInvalidScheduleFormat=xerrors.New("Schedule must be in the format Mon-Fri 09:00AM America/Chicago")
varerrInvalidTimeFormat=xerrors.New("Start time must be in the format hh:mm[am|pm] or HH:MM")
varerrUnsupportedTimezone=xerrors.New("The location you provided looks like a timezone. Check https://ipinfo.io for your location.")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Nit: Go Errors should be lower case.

But technically these are help/documentation, so I understand the use of proper sentence structure.

(This isnon-blocking as I think the right approach might require some more think-through, but writing down my thoughts.)

I have one suggestion, that could have some benefits down the line if we e.g. want to translate the CLI, etc:

funcFormatCliError(errerror)string {switcherr {caseerrInvalidScheduleFormat:return"Schedule ..."// ...}}

We could optionally have a separatetype cliError struct{} type which we print in this special way.

Or perhaps rather we could have:

typecliErrorstruct{errstringcode clierror.Code}funcnewCliError(code clierror.Code,estring)errorvarerrInvalidScheduleFormat=newCliError(clierror.InvalidSchedule,"invalid schedule format")

Where we could keep an enum of cli error messages in e.g. a separate package. Just ideas of the top of my head.

We could also do something simpler like uppercasing the first letter of the error when we print it. I think it'd be helpful if error messages looked consistent across the CLI.

johnstcn reacted with thumbs up emoji
Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

We have something very similar inside another codebase which shall not be named ;-)
But yes, this needs more noodling.

ifassert.NotEmpty(t,actualSchedule) {
assert.Equal(t,testCase.expectedSchedule,actualSchedule.String())
}
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

These are some beautiful tests! ❤️

johnstcn reacted with heart emoji
Default: * (every day)
* Location (optional) must be a valid location in the IANA timezone database.
If omitted, we will fall back to either the TZ environment variable or /etc/localtime.
You can check your corresponding location by visiting https://ipinfo.io - it shows in the demo widget on the right.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yes, this is excellent.

_,_=fmt.Fprintf(cmd.OutOrStdout(),
"%s will automatically start at %s %s (%s)\n",
workspace.Name,
schedNext.In(sched.Location()).Format(time.Kitchen),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I think preference is very location-dependent. It would be unfortunate to add more state for am/pm.

@johnstcnjohnstcnenabled auto-merge (squash)June 13, 2022 20:44
@johnstcnjohnstcndisabled auto-mergeJune 13, 2022 21:00
@johnstcnjohnstcn merged commit0a949aa intomainJun 13, 2022
@johnstcnjohnstcn deleted the cj/1647/autostart-set-unset branchJune 13, 2022 21:09
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@mafredrimafredrimafredri approved these changes

@ammarioammarioammario approved these changes

Assignees

@johnstcnjohnstcn

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Streamlinecoder autostart UX

3 participants

@johnstcn@mafredri@ammario

[8]ページ先頭

©2009-2025 Movatter.jp