Slide 1

Slide 1 text

$—$—$—$—$—$—$—$—$—$—$—$—$— $—$—$—$—$—$—$—$—$—$—$—$—$— Double- Shipping Software For Profit

Slide 2

Slide 2 text

@holman

Slide 3

Slide 3 text

github github github github github github

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

This talk

Slide 6

Slide 6 text

This talk Competitors

Slide 7

Slide 7 text

This talk Competitors Long-running Branches

Slide 8

Slide 8 text

This talk Competitors Long-running Branches Curious Motherfuckers

Slide 9

Slide 9 text

Why?

Slide 10

Slide 10 text

Users

Slide 11

Slide 11 text

$

Slide 12

Slide 12 text

Why not?

Slide 13

Slide 13 text

FIJRUBY OWN BRANCH INSTALLER SPECIAL FEATURES ONE DEVELOPER*

Slide 14

Slide 14 text

B-B-B-BUT OUR SECRETS! THEY’RE SO SECRET!

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

$ jrubyc secrets.rb

Slide 17

Slide 17 text

$ jrubyc secrets.rb #=> secrets.class

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

$ rbx compile secrets.rb

Slide 20

Slide 20 text

$ rbx compile secrets.rb #=> secrets.rbc

Slide 21

Slide 21 text

$ rbx compile secrets.rb #=> secrets.rbc $ rbx compile -h

Slide 22

Slide 22 text

$ rbx compile secrets.rb #=> secrets.rbc $ rbx compile -h #=> whoa.

Slide 23

Slide 23 text

MRI

Slide 24

Slide 24 text

HAX MRI

Slide 25

Slide 25 text

HAX MRI

Slide 26

Slide 26 text

Sales.

Slide 27

Slide 27 text

Support

Slide 28

Slide 28 text

More humans More time More money

Slide 29

Slide 29 text

Make them pay for it.

Slide 30

Slide 30 text

Differences suck

Slide 31

Slide 31 text

github.com GitHub FI fs1 fs2 fs3 fs4 ... local filesystem

Slide 32

Slide 32 text

class Repository < ActiveRecord::Base def file_server if Rails.fi? “localhost” else Smoke.find_fs(self) end end def refs tag_names + branches end def exists_on_disk? if Rails.fi? File.exist?(fs_path) else Smoke.exists_on_disk?(self) end end def route owner.route end def delete if Rails.fi? File.rm_rf(fs_path) else Smoke.delete end end def to_s “lol this is a repository / #{id}” end def online? return true if Rails.fi? CHIMNEY.storage_server_online?(route) end end

Slide 33

Slide 33 text

class Repository < ActiveRecord::Base def file_server if Rails.fi? “localhost” else Smoke.find_fs(self) end end def refs tag_names + branches end def exists_on_disk? if Rails.fi? File.exist?(fs_path) else Smoke.exists_on_disk?(self) end end def route owner.route end def delete if Rails.fi? File.rm_rf(fs_path) else Smoke.delete end end def to_s “lol this is a repository / #{id}” end def online? return true if Rails.fi? CHIMNEY.storage_server_online?(route) end end

Slide 34

Slide 34 text

class Repository < ActiveRecord::Base def file_server if Rails.fi? “localhost” else Smoke.find_fs(self) end end def refs tag_names + branches end def exists_on_disk? if Rails.fi? File.exist?(fs_path) else Smoke.exists_on_disk?(self) end end def route owner.route end def delete if Rails.fi? File.rm_rf(fs_path) else Smoke.delete end end def to_s “lol this is a repository / #{id}” end def online? return true if Rails.fi? CHIMNEY.storage_server_online?(route) end end if Rails.fi? File.exist?(path) else Smoke.exist?(path) end

Slide 35

Slide 35 text

module Smoke def exists? # handle logic for # both FI and .com end end

Slide 36

Slide 36 text

if Rails.fi? File.exist?(path) else Smoke.exist?(path) end

Slide 37

Slide 37 text

Smoke.exist?(path)

Slide 38

Slide 38 text

Get high.

Slide 39

Slide 39 text

Strategy Pattern

Slide 40

Slide 40 text

GitHub::RepoCreator handles repository creation

Slide 41

Slide 41 text

module GitHub RepoCreator = if Rails.fi? Fi::RepoCreator else Web::RepoCreator end end

Slide 42

Slide 42 text

module GitHub module Web class RepoCreator # implementation, lol end end end

Slide 43

Slide 43 text

module GitHub module Fi class RepoCreator < GitHub::Web::RepoCreator # implementation, lol end end end

Slide 44

Slide 44 text

module GitHub module Fi class RepoCreator < GitHub::Web::RepoCreator def setup_smoke # no-op end end end end

Slide 45

Slide 45 text

Provide a standardized API between products.

Slide 46

Slide 46 text

creator = GitHub::RepoCreator.new creator.setup

Slide 47

Slide 47 text

Feature flipping makes things less frightening.

Slide 48

Slide 48 text

if current_user.beta? beta_hotness end

Slide 49

Slide 49 text

if GitHub::Beta.enabled?(:svn) subversion_hotness end

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

Mistakes

Slide 54

Slide 54 text

Mistakes branches

Slide 55

Slide 55 text

Mistakes branches documentation

Slide 56

Slide 56 text

Mistakes branches documentation versioning

Slide 57

Slide 57 text

Zach Holman, @holman http://zachholman.com/talks