Giter VIP home page Giter VIP logo

Comments (16)

mike-burns avatar mike-burns commented on August 15, 2024

I can see why this would be useful. If you can figure out how to make this change, I'd love a pull request---at least to see what API you're imagining.

One idea that keeps coming up is to have a configuration record with username, password, and endpoint URL, which can be created using def.

from github.

iand675 avatar iand675 commented on August 15, 2024

If you aren't set on keeping everything in the IO monad, then you could hoist everything into a Github monad, which would just be along the lines of

data GithubConfig = GithubConfig { auth :: Maybe BasicAuth, endpoint :: String }
newtype Github a = Github { fromGithub :: ReaderT GithubConfig IO a } deriving (Functor, Monad, MonadIO)

githubGet :: [String] -> Github (Either Error b)
githubGet paths = do
  authInfo <- fmap auth ask
  url <- buildUrl paths
  liftIO $ githubAPI (BS.pack "GET")
                            url
                            auth
                            (Nothing :: Maybe value)

buildUrl :: [String] -> Github String
buildUrl paths = fmap endpoint ask >>= \endpoint -> return (endpoint ++ intercalate "/" paths)

That would also make things like coalescing issuesForRepo and issuesForRepo' together trivial since the auth bits are handled by githubGet instead of in every method that might need them:

issuesForRepo = githubGetWithQueryString' ["repos", user, repoName, "issues"]
   ...

I'll be happy to make a pull request if you need, but this is what I had in mind, generally speaking, so if you had any objections to it, it would be nice to know before I go off and convert everything to use the Github monad.

from github.

mike-burns avatar mike-burns commented on August 15, 2024

Cool idea (though I believe you are not the first to suggest it to me!).

Does this affect existing programs? It's OK if it does, but mostly curious. Does this spread liftIO all over people's code? To get more concrete, what would samples/Repos/ListTags.hs look like under the Github monad?

from github.

iand675 avatar iand675 commented on August 15, 2024

It will require code changes to existing programs. Whether it spreads liftIO all over people's code really depends on how they want to structure their programs. Here's how you could write that sample code without having to use any liftIOs:

module ListTags where

import qualified Github.Repos as Github
import Data.List

-- Maybe String parameter denotes custom endpoint (or not)
-- Github.run :: Maybe BasicAuth -> Maybe String -> Github a -> IO a

main = do
  result <- Github.run Nothing Nothing $ do
    possibleTags <- Github.tagsFor "thoughtbot" "paperclip"
    return $ case possibleTags of
      (Left error) -> "Error: " ++ show error
      (Right tags) -> intercalate "\n" $ map Github.tagName tags
  putStrLn result

from github.

sol avatar sol commented on August 15, 2024

@iand675 I think if you abstract over a type class, then you can make both IO and Github an instance of that type class. Something like:

class MonadGithub m where
  getAuth :: m (Maybe BasicAutho)
  getEndpoint :: m String
  doHttps :: Method -> Url -> Body -> m Response

instance MonadGithub IO where
  getAuth = return Nothing
  getEndpoint = "https://api.github.com/"
  doHttps = ...

instance MonadGithub Github where
  getAuth = ..
  getEndpoint = ..
  doHttps m u b = liftIO (doHttps m u b)

API functions would then alway have a GithubMonad constraint, e.g.:

userRepo :: MonadGithub m => String -> String -> m Repo

Non of the code is tested, so it may contain errors. But I hope this illustrates the idea.

from github.

sol avatar sol commented on August 15, 2024

Would probably also work to remove getAuth from the type class, and then give API functions that require authentication some type that expresses this.

from github.

iand675 avatar iand675 commented on August 15, 2024

That's also an option. I spent about an hour to see if I could unify getAuth using type families or type synonym instances, but to no avail. If you go the MonadGithub class route, I don't see any way to keep getAuth as a member of the type class. Not that there's necessarily anything wrong with that, and you could potentially just export slightly different versions from different modules that wrap the auth bits if you want the Github monad to handle all the auth for you.

from github.

sol avatar sol commented on August 15, 2024

@iand675 I'm not sure if I understand what you mean. What exactly is the issue with getAuth?

My thought was that you may give actions that require auth a type Github a instead of MonadGithub m => m a, so that it is clear that those functions can not possibly work in IO. The run function for Github could then always require auth (not really sure if that is desirable).

Anyway, just ideas, not sure how it works out. Or if there are better alternatives. But I certainly like the prospect of being able to run API functions that do not require authentication in IO.

from github.

iand675 avatar iand675 commented on August 15, 2024

Ah, I see what you're saying. I was trying to figure out if there would be an easy way to make (BasicAuth -> IO a) an instance of MonadGithub so that getAuth could be used in the IO monad if you explicitly supplied it with auth information, but it didn't work.

I really like the way you've suggested doing it though.

from github.

mike-burns avatar mike-burns commented on August 15, 2024

Cool, yeah! I think @sol has mentioned this idea to me before, and it's time we actually do it.

So the user-visible change is that, if you want to do auth or change the endpoint, you need to be inside the Github monad, otherwise you can stay in IO and nothing changes?

I would take that pull request.

from github.

iand675 avatar iand675 commented on August 15, 2024

Excellent, I'll see about getting that done in the next few days.

On Wednesday, June 27, 2012 at 12:12 PM, Mike Burns wrote:

Cool, yeah! I think @sol has mentioned this idea to me before, and it's time we actually do it.

So the user-visible change is that, if you want to do auth or change the endpoint, you need to be inside the Github monad, otherwise you can stay in IO and nothing changes?

I would take that pull request.


Reply to this email directly or view it on GitHub:
https://github.com/mike-burns/github/issues/25#issuecomment-6612708

from github.

goblin avatar goblin commented on August 15, 2024

Any luck with this feature? I too would like to be able to log in to github in order to back up private repos (with github-backup)

from github.

DeTeam avatar DeTeam commented on August 15, 2024

Here's the fork https://github.com/iand675/github
Idea with env around those API function looks nice!
Mb we should implement all those things mentioned in #2 ?

from github.

mxswd avatar mxswd commented on August 15, 2024

We should do this for 1.0. A breaking change.

from github.

jwiegley avatar jwiegley commented on August 15, 2024

Some some support for this was just merged in, can someone check if it addresses this ticket?

from github.

phadej avatar phadej commented on August 15, 2024

It should work with http://hackage.haskell.org/package/github-0.14.0/candidate (and 0.13.2 already IIRC)

from github.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.